diff -r 058bb3dc685f -r 0b59724cb3f2 cubicweb/web/data/cubicweb.ajax.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cubicweb/web/data/cubicweb.ajax.js Sat Jan 16 13:48:51 2016 +0100 @@ -0,0 +1,743 @@ +/* copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. + * contact http://www.logilab.fr/ -- mailto:contact@logilab.fr + * + * This file is part of CubicWeb. + * + * CubicWeb is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 2.1 of the License, or (at your option) + * any later version. + * + * CubicWeb is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with CubicWeb. If not, see . + */ + +/** + * .. function:: Deferred + * + * dummy ultra minimalist implementation of deferred for jQuery + */ + +cw.ajax = new Namespace('cw.ajax'); + +function Deferred() { + this.__init__(this); +} + +jQuery.extend(Deferred.prototype, { + __init__: function() { + this._onSuccess = []; + this._onFailure = []; + this._req = null; + this._result = null; + this._error = null; + }, + + addCallback: function(callback) { + if (this._req && (this._req.readyState == 4) && this._result) { + var args = [this._result, this._req]; + jQuery.merge(args, cw.utils.sliceList(arguments, 1)); + callback.apply(null, args); + } + else { + this._onSuccess.push([callback, cw.utils.sliceList(arguments, 1)]); + } + return this; + }, + + addErrback: function(callback) { + if (this._req && this._req.readyState == 4 && this._error) { + callback.apply(null, [this._error, this._req]); + } + else { + this._onFailure.push([callback, cw.utils.sliceList(arguments, 1)]); + } + return this; + }, + + success: function(result) { + this._result = result; + for (var i = 0; i < this._onSuccess.length; i++) { + var callback = this._onSuccess[i][0]; + var args = [result, this._req]; + jQuery.merge(args, this._onSuccess[i][1]); + callback.apply(null, args); + } + }, + + error: function(xhr, status, error) { + this._error = error; + for (var i = 0; i < this._onFailure.length; i++) { + var callback = this._onFailure[i][0]; + var args = [error, this._req]; + jQuery.merge(args, this._onFailure[i][1]); + if (callback !== undefined) + callback.apply(null, args); + } + } + +}); + +var AJAX_PREFIX_URL = 'ajax'; +var JSON_BASE_URL = BASE_URL + 'json?'; +var AJAX_BASE_URL = BASE_URL + AJAX_PREFIX_URL + '?'; + + +jQuery.extend(cw.ajax, { + /* variant of jquery evalScript with cache: true in ajax call */ + _evalscript: function ( i, elem ) { + var src = elem.getAttribute('src'); + if (src) { + jQuery.ajax({ + url: src, + async: false, + cache: true, + dataType: "script" + }); + } else { + jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); + } + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }, + + evalscripts: function ( scripts ) { + if ( scripts.length ) { + jQuery.each(scripts, cw.ajax._evalscript); + } + }, + + /** + * returns true if `url` is a mod_concat-like url + * (e.g. http://..../data??resource1.js,resource2.js) + */ + _modconcatLikeUrl: function(url) { + var modconcat_rgx = new RegExp('(' + BASE_URL + 'data/([a-z0-9]+/)?)\\?\\?(.+)'); + return modconcat_rgx.exec(url); + }, + + /** + * decomposes a mod_concat-like url into its corresponding list of + * resources' urls + * >>> _listResources('http://foo.com/data/??a.js,b.js,c.js') + * ['http://foo.com/data/a.js', 'http://foo.com/data/b.js', 'http://foo.com/data/c.js'] + */ + _listResources: function(src) { + var resources = []; + var groups = cw.ajax._modconcatLikeUrl(src); + if (groups == null) { + resources.push(src); + } else { + var dataurl = groups[1]; + $.each(cw.utils.lastOf(groups).split(','), + function() { + resources.push(dataurl + this); + } + ); + } + return resources; + }, + + _buildMissingResourcesUrl: function(url, loadedResources) { + var resources = cw.ajax._listResources(url); + var missingResources = $.grep(resources, function(resource) { + return $.inArray(resource, loadedResources) == -1; + }); + cw.utils.extend(loadedResources, missingResources); + var missingResourceUrl = null; + if (missingResources.length == 1) { + // only one resource missing: build a node with a single resource url + // (maybe the browser has it in cache already) + missingResourceUrl = missingResources[0]; + } else if (missingResources.length > 1) { + // several resources missing: build a node with a concatenated + // resources url + var dataurl = cw.ajax._modconcatLikeUrl(url)[1]; + var missing_path = $.map(missingResources, function(resource) { + return resource.substring(dataurl.length); + }); + missingResourceUrl = dataurl + '??' + missing_path.join(','); + } + return missingResourceUrl; + }, + + _loadAjaxStylesheets: function($responseHead, $head) { + $responseHead.find('link[href]').each(function(i) { + var $srcnode = $(this); + var url = $srcnode.attr('href'); + if (url) { + var missingStylesheetsUrl = cw.ajax._buildMissingResourcesUrl(url, cw.loaded_links); + // compute concat-like url for missing resources and append + // element to $head + if (missingStylesheetsUrl) { + // IE has problems with dynamic CSS insertions. One symptom (among others) + // is a "1 item remaining" message in the status bar. (cf. #2356261) + // document.createStyleSheet needs to be used for this, although it seems + // that IE can't create more than 31 additional stylesheets with + // document.createStyleSheet. + if ($.browser.msie) { + document.createStyleSheet(missingStylesheetsUrl); + } else { + $srcnode.attr('href', missingStylesheetsUrl); + $srcnode.appendTo($head); + } + } + } + }); + $responseHead.find('link[href]').remove(); + }, + + _loadAjaxScripts: function($responseHead, $head) { + $responseHead.find('cubicweb\\:script').each(function(i) { + var $srcnode = $(this); + var url = $srcnode.attr('src'); + if (url) { + var missingScriptsUrl = cw.ajax._buildMissingResourcesUrl(url, cw.loaded_scripts); + if (missingScriptsUrl) { + $srcnode.attr('src', missingScriptsUrl); + /* special handling of