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