If you're looking to simply observe and intercept, the process can be a bit tricky. However, the code required is relatively straightforward. One option for making changes to a single Request prototype would be to use Class.refactor
from mootools-more, if it's accessible:
// enable log func...
Class.refactor(Request, {
success: function(text, xml){
this.previous(text, xml);
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
},
failure: function(){
this.previous();
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
}
});
The following section of code remains consistent regardless of your approach.
// assign a logger function
Request.monitor = function() {
console.log("onComplete", this.response.text);
};
// call a simple request object.
new Request({
url: "/echo/html/",
method: "post",
data: {
html: "hello"
}
}).send();
The advantage here is that it will remain functional even if there are tweaks to mootools-core. It doesn't rely on the specifics of the core functionality, ensuring it continues running smoothly unless there's a major API alteration down the line.
You could also opt to modify classes using implement
instead, but this approach may not accommodate mootools-core modifications. Essentially, this entails duplicating the current function within the methods and then appending any desired changes - particularly useful for shorter functions we intend to modify:
Request.implement({
success: function(text, xml){
this.onSuccess(this.processScripts(text), xml);
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
},
failure: function(){
this.onFailure();
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
}
});
Finally, you have the option to preserve the original low-level functionality with
var oldsuccess = Request.prototype.success
, make your adjustments, and execute
oldsuccess.apply(this, arguments)
.
The challenge arises when dealing with subclasses like HTML and JSON which might have already mirrored the old prototype, rendering your logger ineffective. A potential solution involves implementing a small object across all Request classes to address this issue.
An elegant method that could work involves combining elements of the last method with the original prototype, especially since the success functions vary among all three:
(function() {
var changes = {
success: function(text, xml){
this.onSuccess(this.processScripts(text), xml);
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
},
failure: function(){
this.onFailure();
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
}
};
[Request, Request.HTML, Request.JSON].invoke('implement', changes);
})();
In terms of practical implementation, consider the final version or refactor tailored for production, tested and operational across all three classes. Be mindful that these alterations occur before additional processing for JSON or HTML takes place, positioning it as a low-level logging system. Alternatively, adjust the structure to post-process after onSuccess and onFailure instead.
(function() {
// Define extensions
var classes = [Request, Request.HTML, Request.JSON],
mapper = ["Request", "Request.HTML", "Request.JSON"],
orig = {
onSuccess: Request.prototype.onSuccess,
onFailure: Request.prototype.onFailure
},
changes = {
onSuccess: function(){
Request.Spy && typeof Request.Spy == "function" && Request.Spy.apply(this, arguments);
orig.onSuccess.apply(this, arguments);
},
onFailure: function(){
Request.Spy && typeof Request.Spy == "function" && Request.Spy.apply(this, arguments);
orig.onFailure.apply(this, arguments);
}
};
classes.invoke('implement', changes);
// Determine which Class prototype triggered the AJAX call
Request.implement({
getClass: function() {
var ret;
Array.each(classes, function(klass, index) {
if (instanceOf(this, klass)) {
ret = mapper[index];
}
}, this);
return ret;
}
});
})();
// Enable spying by defining Request.Spy as a function:
Request.Spy = function() {
console.log(this.getClass(), arguments);
};
// Test through a standard Request
new Request({
url: "/echo/html/",
data: {
html: "normal data"
}
}).send();
// Test via HTML
new Request.HTML({
url: "/echo/html/",
data: {
html: "<p>normal data</p>"
}
}).send();
// Test via JSON
new Request.JSON({
url: "/echo/json/",
data: {
json: JSON.encode({'normal':'data'})
}
}).send();
JsFiddle link: http://jsfiddle.net/dimitar/3rnKe/