Last Comment Bug 567484 - Copying nodes in an XML tree removes the source node
: Copying nodes in an XML tree removes the source node
Product: Rhino
Classification: Components
Component: E4X (show other bugs)
: other
: All All
: -- major (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
Depends on:
  Show dependency treegraph
Reported: 2010-05-21 16:39 PDT by Alberto Saez Torres
Modified: 2010-05-21 16:45 PDT (History)
0 users
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---

Avoid the use of replaceChild method (593 bytes, patch)
2010-05-21 16:45 PDT, Alberto Saez Torres
no flags Details | Diff | Splinter Review

Description Alberto Saez Torres 2010-05-21 16:39:56 PDT
User-Agent:       Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; es-ES; rv: Gecko/20100401 Firefox/3.6.3
Build Identifier: rhino1_7R3pre

When copying nodes in a node tree, removes the original Name.

For example, for the next code:

var tmp =<xml>
   <group>Group One</group>
   <group>Group Two</group>
   <group>Group Three</group>

The result XML of "tmp" is:

   <group>Group Three</group>
   <group>Group Two</group>

The 3ΒΊ "group" element has been removed after.

Reproducible: Always

Actual Results:  
   <group>Group Three</group>
   <group>Group Two</group>

Expected Results:  
tmp result as seeing in spiderMonkey

   <group>Group Three</group>
   <group>Group Two</group>
   <group>Group Three</group>

The problem is related to the function of XmlNode 

void replaceWith(XmlNode other) {
  Node replacement = other.dom;
  if (replacement.getOwnerDocument() != this.dom.getOwnerDocument()) {
     replacement = this.dom.getOwnerDocument().importNode(replacement, true);
  this.dom.getParentNode().replaceChild(replacement, this.dom);

When the function is aplied to a node of the same xml tree, the function importNode has the following behaviour:

Node replaceChild(Node newChild, Node oldChild)  throws DOMException

Replaces the child node oldChild with newChild in the list of children, and returns the oldChild node. 
If newChild is a DocumentFragment object, oldChild is replaced by all of the DocumentFragment children, which are inserted in the same order. If the newChild is already in the tree, it is first removed.

So, my proposal is to change the method to the next:

void replaceWith(XmlNode other) {
   Node replacement = this.dom.getOwnerDocument().importNode(other.dom, true);
   this.dom.getParentNode().replaceChild(replacement, this.dom);
Comment 1 Alberto Saez Torres 2010-05-21 16:45:28 PDT
Created attachment 446843 [details] [diff] [review]
Avoid the use of replaceChild method

Note You need to log in before you can comment on or make changes to this bug.