From 7dc9e50cbda04cbbe95f343a26d602b9080dc95d Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 11 Mar 2010 02:29:26 +0000 Subject: [PATCH] ENHANCEMENT Updated jquery.ondemand.js to sapphire trunk version, to ensure compatibility with jQuery 1.4.2 git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/2.4@100852 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/core/jquery.ondemand.js | 315 ++++++++++++----------------- 1 file changed, 126 insertions(+), 189 deletions(-) diff --git a/javascript/core/jquery.ondemand.js b/javascript/core/jquery.ondemand.js index d1316ed88..0110e2f69 100644 --- a/javascript/core/jquery.ondemand.js +++ b/javascript/core/jquery.ondemand.js @@ -1,233 +1,170 @@ /** * On-demand JavaScript handler - * Based on http://plugins.jquery.com/files/issues/jquery.ondemand.js_.txt and modified to integrate with Sapphire + * Based on http://plugins.jquery.com/files/issues/jquery.ondemand.js_.txt + * and heavily modified to integrate with SilverStripe and prototype.js. + * Adds capabilities for custom X-Include-CSS and X-Include-JS HTTP headers + * to request loading of externals alongside an ajax response. + * + * IMPORTANT: This plugin monkeypatches the jQuery.ajax() method. */ (function($){ - function isExternalScript(url){ - re = new RegExp('(http|https)://'); - return re.test(url); - }; - $.extend({ - requireConfig : { - routeJs : '', // empty default paths give more flexibility and user has - routeCss : '' // choice of using this config or full path in scriptUrl argument - }, // previously were useless for users which don't use '_js/' and '_css/' folders. (by PGA) - - queue : [], - pending : null, - loaded_list : null, // loaded files list - to protect against loading existed file again (by PGA) - + // loaded files list - to protect against loading existed file again (by PGA) + _ondemand_loaded_list : null, // Added by SRM: Initialise the loaded_list with the scripts included on first load initialiseItemLoadedList : function() { - if(this.loaded_list == null) { - $this = this; - $this.loaded_list = {}; - $('script').each(function() { - if($(this).attr('src')) $this.loaded_list[ $(this).attr('src') ] = 1; - }); - $('link[@rel="stylesheet"]').each(function() { - if($(this).attr('href')) $this.loaded_list[ $(this).attr('href') ] = 1; - }); - } - }, - - /** - * Returns true if the given CSS or JS script has already been loaded - */ - isItemLoaded : function(scriptUrl) { - this.initialiseItemLoadedList(); - return this.loaded_list[scriptUrl] != undefined; - }, - - requireJs : function(scriptUrl, callback, opts, obj, scope) - { - - if(opts != undefined || opts == null){ - $.extend($.requireConfig, opts); - } - - var _request = { - url : scriptUrl, - callback : callback, - opts : opts, - obj : obj, - scope : scope - } - - if(this.pending) - { - this.queue.push(_request); - return; - } - - this.pending = _request; - - this.initialiseItemLoadedList(); - - if (this.loaded_list[this.pending.url] != undefined) { // if required file exists (by PGA) - this.requestComplete(); // => request complete - return; - } - - var _this = this; - var _url = (isExternalScript(scriptUrl)) ? scriptUrl : $.requireConfig.routeJs + scriptUrl; - var _head = document.getElementsByTagName('head')[0]; - var _scriptTag = document.createElement('script'); - - // Firefox, Opera - $(_scriptTag).bind('load', function(){ - _this.requestComplete(); + if(this.loaded_list == null) { + $this = this; + $this.loaded_list = {}; + $('script').each(function() { + if($(this).attr('src')) $this.loaded_list[ $(this).attr('src') ] = 1; }); - - // IE - _scriptTag.onreadystatechange = function(){ - if(this.readyState === 'loaded' || this.readyState === 'complete'){ - _this.requestComplete(); - } - } - - _scriptTag.type = "text/javascript"; - _scriptTag.src = _url; - - _head.appendChild(_scriptTag); + $('link[rel="stylesheet"]').each(function() { + if($(this).attr('href')) $this.loaded_list[ $(this).attr('href') ] = 1; + }); + } }, - - requestComplete : function() - { - - if(this.pending.callback){ - if(this.pending.obj){ - if(this.pending.scope){ - this.pending.callback.call(this.pending.obj); - } else { - this.pending.callback.call(window, this.pending.obj); - } - } else { - this.pending.callback.call(); - } - } - - this.loaded_list[this.pending.url] = 1; // adding loaded file to loaded list (by PGA) - this.pending = null; - - if(this.queue.length > 0) - { - var request = this.queue.shift(); - this.requireJs(request.url, request.callback, request.opts, request.obj, request.scope); + + /** + * Returns true if the given CSS or JS script has already been loaded + */ + isItemLoaded : function(scriptUrl) { + var self = this; + + if(this._ondemand_loaded_list == null) { + this._ondemand_loaded_list = {}; + $('script').each(function() { + if($(this).attr('src')) self._ondemand_loaded_list[ $(this).attr('src') ] = 1; + }); + $('link[rel="stylesheet"]').each(function() { + if($(this).attr('href')) self._ondemand_loaded_list[ $(this).attr('href') ] = 1; + }); } + + return (this._ondemand_loaded_list[scriptUrl] != undefined); }, requireCss : function(styleUrl, media){ - if(media == null) media = 'all'; + if(media == null) media = 'all'; - // Don't double up on loading scripts - if(this.isItemLoaded(styleUrl)) return; + // Don't double up on loading scripts + if($.isItemLoaded(styleUrl)) return; if(document.createStyleSheet){ - var ss = document.createStyleSheet($.requireConfig.routeCss + styleUrl); + var ss = document.createStyleSheet(styleUrl); ss.media = media; } else { var styleTag = document.createElement('link'); $(styleTag).attr({ - href : $.requireConfig.routeCss + styleUrl, + href : styleUrl, type : 'text/css', media : media, rel : 'stylesheet' }).appendTo($('head').get(0)); } - this.loaded_list[styleUrl] = 1; + this._ondemand_loaded_list[styleUrl] = 1; + }, + + /** + * Process the X-Include-CSS and X-Include-JS headers provided by the Requirements class + */ + processOnDemandHeaders: function(xml, status, _ondemandComplete) { + var self = this; + + // CSS + if(xml.getResponseHeader('X-Include-CSS')) { + var cssIncludes = xml.getResponseHeader('X-Include-CSS').split(','); + for(var i=0;i 0) { - for(i=0;i