[javascript] remove ajaxHtmlHead from dom response once it has been processed. stable
authorAdrien Di Mascio <Adrien.DiMascio@logilab.fr>
Tue, 22 Dec 2009 10:42:39 +0100
branchstable
changeset 4174 860f622a31aa
parent 4148 748454627176
child 4175 92a10d2a09af
[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.
web/data/cubicweb.ajax.js
--- 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) {