mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
BUGFIX jQuery 1.5 compatibility for jQuery.ondemand, by using jQuery.Deferred and the 'beforeSend' callback instead of monkeypatching jQuery.ajax
This commit is contained in:
parent
31d7a00eb7
commit
c6af46f066
@ -1,11 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
* On-demand JavaScript handler
|
* On-demand JavaScript handler
|
||||||
|
*
|
||||||
* Based on http://plugins.jquery.com/files/issues/jquery.ondemand.js_.txt
|
* Based on http://plugins.jquery.com/files/issues/jquery.ondemand.js_.txt
|
||||||
* and heavily modified to integrate with SilverStripe and prototype.js.
|
* and heavily modified to integrate with SilverStripe and prototype.js.
|
||||||
* Adds capabilities for custom X-Include-CSS and X-Include-JS HTTP headers
|
* Adds capabilities for custom X-Include-CSS and X-Include-JS HTTP headers
|
||||||
* to request loading of externals alongside an ajax response.
|
* to request loading of externals alongside an ajax response.
|
||||||
*
|
*
|
||||||
* IMPORTANT: This plugin monkeypatches the jQuery.ajax() method.
|
* Requires jQuery 1.5 ($.Deferred support)
|
||||||
|
*
|
||||||
|
* CAUTION: Relies on customization of the 'beforeSend' callback in jQuery.ajaxSetup()
|
||||||
|
*
|
||||||
|
* @author Ingo Schommer (ingo at silverstripe dot com)
|
||||||
|
* @author Sam Minnee (sam at silverstripe dot com)
|
||||||
*/
|
*/
|
||||||
(function($){
|
(function($){
|
||||||
|
|
||||||
@ -74,12 +80,12 @@
|
|||||||
/**
|
/**
|
||||||
* Process the X-Include-CSS and X-Include-JS headers provided by the Requirements class
|
* Process the X-Include-CSS and X-Include-JS headers provided by the Requirements class
|
||||||
*/
|
*/
|
||||||
processOnDemandHeaders: function(xml, status, _ondemandComplete) {
|
processOnDemandHeaders: function(xml, status, xhr) {
|
||||||
var self = this;
|
var self = this, processDfd = new $.Deferred();
|
||||||
|
|
||||||
// CSS
|
// CSS
|
||||||
if(xml.getResponseHeader('X-Include-CSS')) {
|
if(xhr.getResponseHeader('X-Include-CSS')) {
|
||||||
var cssIncludes = xml.getResponseHeader('X-Include-CSS').split(',');
|
var cssIncludes = xhr.getResponseHeader('X-Include-CSS').split(',');
|
||||||
for(var i=0;i<cssIncludes.length;i++) {
|
for(var i=0;i<cssIncludes.length;i++) {
|
||||||
// Syntax: "URL:##:media"
|
// Syntax: "URL:##:media"
|
||||||
if(cssIncludes[i].match(/^(.*):##:(.*)$/)) {
|
if(cssIncludes[i].match(/^(.*):##:(.*)$/)) {
|
||||||
@ -93,8 +99,8 @@
|
|||||||
|
|
||||||
// JavaScript
|
// JavaScript
|
||||||
var newJsIncludes = [];
|
var newJsIncludes = [];
|
||||||
if(xml.getResponseHeader('X-Include-JS')) {
|
if(xhr.getResponseHeader('X-Include-JS')) {
|
||||||
var jsIncludes = xml.getResponseHeader('X-Include-JS').split(',');
|
var jsIncludes = xhr.getResponseHeader('X-Include-JS').split(',');
|
||||||
for(var i=0;i<jsIncludes.length;i++) {
|
for(var i=0;i<jsIncludes.length;i++) {
|
||||||
if(!$.isItemLoaded(jsIncludes[i])) {
|
if(!$.isItemLoaded(jsIncludes[i])) {
|
||||||
newJsIncludes.push(jsIncludes[i]);
|
newJsIncludes.push(jsIncludes[i]);
|
||||||
@ -121,7 +127,7 @@
|
|||||||
async: false
|
async: false
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
_ondemandComplete(xml, status);
|
processDfd.resolve(xml, status, xhr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,44 +135,38 @@
|
|||||||
getScriptQueue();
|
getScriptQueue();
|
||||||
} else {
|
} else {
|
||||||
// If there aren't any new includes, then we can just call the callbacks ourselves
|
// If there aren't any new includes, then we can just call the callbacks ourselves
|
||||||
_ondemandComplete(xml, status);
|
processDfd.resolve(xml, status, xhr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return processDfd.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
$.ajaxSetup({
|
||||||
* Ajax requests are amended to look for X-Include-JS and X-Include-CSS headers
|
// beforeSend is the only place to access the XHR object before success handlers are added
|
||||||
*/
|
beforeSend: function(jqXHR, s) {
|
||||||
_originalAjax = $.ajax;
|
|
||||||
$.ajax = function(s) {
|
|
||||||
// Avoid recursion in ajax callbacks caused by getScript(), by not parsing
|
// Avoid recursion in ajax callbacks caused by getScript(), by not parsing
|
||||||
// ondemand headers for 'script' datatypes
|
// ondemand headers for 'script' datatypes
|
||||||
if(s.dataType == 'script') return _originalAjax(s);
|
if(s.dataType == 'script') return;
|
||||||
|
|
||||||
var _complete = s.complete;
|
var dfd = new $.Deferred();
|
||||||
var _success = s.success;
|
|
||||||
var _dataType = s.dataType;
|
|
||||||
|
|
||||||
// This replaces the usual ajax success & complete handlers. They are called after any on demand JS is loaded.
|
// Register our own success handler (assumes no handlers are already registered)
|
||||||
var _ondemandComplete = function(data, status) {
|
// 'success' is an alias for 'done', which is executed by the built-in deferred instance in $.ajax()
|
||||||
//var status = $.httpSuccess(xml) ? 'success' : 'error'; //rewrote success function as httpSuccess doesn't exist anymore in jQuery 1.5
|
jqXHR.success(function(success, statusText, jXHR) {
|
||||||
if (typeof status == 'undefined' || status != 'success') status = 'error';
|
$.processOnDemandHeaders(success, statusText, jXHR).done(function() {
|
||||||
|
dfd.resolveWith(s.context || this, [success, statusText, jXHR]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if(status == 'success') {
|
// Reroute all external success hanlders through our own deferred.
|
||||||
//var data = jQuery.httpData(xml, _dataType); //unnecessary as data type conversion is automatically done in jQuery 1.5 using the ajaxConvert method
|
// Not overloading fail() as no event can cause the original request to fail.
|
||||||
if(_success) _success(data, status);
|
jqXHR.success = function(callback) {
|
||||||
|
dfd.done(callback);
|
||||||
}
|
}
|
||||||
if(_complete) _complete(data, status);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// We remove the success handler and take care of calling it outselves within _ondemandComplete
|
|
||||||
s.success = null;
|
|
||||||
s.complete = function(xml, status) {
|
|
||||||
$.processOnDemandHeaders(xml, status, _ondemandComplete);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _originalAjax(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
Loading…
Reference in New Issue
Block a user