--- a/web/data/cubicweb.ajax.js Thu Jul 15 12:03:13 2010 +0200
+++ b/web/data/cubicweb.ajax.js Mon Jul 19 15:37:02 2010 +0200
@@ -1,33 +1,132 @@
-/*
- * :organization: Logilab
- * :copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
- * :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
+/* copyright 2003-2010 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 <http://www.gnu.org/licenses/>.
*/
-CubicWeb.require('python.js');
-CubicWeb.require('htmlhelpers.js');
+/**
+ * .. function:: Deferred
+ *
+ * dummy ultra minimalist implementation of deferred for jQuery
+ */
+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.readyState == 4) {
+ if (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.readyState == 4) {
+ if (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;
+ try {
+ 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);
+ }
+ } catch(error) {
+ this.error(this.xhr, null, error);
+ }
+ },
+
+ 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]);
+ callback.apply(null, args);
+ }
+ }
+
+});
+
var JSON_BASE_URL = baseuri() + 'json?';
-function _loadAjaxHtmlHead(node, head, tag, srcattr) {
- var loaded = [];
+//============= utility function handling remote calls responses. ==============//
+function _loadAjaxHtmlHead($node, $head, tag, srcattr) {
var jqtagfilter = tag + '[' + srcattr + ']';
- jQuery('head ' + jqtagfilter).each(function(i) {
- loaded.push(this.getAttribute(srcattr));
- });
- node.find(tag).each(function(i) {
- if (this.getAttribute(srcattr)) {
- if (!loaded.contains(this.getAttribute(srcattr))) {
- jQuery(this).appendTo(head);
+ if (cw['loaded_'+srcattr] === undefined) {
+ cw['loaded_'+srcattr] = [];
+ var loaded = cw['loaded_'+srcattr];
+ jQuery('head ' + jqtagfilter).each(function(i) {
+ loaded.push(this.getAttribute(srcattr));
+ });
+ } else {
+ var loaded = cw['loaded_'+srcattr];
+ }
+ $node.find(tag).each(function(i) {
+ var url = this.getAttribute(srcattr);
+ if (url) {
+ if (jQuery.inArray(url, loaded) == -1) {
+ // take care to <script> tags: jQuery append method script nodes
+ // don't appears in the DOM (See comments on
+ // http://api.jquery.com/append/), which cause undesired
+ // duplicated load in our case. After trying to use bare DOM api
+ // to avoid this, we switched to handle a list of already loaded
+ // stuff ourselves, since bare DOM api gives bug with the
+ // server-response event, since we loose control on when the
+ // script is loaded (jQuery load it immediatly).
+ loaded.push(url);
+ jQuery(this).appendTo($head);
}
} else {
- jQuery(this).appendTo(head);
+ jQuery(this).appendTo($head);
}
});
- node.find(jqtagfilter).remove();
+ $node.find(jqtagfilter).remove();
}
-/*
+/**
+ * .. function:: function loadAjaxHtmlHead(response)
+ *
* inspect dom response (as returned by getDomFromResponse), search for
* a <div class="ajaxHtmlHead"> node and put its content into the real
* document's head.
@@ -59,18 +158,13 @@
// we can safely return this node. Otherwise, the view itself
// returned several 'root' nodes and we need to keep the wrapper
// created by getDomFromResponse()
- if (response.childNodes.length == 1 &&
- response.getAttribute('cubicweb:type') == 'cwResponseWrapper') {
+ if (response.childNodes.length == 1 && response.getAttribute('cubicweb:type') == 'cwResponseWrapper') {
return response.firstChild;
}
return response;
}
-function preprocessAjaxLoad(node, newdomnode) {
- return loadAjaxHtmlHead(newdomnode);
-}
-
-function postAjaxLoad(node) {
+function _postAjaxLoad(node) {
// find sortable tables if there are some
if (typeof(Sortable) != 'undefined') {
Sortable.sortTables(node);
@@ -89,47 +183,80 @@
roundedCorners(node);
}
if (typeof setFormsTarget != 'undefined') {
- setFormsTarget(node);
+ setFormsTarget(node);
}
- loadDynamicFragments(node);
+ _loadDynamicFragments(node);
// XXX [3.7] jQuery.one is now used instead jQuery.bind,
// jquery.treeview.js can be unpatched accordingly.
jQuery(CubicWeb).trigger('server-response', [true, node]);
+ jQuery(node).trigger('server-response', [true, node]);
+}
+
+function remoteCallFailed(err, req) {
+ cw.log(err);
+ if (req.status == 500) {
+ updateMessage(err);
+ } else {
+ updateMessage(_("an error occured while processing your request"));
+ }
}
-/* cubicweb loadxhtml plugin to make jquery handle xhtml response
+//============= base AJAX functions to make remote calls =====================//
+/**
+ * .. function:: ajaxFuncArgs(fname, form, *args)
*
- * fetches `url` and replaces this's content with the result
+ * extend `form` parameters to call the js_`fname` function of the json
+ * controller with `args` arguments.
+ */
+function ajaxFuncArgs(fname, form /* ... */) {
+ form = form || {};
+ $.extend(form, {
+ 'fname': fname,
+ 'pageid': pageid,
+ 'arg': $.map(cw.utils.sliceList(arguments, 2), jQuery.toJSON)
+ });
+ return form;
+}
+
+/**
+ * .. function:: loadxhtml(url, form, reqtype='get', mode='replace', cursor=true)
*
- * @param mode how the replacement should be done (default is 'replace')
- * Possible values are :
+ * build url given by absolute or relative `url` and `form` parameters
+ * (dictionary), fetch it using `reqtype` method, then evaluate the
+ * returned XHTML and insert it according to `mode` in the
+ * document. Possible modes are :
+ *
* - 'replace' to replace the node's content with the generated HTML
* - 'swap' to replace the node itself with the generated HTML
* - 'append' to append the generated HTML to the node's content
+ *
+ * If `cursor`, turn mouse cursor into 'progress' cursor until the remote call
+ * is back.
*/
-jQuery.fn.loadxhtml = function(url, data, reqtype, mode) {
- var ajax = null;
- if (reqtype == 'post') {
- ajax = jQuery.post;
- } else {
- ajax = jQuery.get;
+jQuery.fn.loadxhtml = function(url, form, reqtype, mode, cursor) {
+ if (this.size() > 1) {
+ cw.log('loadxhtml was called with more than one element');
}
- if (this.size() > 1) {
- log('loadxhtml was called with more than one element');
+ var callback = null;
+ if (form && form.callback) {
+ cw.log('[3.9] callback given through form.callback is deprecated, add ' + 'callback on the defered');
+ callback = form.callback;
+ delete form.callback;
}
var node = this.get(0); // only consider the first element
- mode = mode || 'replace';
- var callback = null;
- if (data && data.callback) {
- callback = data.callback;
- delete data.callback;
+ if (cursor) {
+ setProgressCursor();
}
- ajax(url, data, function(response) {
+ var d = loadRemote(url, form, reqtype);
+ d.addCallback(function(response) {
var domnode = getDomFromResponse(response);
- domnode = preprocessAjaxLoad(node, domnode);
+ domnode = loadAjaxHtmlHead(domnode);
+ mode = mode || 'replace';
+ // make sure the component is visible
+ $(node).removeClass("hidden");
if (mode == 'swap') {
var origId = node.id;
- node = swapDOM(node, domnode);
+ node = cw.swapDOM(node, domnode);
if (!node.id) {
node.id = origId;
}
@@ -138,19 +265,97 @@
} else if (mode == 'append') {
jQuery(node).append(domnode);
}
- postAjaxLoad(node);
+ _postAjaxLoad(node);
while (jQuery.isFunction(callback)) {
callback = callback.apply(this, [domnode]);
}
});
-};
+ d.addErrback(remoteCallFailed);
+ if (cursor) {
+ d.addCallback(resetCursor);
+ d.addErrback(resetCursor);
+ }
+ return d;
+}
+/**
+ * .. function:: loadRemote(url, form, reqtype='GET', sync=false)
+ *
+ * Asynchronously (unless `async` argument is set to false) load an url or path
+ * and return a deferred whose callbacks args are decoded according to the
+ * Content-Type response header. `form` should be additional form params
+ * dictionary, `reqtype` the HTTP request type (get 'GET' or 'POST').
+ */
+function loadRemote(url, form, reqtype, sync) {
+ if (!url.startswith(baseuri())) {
+ url = baseuri() + url;
+ }
+ if (!sync) {
+ var deferred = new Deferred();
+ jQuery.ajax({
+ url: url,
+ type: (reqtype || 'GET').toUpperCase(),
+ data: form,
+ async: true,
+
+ beforeSend: function(xhr) {
+ deferred._req = xhr;
+ },
+
+ success: function(data, status) {
+ if (deferred._req.getResponseHeader("content-type") == 'application/json') {
+ data = cw.evalJSON(data);
+ }
+ deferred.success(data);
+ },
+ error: function(xhr, status, error) {
+ try {
+ if (xhr.status == 500) {
+ var reason_dict = cw.evalJSON(xhr.responseText);
+ deferred.error(xhr, status, reason_dict['reason']);
+ return;
+ }
+ } catch(exc) {
+ cw.log('error with server side error report:' + exc);
+ }
+ deferred.error(xhr, status, null);
+ }
+ });
+ return deferred;
+ } else {
+ var result = jQuery.ajax({
+ url: url,
+ type: (reqtype || 'GET').toUpperCase(),
+ data: form,
+ async: false
+ });
+ if (result) {
+ // XXX no good reason to force json here,
+ // it should depends on request content-type
+ result = cw.evalJSON(result.responseText);
+ }
+ return result
+ }
+}
-/* finds each dynamic fragment in the page and executes the
+//============= higher level AJAX functions using remote calls ===============//
+/**
+ * .. function:: _(message)
+ *
+ * emulation of gettext's _ shortcut
+ */
+function _(message) {
+ return loadRemote('json', ajaxFuncArgs('i18n', null, [message]), 'GET', true)[0];
+}
+
+/**
+ * .. function:: _loadDynamicFragments(node)
+ *
+ * finds each dynamic fragment in the page and executes the
* the associated RQL to build them (Async call)
*/
-function loadDynamicFragments(node) {
+function _loadDynamicFragments(node) {
if (node) {
var fragments = jQuery(node).find('div.dynamicFragment');
} else {
@@ -162,247 +367,136 @@
if (typeof LOADING_MSG == 'undefined') {
LOADING_MSG = 'loading'; // this is only a safety belt, it should not happen
}
- for(var i=0; i<fragments.length; i++) {
+ for (var i = 0; i < fragments.length; i++) {
var fragment = fragments[i];
fragment.innerHTML = '<h3>' + LOADING_MSG + ' ... <img src="data/loading.gif" /></h3>';
+ var $fragment = jQuery(fragment);
// if cubicweb:loadurl is set, just pick the url et send it to loadxhtml
- var url = getNodeAttribute(fragment, 'cubicweb:loadurl');
+ var url = $fragment.attr('cubicweb:loadurl');
if (url) {
- jQuery(fragment).loadxhtml(url);
+ $fragment.loadxhtml(url);
continue;
}
// else: rebuild full url by fetching cubicweb:rql, cubicweb:vid, etc.
- var rql = getNodeAttribute(fragment, 'cubicweb:rql');
- var items = getNodeAttribute(fragment, 'cubicweb:vid').split('&');
+ var rql = $fragment.attr('cubicweb:rql');
+ var items = $fragment.attr('cubicweb:vid').split('&');
var vid = items[0];
var extraparams = {};
// case where vid='myvid¶m1=val1¶m2=val2': this is a deprecated abuse-case
if (items.length > 1) {
- console.log("[3.5] you're using extraargs in cubicweb:vid attribute, this is deprecated, consider using loadurl instead");
- for (var j=1; j<items.length; j++) {
+ cw.log("[3.5] you're using extraargs in cubicweb:vid " +
+ "attribute, this is deprecated, consider using " +
+ "loadurl instead");
+ for (var j = 1; j < items.length; j++) {
var keyvalue = items[j].split('=');
extraparams[keyvalue[0]] = keyvalue[1];
}
}
- var actrql = getNodeAttribute(fragment, 'cubicweb:actualrql');
- if (actrql) { extraparams['actualrql'] = actrql; }
- var fbvid = getNodeAttribute(fragment, 'cubicweb:fallbackvid');
- if (fbvid) { extraparams['fallbackvid'] = fbvid; }
- replacePageChunk(fragment.id, rql, vid, extraparams);
- }
-}
-
-jQuery(document).ready(function() {loadDynamicFragments();});
-
-//============= base AJAX functions to make remote calls =====================//
-
-function remoteCallFailed(err, req) {
- if (req.status == 500) {
- updateMessage(err);
- } else {
- log(err);
- updateMessage(_("an error occured while processing your request"));
+ var actrql = $fragment.attr('cubicweb:actualrql');
+ if (actrql) {
+ extraparams['actualrql'] = actrql;
+ }
+ var fbvid = $fragment.attr('cubicweb:fallbackvid');
+ if (fbvid) {
+ extraparams['fallbackvid'] = fbvid;
+ }
+ extraparams['rql'] = rql;
+ extraparams['vid'] = vid;
+ $fragment.loadxhtml('json', ajaxFuncArgs('view', extraparams));
}
}
-
-/*
- * This function will call **synchronously** a remote method on the cubicweb server
- * @param fname: the function name to call (as exposed by the JSONController)
- *
- * additional arguments will be directly passed to the specified function
- *
- * It looks at http headers to guess the response type.
- */
-function remoteExec(fname /* ... */) {
- setProgressCursor();
- var props = {'fname' : fname, 'pageid' : pageid,
- 'arg': map(jQuery.toJSON, sliceList(arguments, 1))};
- var result = jQuery.ajax({url: JSON_BASE_URL, data: props, async: false}).responseText;
- if (result) {
- result = evalJSON(result);
- }
- resetCursor();
- return result;
-}
-
-/*
- * This function will call **asynchronously** a remote method on the json
- * controller of the cubicweb http server
- *
- * @param fname: the function name to call (as exposed by the JSONController)
- *
- * additional arguments will be directly passed to the specified function
- *
- * It looks at http headers to guess the response type.
- */
-
-function asyncRemoteExec(fname /* ... */) {
- setProgressCursor();
- var props = {'fname' : fname, 'pageid' : pageid,
- 'arg': map(jQuery.toJSON, sliceList(arguments, 1))};
- // XXX we should inline the content of loadRemote here
- var deferred = loadRemote(JSON_BASE_URL, props, 'POST');
- deferred = deferred.addErrback(remoteCallFailed);
- deferred = deferred.addErrback(resetCursor);
- deferred = deferred.addCallback(resetCursor);
- return deferred;
-}
-
-
-/* emulation of gettext's _ shortcut
- */
-function _(message) {
- return remoteExec('i18n', [message])[0];
-}
-
-function userCallback(cbname) {
- asyncRemoteExec('user_callback', cbname);
-}
+jQuery(document).ready(function() {
+ _loadDynamicFragments();
+});
function unloadPageData() {
// NOTE: do not make async calls on unload if you want to avoid
// strange bugs
- remoteExec('unload_page_data');
+ loadRemote('json', ajaxFuncArgs('unload_page_data'), 'GET', true);
+}
+
+function removeBookmark(beid) {
+ var d = loadRemote('json', ajaxFuncArgs('delete_bookmark', null, beid));
+ d.addCallback(function(boxcontent) {
+ $('#bookmarks_box').loadxhtml('json',
+ ajaxFuncArgs('render', null, 'boxes',
+ 'bookmarks_box'));
+ document.location.hash = '#header';
+ updateMessage(_("bookmark has been removed"));
+ });
+}
+
+function userCallback(cbname) {
+ setProgressCursor();
+ var d = loadRemote('json', ajaxFuncArgs('user_callback', null, cbname));
+ d.addCallback(resetCursor);
+ d.addErrback(resetCursor);
+ d.addErrback(remoteCallFailed);
+ return d;
}
+function userCallbackThenUpdateUI(cbname, compid, rql, msg, registry, nodeid) {
+ var d = userCallback(cbname);
+ d.addCallback(function() {
+ $('#' + nodeid).loadxhtml('json', ajaxFuncArgs('render', {'rql': rql},
+ registry, compid));
+ if (msg) {
+ updateMessage(msg);
+ }
+ });
+}
+
+function userCallbackThenReloadPage(cbname, msg) {
+ var d = userCallback(cbname);
+ d.addCallback(function() {
+ window.location.reload();
+ if (msg) {
+ updateMessage(msg);
+ }
+ });
+}
+
+/**
+ * .. function:: unregisterUserCallback(cbname)
+ *
+ * unregisters the python function registered on the server's side
+ * while the page was generated.
+ */
+function unregisterUserCallback(cbname) {
+ setProgressCursor();
+ var d = loadRemote('json', ajaxFuncArgs('unregister_user_callback',
+ null, cbname));
+ d.addCallback(resetCursor);
+ d.addErrback(resetCursor);
+ d.addErrback(remoteCallFailed);
+}
+
+//============= XXX move those functions? ====================================//
function openHash() {
if (document.location.hash) {
var nid = document.location.hash.replace('#', '');
var node = jQuery('#' + nid);
- if (node) { removeElementClass(node, "hidden"); }
+ if (node) {
+ $(node).removeClass("hidden");
+ }
};
}
jQuery(document).ready(openHash);
-function reloadComponent(compid, rql, registry, nodeid, extraargs) {
- registry = registry || 'components';
- rql = rql || '';
- nodeid = nodeid || (compid + 'Component');
- extraargs = extraargs || {};
- var node = getNode(nodeid);
- var d = asyncRemoteExec('component', compid, rql, registry, extraargs);
- d.addCallback(function(result, req) {
- var domnode = getDomFromResponse(result);
- if (node) {
- // make sure the component is visible
- removeElementClass(node, "hidden");
- domnode = preprocessAjaxLoad(node, domnode);
- swapDOM(node, domnode);
- postAjaxLoad(domnode);
- }
- });
- d.addCallback(resetCursor);
- d.addErrback(function(xxx) {
- updateMessage(_("an error occured"));
- log(xxx);
- });
- return d;
-}
-
-/* XXX: HTML architecture of cubicweb boxes is a bit strange */
-function reloadBox(boxid, rql) {
- return reloadComponent(boxid, rql, 'boxes', boxid);
-}
-
-function userCallbackThenUpdateUI(cbname, compid, rql, msg, registry, nodeid) {
- var d = asyncRemoteExec('user_callback', cbname);
- d.addCallback(function() {
- reloadComponent(compid, rql, registry, nodeid);
- if (msg) { updateMessage(msg); }
- });
- d.addCallback(resetCursor);
- d.addErrback(function(xxx) {
- updateMessage(_("an error occured"));
- log(xxx);
- return resetCursor();
- });
-}
-
-function userCallbackThenReloadPage(cbname, msg) {
- var d = asyncRemoteExec('user_callback', cbname);
- d.addCallback(function() {
- window.location.reload();
- if (msg) { updateMessage(msg); }
- });
- d.addCallback(resetCursor);
- d.addErrback(function(xxx) {
- updateMessage(_("an error occured"));
- log(xxx);
- return resetCursor();
- });
-}
-
-/*
- * unregisters the python function registered on the server's side
- * while the page was generated.
- */
-function unregisterUserCallback(cbname) {
- var d = asyncRemoteExec('unregister_user_callback', cbname);
- d.addCallback(function() {resetCursor();});
- d.addErrback(function(xxx) {
- updateMessage(_("an error occured"));
- log(xxx);
- return resetCursor();
- });
-}
-
-
-/* executes an async query to the server and replaces a node's
- * content with the query result
+/**
+ * .. function:: buildWysiwygEditors(parent)
*
- * @param nodeId the placeholder node's id
- * @param rql the RQL query
- * @param vid the vid to apply to the RQL selection (default if not specified)
- * @param extraparmas table of additional query parameters
- */
-function replacePageChunk(nodeId, rql, vid, extraparams, /* ... */ swap, callback) {
- var params = null;
- if (callback) {
- params = {callback: callback};
- }
-
- var node = jQuery('#' + nodeId)[0];
- var props = {};
- if (node) {
- props['rql'] = rql;
- props['fname'] = 'view';
- props['pageid'] = pageid;
- if (vid) { props['vid'] = vid; }
- if (extraparams) { jQuery.extend(props, extraparams); }
- // FIXME we need to do asURL(props) manually instead of
- // passing `props` directly to loadxml because replacePageChunk
- // is sometimes called (abusively) with some extra parameters in `vid`
- var mode = swap?'swap':'replace';
- var url = JSON_BASE_URL + asURL(props);
- jQuery(node).loadxhtml(url, params, 'get', mode);
- } else {
- log('Node', nodeId, 'not found');
- }
-}
-
-/* XXX deprecates?
- * fetches `url` and replaces `nodeid`'s content with the result
- * @param replacemode how the replacement should be done (default is 'replace')
- * Possible values are :
- * - 'replace' to replace the node's content with the generated HTML
- * - 'swap' to replace the node itself with the generated HTML
- * - 'append' to append the generated HTML to the node's content
- */
-function loadxhtml(nodeid, url, /* ... */ replacemode) {
- jQuery('#' + nodeid).loadxhtml(url, null, 'post', replacemode);
-}
-
-/* XXX: this function should go in edition.js but as for now, htmlReplace
+ *XXX: this function should go in edition.js but as for now, htmlReplace
* references it.
*
* replace all textareas with fckeditors.
*/
function buildWysiwygEditors(parent) {
- jQuery('textarea').each(function () {
+ jQuery('textarea').each(function() {
if (this.getAttribute('cubicweb:type') == 'wysiwyg') {
// mark editor as instanciated, we may be called a number of times
- // (see postAjaxLoad)
+ // (see _postAjaxLoad)
this.setAttribute('cubicweb:type', 'fckeditor');
if (typeof FCKeditor != "undefined") {
var fck = new FCKeditor(this.id);
@@ -411,29 +505,29 @@
fck.BasePath = "fckeditor/";
fck.ReplaceTextarea();
} else {
- log('fckeditor could not be found.');
+ cw.log('fckeditor could not be found.');
}
}
});
}
-
jQuery(document).ready(buildWysiwygEditors);
-
-/*
+/**
+ * .. function:: stripEmptyTextNodes(nodelist)
+ *
* takes a list of DOM nodes and removes all empty text nodes
*/
function stripEmptyTextNodes(nodelist) {
/* this DROPS empty text nodes */
var stripped = [];
- for (var i=0; i < nodelist.length; i++) {
+ for (var i = 0; i < nodelist.length; i++) {
var node = nodelist[i];
if (isTextNode(node)) {
- /* all browsers but FF -> innerText, FF -> textContent */
- var text = node.innerText || node.textContent;
- if (text && !text.strip()) {
- continue;
- }
+ /* all browsers but FF -> innerText, FF -> textContent */
+ var text = node.innerText || node.textContent;
+ if (text && ! text.strip()) {
+ continue;
+ }
} else {
stripped.push(node);
}
@@ -441,7 +535,10 @@
return stripped;
}
-/* convenience function that returns a DOM node based on req's result.
+/**
+ * .. function:: getDomFromResponse(response)
+ *
+ * convenience function that returns a DOM node based on req's result.
* XXX clarify the need to clone
* */
function getDomFromResponse(response) {
@@ -462,17 +559,116 @@
}
// several children => wrap them in a single node and return the wrap
return DIV({'cubicweb:type': "cwResponseWrapper"},
- map(function(node) {
- return jQuery(node).clone().context;
- }, children));
+ $.map(children, function(node) {
+ return jQuery(node).clone().context;})
+ );
}
-function postJSON(url, data, callback) {
- return jQuery.post(url, data, callback, 'json');
-}
+/* DEPRECATED *****************************************************************/
+
+preprocessAjaxLoad = cw.utils.deprecatedFunction(
+ '[3.9] preprocessAjaxLoad() is deprecated, use loadAjaxHtmlHead instead',
+ function(node, newdomnode) {
+ return loadAjaxHtmlHead(newdomnode);
+ }
+);
+
+reloadComponent = cw.utils.deprecatedFunction(
+ '[3.9] reloadComponent() is deprecated, use loadxhtml instead',
+ function(compid, rql, registry, nodeid, extraargs) {
+ registry = registry || 'components';
+ rql = rql || '';
+ nodeid = nodeid || (compid + 'Component');
+ extraargs = extraargs || {};
+ var node = cw.jqNode(nodeid);
+ return node.loadxhtml('json', ajaxFuncArgs('component', null, compid,
+ rql, registry, extraargs));
+ }
+);
+
+reloadBox = cw.utils.deprecatedFunction(
+ '[3.9] reloadBox() is deprecated, use loadxhtml instead',
+ function(boxid, rql) {
+ return reloadComponent(boxid, rql, 'boxes', boxid);
+ }
+);
-function getJSON(url, data, callback){
- return jQuery.get(url, data, callback, 'json');
-}
+replacePageChunk = cw.utils.deprecatedFunction(
+ '[3.9] replacePageChunk() is deprecated, use loadxhtml instead',
+ function(nodeId, rql, vid, extraparams, /* ... */ swap, callback) {
+ var params = null;
+ if (callback) {
+ params = {
+ callback: callback
+ };
+ }
+ var node = jQuery('#' + nodeId)[0];
+ var props = {};
+ if (node) {
+ props['rql'] = rql;
+ props['fname'] = 'view';
+ props['pageid'] = pageid;
+ if (vid) {
+ props['vid'] = vid;
+ }
+ if (extraparams) {
+ jQuery.extend(props, extraparams);
+ }
+ // FIXME we need to do asURL(props) manually instead of
+ // passing `props` directly to loadxml because replacePageChunk
+ // is sometimes called (abusively) with some extra parameters in `vid`
+ var mode = swap ? 'swap': 'replace';
+ var url = JSON_BASE_URL + asURL(props);
+ jQuery(node).loadxhtml(url, params, 'get', mode);
+ } else {
+ cw.log('Node', nodeId, 'not found');
+ }
+ }
+);
+
+loadxhtml = cw.utils.deprecatedFunction(
+ '[3.9] loadxhtml() function is deprecated, use loadxhtml method instead',
+ function(nodeid, url, /* ... */ replacemode) {
+ jQuery('#' + nodeid).loadxhtml(url, null, 'post', replacemode);
+ }
+);
-CubicWeb.provide('ajax.js');
+remoteExec = cw.utils.deprecatedFunction(
+ '[3.9] remoteExec() is deprecated, use loadRemote instead',
+ function(fname /* ... */) {
+ setProgressCursor();
+ var props = {
+ 'fname': fname,
+ 'pageid': pageid,
+ 'arg': $.map(cw.utils.sliceList(arguments, 1), jQuery.toJSON)
+ };
+ var result = jQuery.ajax({
+ url: JSON_BASE_URL,
+ data: props,
+ async: false
+ }).responseText;
+ if (result) {
+ result = cw.evalJSON(result);
+ }
+ resetCursor();
+ return result;
+ }
+);
+
+asyncRemoteExec = cw.utils.deprecatedFunction(
+ '[3.9] asyncRemoteExec() is deprecated, use loadRemote instead',
+ function(fname /* ... */) {
+ setProgressCursor();
+ var props = {
+ 'fname': fname,
+ 'pageid': pageid,
+ 'arg': $.map(cw.utils.sliceList(arguments, 1), jQuery.toJSON)
+ };
+ // XXX we should inline the content of loadRemote here
+ var deferred = loadRemote(JSON_BASE_URL, props, 'POST');
+ deferred = deferred.addErrback(remoteCallFailed);
+ deferred = deferred.addErrback(resetCursor);
+ deferred = deferred.addCallback(resetCursor);
+ return deferred;
+ }
+);