<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>55666</bug_id>
          
          <creation_ts>2011-03-03 06:22:44 -0800</creation_ts>
          <short_desc>DOMNodeRemoved events are not dispatched</short_desc>
          <delta_ts>2011-03-04 07:00:08 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>DOM</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>WONTFIX</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>0</everconfirmed>
          <reporter name="Andrey Adaikin">aandrey</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>aandrey</cc>
    
    <cc>ap</cc>
    
    <cc>darin</cc>
    
    <cc>jamesr</cc>
    
    <cc>mihaip</cc>
    
    <cc>mjs</cc>
    
    <cc>ojan</cc>
    
    <cc>rniwa</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>361557</commentid>
    <comment_count>0</comment_count>
    <who name="Andrey Adaikin">aandrey</who>
    <bug_when>2011-03-03 06:22:44 -0800</bug_when>
    <thetext>DOMNodeRemoved events are not dispatched in some cases (I&apos;d even say, it is rarely dispatched).

Repro steps:
- open the attached test case
- click DEL or BACKSPACE to delete the selected text
- expected log messages from the DOMNodeRemoved event handler, but nothing happens

NOTE: This test works on Safari 5.0.3 (6533.19.4) on Mac, but not on the latest versions of Chrome.

AFAIU, this may be a good point to look into: https://bugs.webkit.org/show_bug.cgi?id=46936</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>361560</commentid>
    <comment_count>1</comment_count>
      <attachid>84552</attachid>
    <who name="Andrey Adaikin">aandrey</who>
    <bug_when>2011-03-03 06:24:07 -0800</bug_when>
    <thetext>Created attachment 84552
Test on missing DOMNodeRemoved events</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>361571</commentid>
    <comment_count>2</comment_count>
    <who name="Andrey Adaikin">aandrey</who>
    <bug_when>2011-03-03 06:31:30 -0800</bug_when>
    <thetext>Also, if you delete the line 8 in the test case, here is the output in Safari 5.0.3:

Event DOMNodeRemoved: // line #8
Event DOMNodeInserted: 
Event DOMNodeRemoved: // line #9
Event DOMNodeInserted: 
Event DOMNodeRemoved: 
Event DOMNodeRemoved: 
Event DOMNodeInserted: // line #9
Event DOMNodeRemoved: 

And in the latest Chrome 11.0.686.1:

Event DOMNodeInserted: // line #9
Event DOMNodeRemoved: // line #9
Event DOMNodeInserted: // line #9
Event DOMNodeRemoved: // line #9
Event DOMNodeInserted: // line #9
Event DOMNodeRemoved: // line #9
Event DOMNodeInserted: // line #9</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362260</commentid>
    <comment_count>3</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2011-03-03 21:34:15 -0800</bug_when>
    <thetext>This isn&apos;t a bug but rather a conscious behavior change per http://trac.webkit.org/changeset/73690.  After this changeset, WebKit fires DOMNodeRemoved AFTER the node has been removed, in which case, the event doesn&apos;t bubble to the node&apos;s ancestors because by the time we fire the event, the node had already removed from the document and therefore has no parent.

You can listen to DOMSubtreeModified to detect node removal if you want to detect descendent nodes being removed.  Please let me know if this alternative isn&apos;t adequate for your purpose and poses significant challenges.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362293</commentid>
    <comment_count>4</comment_count>
    <who name="Ojan Vafai">ojan</who>
    <bug_when>2011-03-03 22:48:05 -0800</bug_when>
    <thetext>Is there a page that breaks because of this? If not, I&apos;m tempted to WONTFIX this given that subtreemodified still works and DOMNodeRemoved still works if you add the listener to the node itself.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362316</commentid>
    <comment_count>5</comment_count>
    <who name="Andrey Adaikin">aandrey</who>
    <bug_when>2011-03-03 23:55:18 -0800</bug_when>
    <thetext>Strange, according to the http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeRemoved - &quot;This event must be dispatched before the removal takes place.&quot; Is this a wrong place to look at, or we just don&apos;t care about the standards? :)

I am more than happy to use a workaround using DOMSubtreeModified, but I failed to find one... Can you give me a good recipe how to use it, so that I should not miss DOMNodeRemoved events? If I remember correctly, I was not able to determine the particular DOM node that was removed from a subtree. Seems like there is no way now to catch the removed DOM node directly from the event?!</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362320</commentid>
    <comment_count>6</comment_count>
    <who name="Ojan Vafai">ojan</who>
    <bug_when>2011-03-04 00:05:09 -0800</bug_when>
    <thetext>(In reply to comment #5)
&gt; Strange, according to the http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeRemoved - &quot;This event must be dispatched before the removal takes place.&quot; Is this a wrong place to look at, or we just don&apos;t care about the standards? :)

This in an intentional experiment to see if we can get away with diverging from the current specification without hurting web compatibility. If we succeed, then we will encourage other browser vendors to follow suite and will try to get the standard changed.

&gt; I am more than happy to use a workaround using DOMSubtreeModified, but I failed to find one... Can you give me a good recipe how to use it, so that I should not miss DOMNodeRemoved events? If I remember correctly, I was not able to determine the particular DOM node that was removed from a subtree. Seems like there is no way now to catch the removed DOM node directly from the event?!

Correct. There&apos;s no way to get the list of nodes removed without keeping track of it yourself. Is there a web page that&apos;s not working? What are you trying to do that you need this information?

At a high-level, mutation events cause a lot of problems for browser developers without really helping web developers much. In addition, they have performance costs that web developers are rightfully unaware of. So we&apos;re seeing how much we can get away with modifying them to avoid these problems. There are a number of proposals for full replacements of mutation events, but none of them are currently being worked on.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362321</commentid>
    <comment_count>7</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2011-03-04 00:17:29 -0800</bug_when>
    <thetext>(In reply to comment #5)
&gt; Strange, according to the http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeRemoved - &quot;This event must be dispatched before the removal takes place.&quot; Is this a wrong place to look at, or we just don&apos;t care about the standards? :)

This is a willful violation of the spec.  Also note that DOM Level 3 deprecates the use of DOM mutation events entirely.

&gt; I am more than happy to use a workaround using DOMSubtreeModified, but I failed to find one... Can you give me a good recipe how to use it, so that I should not miss DOMNodeRemoved events? If I remember correctly, I was not able to determine the particular DOM node that was removed from a subtree. Seems like there is no way now to catch the removed DOM node directly from the event?!

Ah, DOMSubtreeModified might not be a good alternative.  Try attaching an event listener for DOMNodeRemoved to every child node.  Then the event will fire for each node after the node has been removed.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362323</commentid>
    <comment_count>8</comment_count>
    <who name="Andrey Adaikin">aandrey</who>
    <bug_when>2011-03-04 00:23:37 -0800</bug_when>
    <thetext>I see. I am working on the editor inside the Web Inspector: https://bugs.webkit.org/show_bug.cgi?id=53588

I already use the DOMSubtreeModified event to hack around the &quot;missing&quot; DOMNodeRemoved events, but in some corner cases it still does not work. I do not want to traverse the whole subtree every time a node is removed for obvious performance reasons. Also it may not be a good idea to listen for DOMNodeRemoved on every DOM node inside the subtree - it does not seem to be a robust solution, and, if I understand correctly, the parent node of the remove node will still be unavailable.

In other words, a DOMNodeRemoved event dispatched BEFORE the removal takes place - is exactly what I need. And now I have to invent a workaround to &quot;emulate&quot; it :)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362328</commentid>
    <comment_count>9</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2011-03-04 00:29:31 -0800</bug_when>
    <thetext>(In reply to comment #8)
&gt; I already use the DOMSubtreeModified event to hack around the &quot;missing&quot; DOMNodeRemoved events, but in some corner cases it still does not work. I do not want to traverse the whole subtree every time a node is removed for obvious performance reasons.

Why do you need to detect a node removal?

&gt;Also it may not be a good idea to listen for DOMNodeRemoved on every DOM node inside the subtree - it does not seem to be a robust solution, and, if I understand correctly, the parent node of the remove node will still be unavailable.

Yes, the parent node won&apos;t available.

&gt; In other words, a DOMNodeRemoved event dispatched BEFORE the removal takes place - is exactly what I need. And now I have to invent a workaround to &quot;emulate&quot; it :)

For what do you use DOMNodeRemoved?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362339</commentid>
    <comment_count>10</comment_count>
    <who name="Andrey Adaikin">aandrey</who>
    <bug_when>2011-03-04 00:38:56 -0800</bug_when>
    <thetext>In the contentEditable editor I listen for the DOM mutation events to find out the DOM nodes that were modified, inserted or removed by the user, so that I could update the underlying text model being edited. For the &quot;modified&quot; part I use DOMCharacterDataModified event, and for the &quot;inserted&quot; - DOMNodeInserted, and both work perfectly. The problem now is how to track the removed DOM nodes...</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362360</commentid>
    <comment_count>11</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2011-03-04 01:20:18 -0800</bug_when>
    <thetext>(In reply to comment #10)
&gt; In the contentEditable editor I listen for the DOM mutation events to find out the DOM nodes that were modified, inserted or removed by the user, so that I could update the underlying text model being edited. For the &quot;modified&quot; part I use DOMCharacterDataModified event, and for the &quot;inserted&quot; - DOMNodeInserted, and both work perfectly. The problem now is how to track the removed DOM nodes...

You can listen to DOMNodeInserted, and then add an event listener for DOMNodeRemoved on that node inside the event listener and you can also remember the parent node.  When the node is removed, DOMNodeRemoved is fired.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362366</commentid>
    <comment_count>12</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2011-03-04 01:31:52 -0800</bug_when>
    <thetext>I did some research on how IE9 handles this.  It fires DOMNodeRemoved (possibly others) on all the nodes it intends to remove before making any mutations.  It then mutates the DOM and fires the rest of mutation events asynchronously.

Mimicking this behavior in WebKit poses a challenge because editing code assumes that mutations happen in place (i.e. when we invoke a function).  One possible work-around is to simulate the entire editing command in some isolated world where we detect which node is removed, and then re-run the editing command on the actual DOM.  It&apos;s like run the command, undo it, and then redo it again where only the last redo part is visible to scripts.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362372</commentid>
    <comment_count>13</comment_count>
    <who name="Andrey Adaikin">aandrey</who>
    <bug_when>2011-03-04 01:46:47 -0800</bug_when>
    <thetext>Ryosuke, thanks for the research and your ideas!

I will try to workaround this by adding DOMNodeRemoved listeners only on direct children of the subtree I need to monitor, and traverse those children on the DOMSubtreeModified events to find the removed nodes inside those subtrees. Such combined solution seems to be acceptable for me from the performance point of view.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362401</commentid>
    <comment_count>14</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2011-03-04 03:25:29 -0800</bug_when>
    <thetext>(In reply to comment #13)
&gt; I will try to workaround this by adding DOMNodeRemoved listeners only on direct children of the subtree I need to monitor, and traverse those children on the DOMSubtreeModified events to find the removed nodes inside those subtrees. Such combined solution seems to be acceptable for me from the performance point of view.

Great! Let me know how it goes. I&apos;m very much interested in knowing if new behavior makes something impossible or there is a reasonable work-around to it.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>362473</commentid>
    <comment_count>15</comment_count>
    <who name="Andrey Adaikin">aandrey</who>
    <bug_when>2011-03-04 07:00:08 -0800</bug_when>
    <thetext>I implemented the suggested workaround (details here: https://bugs.webkit.org/show_bug.cgi?id=55769), and it seems working fine.

Marking this issue as WONTFIX.</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>84552</attachid>
            <date>2011-03-03 06:24:07 -0800</date>
            <delta_ts>2011-03-03 06:24:07 -0800</delta_ts>
            <desc>Test on missing DOMNodeRemoved events</desc>
            <filename>test.html</filename>
            <type>text/html</type>
            <size>2226</size>
            <attacher name="Andrey Adaikin">aandrey</attacher>
            
              <data encoding="base64">PGh0bWw+CjxoZWFkPgogICAgPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KICAgICAgICAjbWFpbiB7
CiAgICAgICAgICAgIC13ZWJraXQtdXNlci1tb2RpZnk6IHJlYWQtd3JpdGUtcGxhaW50ZXh0LW9u
bHk7CiAgICAgICAgfQogICAgICAgICNsb2dzIHsKICAgICAgICAgICAgd2hpdGUtc3BhY2U6IHBy
ZTsKICAgICAgICB9CiAgICA8L3N0eWxlPgo8L2hlYWQ+CgoKPGJvZHk+CjxkaXYgaWQ9Im1haW4i
PjwvZGl2Pgo8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iQ2xlYXIiIG9uY2xpY2s9ImxvZ3Mu
dGV4dENvbnRlbnQ9JyciIC8+CjxkaXYgaWQ9ImxvZ3MiPjwvZGl2PgoKPHNjcmlwdD4KICAgIHZh
ciBtYWluID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm1haW4iKTsKICAgIHZhciBsb2dzID0g
ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImxvZ3MiKTsKCiAgICB2YXIgbGluZXMgPSBbXTsKICAg
IGZvciAodmFyIGkgPSAwOyBpIDwgMTA7ICsraSkgewogICAgICAgIGxpbmVzLnB1c2goJzxkaXY+
PHNwYW4gY2xhc3M9IndlYmtpdC1qYXZhc2NyaXB0LWNvbW1lbnQiPi8vIGxpbmUgIycgKyAoaSsx
KSArICc8L3NwYW4+PC9kaXY+Jyk7CiAgICB9CiAgICBtYWluLmlubmVySFRNTCA9IGxpbmVzLmpv
aW4oJycpOwoKICAgIGZ1bmN0aW9uIGhhbmRsZUV2ZW50KGUpIHsKICAgICAgICBsb2dzLnRleHRD
b250ZW50ICs9ICJFdmVudCAiICsgZS50eXBlICsgIjogIiArIGUudGFyZ2V0LnRleHRDb250ZW50
ICsgIlxuIjsKICAgIH0KCiAgICBtYWluLmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNoYXJhY3RlckRh
dGFNb2RpZmllZCIsIGhhbmRsZUV2ZW50LCBmYWxzZSk7CiAgICBtYWluLmFkZEV2ZW50TGlzdGVu
ZXIoIkRPTU5vZGVJbnNlcnRlZCIsIGhhbmRsZUV2ZW50LCBmYWxzZSk7CiAgICBtYWluLmFkZEV2
ZW50TGlzdGVuZXIoIkRPTU5vZGVSZW1vdmVkIiwgaGFuZGxlRXZlbnQsIGZhbHNlKTsKCiAgICBm
dW5jdGlvbiBzaW11bGF0ZUtleXByZXNzKGVsbSkgewogICAgICAgIHZhciBlID0gZG9jdW1lbnQu
Y3JlYXRlRXZlbnQoIktleWJvYXJkRXZlbnQiKTsKICAgICAgICBlLmluaXRLZXlib2FyZEV2ZW50
KAogICAgICAgICAgICAgICAgImtleXByZXNzIiwgICAgICAgLy8gIGluIERPTVN0cmluZyB0eXBl
QXJnLAogICAgICAgICAgICAgICAgdHJ1ZSwgICAgICAgICAgICAgLy8gIGluIGJvb2xlYW4gY2Fu
QnViYmxlQXJnLAogICAgICAgICAgICAgICAgdHJ1ZSwgICAgICAgICAgICAgLy8gIGluIGJvb2xl
YW4gY2FuY2VsYWJsZUFyZywKICAgICAgICAgICAgICAgIG51bGwsICAgICAgICAgICAvLyAgaW4g
dmlld3M6OkFic3RyYWN0VmlldyB2aWV3QXJnLAogICAgICAgICAgICAgICAgIlUrMDAzMCIsCiAg
ICAgICAgICAgICAgICAvLyJVKzAwN0YiLCAgICAgICAgICAvLyBpbiBET01TdHJpbmcga2V5SWRl
bnRpZmllckFyZywKICAgICAgICAgICAgICAgIDAsIC8vIGluIHVuc2lnbmVkIGxvbmcga2V5TG9j
YXRpb25BcmcsCiAgICAgICAgICAgICAgICAiIiAvL2luIERPTVN0cmluZyBtb2RpZmllcnNMaXN0
CiAgICAgICAgKTsKICAgICAgICBlbG0uZGlzcGF0Y2hFdmVudChlKTsKICAgIH0KCiAgICBmdW5j
dGlvbiBzZWxlY3RUZXh0QW5kRGVsZXRlKCkgewogICAgICAgIHZhciBzZWxlY3Rpb24gPSB3aW5k
b3cuZ2V0U2VsZWN0aW9uKCk7CiAgICAgICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpOwoK
ICAgICAgICB2YXIgc3RhcnROb2RlID0gbWFpbi5maXJzdENoaWxkLm5leHRFbGVtZW50U2libGlu
Zy5uZXh0RWxlbWVudFNpYmxpbmc7CiAgICAgICAgdmFyIGVuZE5vZGUgPSBtYWluLmxhc3RDaGls
ZC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7CgogICAgICAg
IHZhciByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgcmFuZ2Uuc2V0U3Rh
cnQoc3RhcnROb2RlLmZpcnN0Q2hpbGQuZmlyc3RDaGlsZCwgc3RhcnROb2RlLnRleHRDb250ZW50
Lmxlbmd0aCk7CiAgICAgICAgcmFuZ2Uuc2V0RW5kKGVuZE5vZGUuZmlyc3RDaGlsZC5maXJzdENo
aWxkLCBlbmROb2RlLnRleHRDb250ZW50Lmxlbmd0aCk7CiAgICAgICAgc2VsZWN0aW9uLmFkZFJh
bmdlKHJhbmdlKTsKCi8vICAgICAgICBzaW11bGF0ZUtleXByZXNzKGxvZ3MpOwogICAgfQoKICAg
IHNlbGVjdFRleHRBbmREZWxldGUoKTsKCjwvc2NyaXB0PgoKPC9ib2R5Pgo8L2h0bWw+CiAgICAg
ICAg
</data>

          </attachment>
      

    </bug>

</bugzilla>