I didn’t want to have to tell you this way, but there’s just no way around it: in Internet Explorer 7 (I’ve left testing 6 and 8 as an exercise for the reader 🙂 ) the parentNode property can flat out lie to you – specifically – with pasted content in a rich text editor like TinyMCE. That’s right, a bold-faced chain-yanking tall-tale’d lie, and I’ll prove it to you.
According to the W3C documentation, “the parentNode property returns the parent node of a node.” And based on that, you would expect the following code to alert “true!” for as many times as the node has children:
var node = document.getElementById(‘someElement’);
Just get to the Demo!
I’ve set up a demo page that can consistently repeat the bug. For the demo to work, you’ll need to:
- use Internet Explorer 7
- open the attached rtf in WordPad
- paste into the TinyMCE content area
- press the “validate” button on the bottom toolbar
Besides IE’s fearsome use of the DIR tag, you’ll notice:
- I’ve painted duplicate nodes red in TinyMCE
- An brief XML output of the DOM is output into a text area beneath TinyMCE showing the duplicate node
- A count of each node is displayed as an attribute in the text area. Notice the count=2 in the nodes at the bottom of the textarea! Yikes!
If you’re not in the mood to fire up the demo yourself, just click the link below to see what the DOM ends up looking like. Take special notice of the count=2 on the nodes at the bottom:
Try It Yourself!
A TinyMCE Bug?
An obvious question is: is this a TinyMCE bug? and the answer is “No.” There is no way to manually add the exact same node to multiple places in the DOM. Instead, the browser simply moves the node to the new place, and removes it from its original location. Even if Spocke tried to create this bug, he couldn’t 🙂
If you believe me, skip to the conclusion. If you don’t believe me, open up this second demo that uses the following code to append a node without calling removeChild() first. Even without specifically removing a node before appending it somewhere else, there still only exists one node in the document:
var node = document.getElementById(“copyMe”);
var target = document.getElementById(“target”);
As far as parentNode is concerned, if:
- you’re writing a plugin for TinyMCE or similar
- you’re dealing with (possibly) pasted content
- relying on parentNode
- validate! If(myNode != myNode.childNodes[i].parentNode) is true then you have a problem!
I hope you enjoyed the latest the-undocumented-life-of post! Also a fun read: The undocumented life of jQuery’s .append()!