Last Comment Bug 74219 - Implement NodeInsertedIntoDocument, NodeRemovedFromDocument
: Implement NodeInsertedIntoDocument, NodeRemovedFromDocument
: testcase
Product: Core
Classification: Components
Component: DOM: Events (show other bugs)
: Trunk
: All All
: P3 enhancement with 4 votes (vote)
: mozilla1.0.1
Assigned To: Nobody; OK to take it and work on it
: 74220 (view as bug list)
Depends on: 231676
Blocks: 149654
  Show dependency treegraph
Reported: 2001-03-30 19:54 PST by Jeff Yates
Modified: 2012-06-22 05:47 PDT (History)
19 users (show)
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---

Test case (1.63 KB, text/html)
2004-01-14 09:58 PST, Erik Arvidsson
no flags Details
Test case (1.74 KB, text/html)
2005-09-04 03:18 PDT, Erik Arvidsson
no flags Details

Description Jeff Yates 2001-03-30 19:54:55 PST
NodeInsertedIntoDocument Mutation event needs implemented.

Comment 1 Keyser Sose 2001-04-10 17:49:25 PDT
marking NEW.
Comment 2 Erik Arvidsson 2004-01-14 09:58:43 PST
Created attachment 139035 [details]
Test case
Comment 3 Alex Vincent [:WeirdAl] 2005-09-02 10:22:22 PDT
I think I might implement this (I'm hacking nsDocument for mutation events
anyway for for bug 201236), but I will not attempt to follow bug 231676.
Comment 4 Alex Vincent [:WeirdAl] 2005-09-02 11:01:42 PDT
The testcase given is not comprehensive enough.  DOMNodeInsertedIntoDocument
fires once for every node removed, directly or indirectly.  If you insert the
bar element:


Then you must fire (after the insertion)

(no specific order to the last three)
NodeInserted @ bar
DOMNodeInsertedIntoDocument @ bar
DOMNodeInsertedIntoDocument @ one
DOMNodeInsertedIntoDocument @ two
Comment 5 Alex Vincent [:WeirdAl] 2005-09-02 21:18:05 PDT
I'm going to consolidate this bug and bug 74220; the functionality needed to
implement them will be very similar.

I did a little thinking, based on earlier work I've done today, and realized
that if the node doing the insertion or removal, or any of its ancestors, has a
listener for the document insertion/removal event, then the node, and every one
of its descendants, must have the document insertion/removal event dispatched to it.

Failing that test, dispatch must occur to any descendant node having the event
listener, and any of that node's descendants.

I've written up some JavaScript pseudo-code to explain the equivalent:

const fauxNode = {
  recursiveDispatchEvents: function recursiveDispatch(node, eventType) {
    var event = node.ownerDocument.createEvent("MutationEvents");
                            true,  /* canBubble */
                            false, /* canCancel */
                            null,  /* relatedNode */
                            null,  /* previousValue */
                            null,  /* newValue */
                            null,  /* attrNameArg */
                            0);    /* attrChangeArg */
    for each (var child in node.childNodes)
      this.recursiveDispatchEvents(child, eventType);

  checkDocumentEventReq: function checkDocumentEventReq(eventType) {
    var node = this;
    while (node) {
      if (node.hasMutationListeners(eventType)) {
        this.recursiveDispatchEvents(this, eventType);
      node = node.parentNode();
    var window = this.ownerDocument.defaultView;
    if (window.hasMutationListeners(eventType)) {
      this.recursiveDispatchEvents(this, eventType);

    /* If we got this far, then we need to check descendants. */
    var filter = {
      acceptNode: function acceptNode(aNode) {
        // Skip all descendants of accepted nodes.  We've hit them already.
        if (this.acceptNode(aNode.parentNode) == NodeFilter.FILTER_ACCEPT)
          return NodeFilter.FILTER_REJECT;

        if (aNode.hasMutationListeners(eventType))
          return NodeFilter.FILTER_ACCEPT;

        return NodeFilter.FILTER_SKIP;

    var walker = document.createTreeWalker(this, NodeFilter.SHOW_ALL, filter, true);
    while (walker.nextNode())
      this.recursiveDispatchEvents(walker.currentNode, eventType);

    walker = null;

Question marks:

* Attributes.  Since they don't have parent nodes, and since there's a
DOMAttrModified event for their removal, arguably they don't belong.  (We
haven't fired DOMNodeRemoved / DOMNodeInserted events for attributes being added
or removed.)

* Anonymous content.  Two questions.  (1) If the node being added or removed is
anonymous, do we retarget, and if so, how?  (2) If a node qualified for
receiving the document insertion/removal event, do its anonymous descendants
also qualify?

* Framed content (contentDocument and its descendants).  Same two questions.

Boris, would you like to weigh in?  This is something you always have an opinion
on.  :)
Comment 6 Alex Vincent [:WeirdAl] 2005-09-02 21:19:34 PDT
*** Bug 74220 has been marked as a duplicate of this bug. ***
Comment 7 Alex Vincent [:WeirdAl] 2005-09-02 21:28:01 PDT
Incidentally, you could performance-test event dispatch with the following:

function mutEvt(evt) {
  dump("Mutation event detected!\n");
document.addEventListener("DOMNodeInsertedIntoDocument", mutEvt, true);
document.addEventListener("DOMNodeInsertedIntoDocument", mutEvt, false);
document.addEventListener("DOMNodeRemovedFromDocument", mutEvt, true);
document.addEventListener("DOMNodeRemovedFromDocument", mutEvt, false);

That would really blitz the event listener code.
Comment 8 Boris Zbarsky [:bz] 2005-09-02 21:39:02 PDT
Frankly, these events are very low-priority for me...
Comment 9 Olli Pettay [:smaug] 2005-09-03 00:52:22 PDT
(In reply to comment #5)
> * Anonymous content.  Two questions.  (1) If the node being added or removed
> is anonymous, do we retarget, and if so, how? 

Isn't the following doing the right thing for you:
Comment 10 Erik Arvidsson 2005-09-04 03:18:34 PDT
Created attachment 194814 [details]
Test case

Slightly modified test case.
Comment 11 Boris Zbarsky [:bz] 2005-09-05 21:17:18 PDT
> * Attributes.  Since they don't have parent nodes, and since there's a
> DOMAttrModified event for their removal

Yeah, these events should not fire for Attr nodes.

> * Anonymous content.
> * Framed content

This should Just Work.  That is, these events are no different from other DOM
Comment 12 Olli Pettay [:smaug] 2007-02-20 05:28:01 PST
Alex, are you going to work on this? If not, maybe this could be
assigned to default assignee? (I may take this at some point.)
Comment 13 pmbmo1 2009-03-10 10:55:41 PDT
This bug seems pretty old, is it still not fixed? that is, are DOMNodeInsertedIntoDocument events still not working? -- no offense but on IRC I could not get a real answer (i.e., either confirmation that these events don't work nor a working example)
Comment 14 Boris Zbarsky [:bz] 2009-03-10 11:17:25 PDT
These events are not fired, correct.
Comment 15 Andreas Madsen 2010-12-19 04:03:47 PST
Can someone tell me the status of this bug.
Comment 16 Olli Pettay [:smaug] 2010-12-19 07:37:29 PST
Mutation Events are deprecated in W3C DOM 3 Events.
An alternative way to detect mutations in DOM will be provided way before
removing support for the currently supported mutation events.
But this bug is, as far as I see, WONTFIX.
Comment 17 Andreas Madsen 2010-12-19 07:52:21 PST
Thank you so much for the information.
But i think it is sad that the event is deprecated, when there isn’t an alternative. It looks like i need to extend the appendChild and the insertBefore metodes i order to detect when a node is inserted into the document.
Comment 18 Olli Pettay [:smaug] 2010-12-19 07:59:33 PST
Well, couldn't you just use DOMNodeInserted and DOMNodeRemoved?
Comment 19 Andreas Madsen 2010-12-19 08:05:17 PST
Yes I could do that, I will need to add some extra code but it won’t be a problem.
Thank you, again.
Comment 20 :Ms2ger 2012-06-22 05:47:44 PDT
Yep, this is wontfix.

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