User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b1) Gecko/20081007 Firefox/3.1b1 Build Identifier: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b2pre) Gecko/20081015 It is not possible anymore to import or adopt nodes from an XML document retrieved using XHR into a doc created by implementation.createDocument(). The error returned is NS_UNEXPECTED_ERROR Reproducible: Always Steps to Reproduce: 1. Create a document using doc = CC["@mozilla.org/xml/xml-document;1"].createInstance(CI.nsIDOMDocument).implementation.createDocument("", "root", null); 2. Retrieve an XML doc using XHR 3. try node = doc.importNode(xhr.responseXML.documentElement) Actual Results: Fails with NS_UNEXPECTED_ERROR Expected Results: This should work, and was working before
Note that this also fails in any chrome script in an extension, not only in a JS XPCOM component.
Bug 456271 prevented adopting/importing if (1) the new doc doesn't have script handling object (which is the case here) and (2) the original document isn't a chrome document and (3) it does have a script handling object. On IRC you mentioned that you create XHR using .createInstance(). That tries to get the |window| to which it is bound to from stack. Perhaps that is the problem here. Maybe it finds non-chrome window. What causes XHR to be created?
Does it fail if you create XHR using "new XMLHttpRequest()"?
The best thing you could do is to create document using document.implementation.createDocument("", "", null); and XHR using new XMLHttpRequest(); Perhaps you could pass chrome |window| to your JS component and call |new chromeWindow.XMLHttpRequest()| and |chromeWindow.document.implementation.createDocument("", "", null)| ?
Er... why does the XHR document have a script handling object? Or alternately, why does the createDocument()-created object not have one? I would think they would behave identically in this respect... I should note that this code's use of a contract to create XML documents is going to become unsupported in the very near future, but that's not really important to this bug report.
CC["@mozilla.org/xml/xml-document;1"].createInstance(CI.nsIDOMDocument).implementation.createDocument("", "root", null); Doesn't set any script handling object because the original created document doesn't have one. (I don't know why to create 2 documents, first a temporary with .createInstance and then with .createDocument)
I guess the reason the createDocument() doc doesn't have a script handling object in this case is in fact due to the use of the contract id thing, huh? Getting the window from the stack sounds like a bad-and-frightening thing to me.... :( Also, does DOMParser have similar issues if created via contract? This whole script handling object thing needs to go. It's basically incompatible with sane use in JS components, if it requires everything to have a DOMWindow... :(
(In reply to comment #5) > Er... why does the XHR document have a script handling object? We could perhaps remove the Init thing, which tries to get the script object. C++ should always call Init explicitly and JS should use new XMLHttpRequest syntax.
(In reply to comment #7) > This whole script handling object thing needs to go. It's basically > incompatible with sane use in JS components, if it requires everything to have > a DOMWindow... :( I know. The problem is in XPConnect.
I should note that for DOMParser we expose a JS-callable init() to be used from JS components, but the hack job of adding init() to XMLHttpRequest didn't copy that over. I should also note that the JS-callable DOMParser init() doesn't take a script global object. Should it? Again, the goal is to be able to use all this stuff in a sane way in a JS component. As for the XPConnect thing... What that really means is that XHR and so forth need a JSContext, right? They don't actually need a script global, as far as I can tell.
In particular, I would think that a JS component has a sane JSContext, but I'm not sure it would outlive the initial execution of the component's script. :(
Oh, and comment 8 is a non-starter precisely because JS components can't use |new XMLHttpRequest()|.
FWIW this is a regression between firefox 3.0.x and 3.5. TBH from the comments I can't gleam exactly what is supposed to be the correct behavior. This is what used to work in older version of mozilla: var xmlNode = someXHRXMLNode; // recv from a XMLHTTPRequest var doc = Cc["@mozilla.org/xml/xml-document;1"].createInstance(Ci.nsIDOMDocument); // more code to create document // this line blows up with NS_UNEXPECTED_ERROR someNodeInNewDoc.appendChild(doc.importNode(xmlNode,true)); The solution (as hinted at above) is to make sure both documents are created using the same implementation. Luckily from any DOM node you can can get back to the implementation. What worked for me: var doc = xmlNode.ownerDocument.implementation.createDocument(null,"yourroottag",null); doc.documentElement.appendChild(doc.importNode(xmlNode,true));
> FWIW this is a regression between firefox 3.0.x and 3.5. Yes, we know. See comment 2.
This is an issue if you use document.implementation.createHTMLDocument() to create an HTML document on the fly, then attempt to insert it into an iframe as well.
Er... what does comment 16 have to do with this bug? You can't insert dynamically created documents into iframes. Or do you mean that you're inserting nodes from that document?