[FIX] convert XML documents to HTML in MSIE so jQuery does not bork its parsing
authorXavier Morel <xmo@openerp.com>
Wed, 18 Jan 2012 10:40:15 +0000 (11:40 +0100)
committerXavier Morel <xmo@openerp.com>
Wed, 18 Jan 2012 10:40:15 +0000 (11:40 +0100)
done via DOM traversal, slow as shit and currently drops half the attributes

bzr revid: xmo@openerp.com-20120118104015-ot102e8yniqjd4bf

addons/web/static/lib/qweb/qweb2.js

index 8657a8b..7dcac2e 100644 (file)
@@ -93,10 +93,10 @@ var QWeb2 = {
                 }
                 return r.join('');
             } else {
-                if (node.xml !== undefined) {
-                    return node.xml;
-                } else {
+                if (typeof XMLSerializer !== 'undefined') {
                     return (new XMLSerializer()).serializeToString(node);
+                } else {
+                    return node.outerHTML;
                 }
             }
         },
@@ -265,11 +265,16 @@ QWeb2.Engine = (function() {
                     }
                     req.open('GET', s, false);
                     req.send(null);
-                    if (req.responseXML) {
-                        if (req.responseXML.documentElement.nodeName == "parsererror") {
-                            return this.tools.exception(req.responseXML.documentElement.childNodes[0].nodeValue);
+                    var xDoc = req.responseXML;
+                    if (xDoc) {
+                        if (xDoc.documentElement.nodeName == "parsererror") {
+                            return this.tools.exception(xDoc.documentElement.childNodes[0].nodeValue);
+                        }
+                        if (xDoc.xml !== undefined) {
+                            // MSIE
+                            return this.convert_xml_to_html(xDoc.documentElement);
                         }
-                        return req.responseXML;
+                        return xDoc;
                     } else {
                         return this.load_xml_string(req.responseText);
                     }
@@ -295,7 +300,27 @@ QWeb2.Engine = (function() {
             xDoc.async = false;
             xDoc.preserveWhiteSpace = true;
             xDoc.loadXML(s);
-            return xDoc;
+            return this.convert_xml_to_html(xDoc.documentElement);
+        },
+        convert_xml_to_html: function (node) {
+            var character_data = {
+                3: document.createTextNode,
+                4: document.createCDATASection,
+                8: document.createComment
+            };
+            if (node.nodeType in character_data) {
+                return character_data[node.nodeType](node.data);
+            }
+
+            var hnode = document.createElement(node.nodeName);
+            for(var i=0, alen=node.attributes.length; i < alen; ++i) {
+                var attr = node.attributes[i];
+                hnode.setAttribute(attr.name, attr.value);
+            }
+            for(var j=0, clen=node.childNodes.length; j < clen; ++j) {
+                hnode.appendChild(this.convert_xml_to_html(node.childNodes[j]));
+            }
+            return hnode;
         },
         has_template : function(template) {
             return !!this.templates[template];
@@ -373,12 +398,7 @@ QWeb2.Engine = (function() {
             if (!this.jQuery) {
                 return this.tools.exception("Can't extend template " + template + " without jQuery");
             }
-            var template_dest = this.templates[template],
-                msie_trololo = false;
-            if (template_dest.xml !== undefined) {
-                template_dest = this.jQuery(template_dest.xml);
-                msie_trololo = true;
-            }
+            var template_dest = this.templates[template];
             for (var i = 0, ilen = extend_node.childNodes.length; i < ilen; i++) {
                 var child = extend_node.childNodes[i];
                 if (child.nodeType === 1) {
@@ -421,9 +441,6 @@ QWeb2.Engine = (function() {
                     }
                 }
             }
-            if (msie_trololo) {
-                this.templates[template] = template_dest[0];
-            }
         }
     });
     return Engine;