Closed Bug 74219 Opened 23 years ago Closed 12 years ago

Implement NodeInsertedIntoDocument, NodeRemovedFromDocument

Categories

(Core :: DOM: Events, enhancement, P3)

enhancement

Tracking

()

RESOLVED WONTFIX
mozilla1.0.1

People

(Reporter: pbwiz, Unassigned)

References

Details

(Keywords: testcase)

Attachments

(1 file, 1 obsolete file)

NodeInsertedIntoDocument Mutation event needs implemented.

Jeff.
marking NEW.
Severity: normal → enhancement
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: other → All
Hardware: PC → All
Summary: NodeInsertedIntoDocument Mutation Event Needs Implemented → [RFE] NodeInsertedIntoDocument Mutation Event Needs Implemented
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla1.0
Target Milestone: mozilla1.0 → mozilla1.0.1
Priority: -- → P3
Summary: [RFE] NodeInsertedIntoDocument Mutation Event Needs Implemented → NodeInsertedIntoDocument Mutation Event Needs Implemented
Blocks: 149654
Attached file Test case (obsolete) —
Keywords: testcase
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.
Assignee: hyatt → ajvincent
Status: ASSIGNED → NEW
The testcase given is not comprehensive enough.  DOMNodeInsertedIntoDocument
fires once for every node removed, directly or indirectly.  If you insert the
bar element:

<bar><one/><two/></bar>

Then you must fire (after the insertion)

(no specific order to the last three)
NodeInserted @ bar
DOMNodeInsertedIntoDocument @ bar
DOMNodeInsertedIntoDocument @ one
DOMNodeInsertedIntoDocument @ two
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");
    event.initMutationEvent(eventType,
                            true,  /* canBubble */
                            false, /* canCancel */
                            null,  /* relatedNode */
                            null,  /* previousValue */
                            null,  /* newValue */
                            null,  /* attrNameArg */
                            0);    /* attrChangeArg */
    node.dispatchEvent(event);
    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);
        return;
      }
      node = node.parentNode();
    }
    var window = this.ownerDocument.defaultView;
    if (window.hasMutationListeners(eventType)) {
      this.recursiveDispatchEvents(this, eventType);
      return;
    }

    /* 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.  :)
Summary: NodeInsertedIntoDocument Mutation Event Needs Implemented → Implement NodeInsertedIntoDocument, NodeRemovedFromDocument
*** Bug 74220 has been marked as a duplicate of this bug. ***
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);
document.replaceChild(document.documentElement.cloneNode(true),
document.documentElement);

That would really blitz the event listener code.
Frankly, these events are very low-priority for me...
(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:
http://lxr.mozilla.org/seamonkey/source/content/base/src/nsGenericElement.cpp#2088
http://lxr.mozilla.org/seamonkey/source/content/base/src/nsGenericElement.cpp#2137
Attached file Test case
Slightly modified test case.
Attachment #139035 - Attachment is obsolete: true
> * 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
events.
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.)
Assignee: ajvincent → events
QA Contact: vladimire → ian
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)
These events are not fired, correct.
Assignee: events → nobody
QA Contact: ian → events
Can someone tell me the status of this bug.
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.
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.
Well, couldn't you just use DOMNodeInserted and DOMNodeRemoved?
Yes I could do that, I will need to add some extra code but it won’t be a problem.
Thank you, again.
Yep, this is wontfix.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: