Node.cloneNode () is incompatible with DOM Spec
It is well documented (mostly on SO) that using Node.cloneNode(true)
in <input type="text">
returns a new <input>
node with the same text content as the original, but clones a <select>
(after the user selected) returns a new one <select>
without the user selecting. This is not in line with the spec at first because according to DOM 3 :
cloneNode
Returns a duplicate of this node, i.e. Serves as a generic copy constructor for nodes. The duplicate node has no parent (parentNode is null) and no user data. User data associated with the imported node is not migrated.
The answer to why this is happening is explained somewhat later, but it is clearer in the DOM 2 spec .
cloneNode
Cloning the Element copies all attributes and their values, including those generated by the XML processor to represent the default attributes, but this method does not copy any text unless it is a deep clone, since the text is contained in the child Text node.
I agree to accept this behavior with this wording in mind, although I would say it <input>
does not contain text node since the property childNodes
for <input>
will always be empty NodeList
regardless of whether it contains text (in the spec spec "has text node").
At least I understand that user selectable <option>
counts as user data, so it makes sense that this is not cloned. In this case, this "user data" is contained in the property selected
<option>
.
However, when trying to execute behavior using radio buttons and checkboxes , the behavior in Chrome 38, FF 33, Safari 6.2 completely ignores the above definition. Cloning checked checkboxes or selected radio buttons maintains their checked state. This seems to contradict the specification, as this information is "user data" that (for example <select>
) is contained in the property (in this case checked
).
Is it correct that this is out of specification? If not, is there somewhere else where this behavior is defined? And if so, is there a use case explaining why it is cloneNode()
so inconsistent with how it clones the states of user input fields?
Edit. By testing this on my set of browsers, I found that Opera 12.15 works as I would like with inputs <select>
. Namely, it stores the user's selection on the clone.
source to share
DOM level 4 defines the steps for cloning the clearlier:
Specifications can define cloning steps for all or some of the nodes . The algorithm is passed by copy, node, document and optionally, the clone children flag, as specified in the clone algorithm.
To clone a node, optionally with document and clone children, do the following:
If no document is specified, let the document be node node document .
Copy a node that implements the same interfaces as node.
If copy is document , set node document and document to copy.
Otherwise, copy the node document into the document.Copy the following from node to copy depending on the node type:
Document
encoding , content type , URL , its mode ( quirks mode , limited quirks mode , or no-quirks mode ) and its type ( XML document or HTML document ).
DocumentType
name , public identifier, and system identifier .
Element
namespace , namespace prefix , local name and its list of attributes .
ProcessingInstruction
Its target and data .Any other node
-Run any cloning steps defined for node in other applicable specifications and pass the copy, node, document, and clone children flag, if set, as parameters.
If the clone children flag is set, clone all children from the node and add them to copy, with the document as specified and the clones flag flag set.
Check in a copy.
The method
cloneNode(deep)
should return the clone context object , with the clones flag set, if the depth value is true.
Both select
and input
are Element
s, so only their namespace , namespace prefix , local name and should be copied in step 4.
However, in step 5, additional cloning steps can be performed. Probably, these steps include up properties value
and selected
in the case of elements input
.
source to share