[javascript] remove ajaxHtmlHead from dom response once it has been processed.
This fixes #549138: treeview: folding is broken
The new, systematic, pageid management (introduced by rev 37b376bb4088) made
the treeview return :
<ul class="treeview">...</ul>
<div class="ajaxHtmlHead">...</div>
which was then processed by getDomFromResponse and wrapped into
a single div node :
<div>
<ul class="treeview">...</ul>
<div class="ajaxHtmlHead">...</div>
</div>
In the treeview case, the node inserted into the tree was the wrapping
<div> instead of the <ul>, causing the folding bug mentioned in the
ticket.
--- a/web/data/cubicweb.ajax.js Fri Dec 18 15:59:19 2009 +0100
+++ b/web/data/cubicweb.ajax.js Tue Dec 22 10:42:39 2009 +0100
@@ -28,20 +28,46 @@
}
/*
- * inspect dom response, search for a <div class="ajaxHtmlHead"> node and
- * put its content into the real document's head.
+ * inspect dom response (as returned by getDomFromResponse), search for
+ * a <div class="ajaxHtmlHead"> node and put its content into the real
+ * document's head.
* This enables dynamic css and js loading and is used by replacePageChunk
*/
-function loadAjaxHtmlHead(node) {
- var head = jQuery('head');
- node = jQuery(node).find('div.ajaxHtmlHead');
- _loadAjaxHtmlHead(node, head, 'script', 'src');
- _loadAjaxHtmlHead(node, head, 'link', 'href');
- node.find('*').appendTo(head);
+function loadAjaxHtmlHead(response) {
+ var $head = jQuery('head');
+ var $responseHead = jQuery(response).find('div.ajaxHtmlHead');
+ // no ajaxHtmlHead found, no processing required
+ if (!$responseHead.length) {
+ return response;
+ }
+ _loadAjaxHtmlHead($responseHead, $head, 'script', 'src');
+ _loadAjaxHtmlHead($responseHead, $head, 'link', 'href');
+ // add any remaining children (e.g. meta)
+ $responseHead.children().appendTo($head);
+ // remove original container, which is now empty
+ $responseHead.remove();
+ // if there was only one actual node in the reponse besides
+ // the ajaxHtmlHead, then remove the wrapper created by
+ // getDomFromResponse() and return this single element
+ // For instance :
+ // 1/ CW returned the following content :
+ // <div>the-actual-content</div><div class="ajaxHtmlHead">...</div>
+ // 2/ getDomFromReponse() wrapped this into a single DIV to hold everything
+ // in one, unique, dom element
+ // 3/ now that we've removed the ajaxHtmlHead div, the only
+ // node left in the wrapper if the 'real' node built by the view,
+ // 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') {
+ return response.firstChild;
+ }
+ return response;
}
function preprocessAjaxLoad(node, newdomnode) {
- loadAjaxHtmlHead(newdomnode);
+ return loadAjaxHtmlHead(newdomnode);
}
function postAjaxLoad(node) {
@@ -102,23 +128,23 @@
delete data.callback;
}
ajax(url, data, function(response) {
- var domnode = getDomFromResponse(response);
- preprocessAjaxLoad(node, domnode);
- if (mode == 'swap') {
- var origId = node.id;
- node = swapDOM(node, domnode);
- if (!node.id) {
- node.id = origId;
- }
- } else if (mode == 'replace') {
- jQuery(node).empty().append(domnode);
- } else if (mode == 'append') {
- jQuery(node).append(domnode);
- }
- postAjaxLoad(node);
- while (jQuery.isFunction(callback)) {
- callback = callback.apply(this, [domnode]);
- }
+ var domnode = getDomFromResponse(response);
+ domnode = preprocessAjaxLoad(node, domnode);
+ if (mode == 'swap') {
+ var origId = node.id;
+ node = swapDOM(node, domnode);
+ if (!node.id) {
+ node.id = origId;
+ }
+ } else if (mode == 'replace') {
+ jQuery(node).empty().append(domnode);
+ } else if (mode == 'append') {
+ jQuery(node).append(domnode);
+ }
+ postAjaxLoad(node);
+ while (jQuery.isFunction(callback)) {
+ callback = callback.apply(this, [domnode]);
+ }
});
};
@@ -430,10 +456,10 @@
return jQuery(children[0]).clone().context;
}
// several children => wrap them in a single node and return the wrap
- return DIV(null, map(function(node) {
- return jQuery(node).clone().context;
- },
- children));
+ return DIV({'cubicweb:type': "cwResponseWrapper"},
+ map(function(node) {
+ return jQuery(node).clone().context;
+ }, children));
}
function postJSON(url, data, callback) {