<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[180139] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/180139">180139</a></dd>
<dt>Author</dt> <dd>g.czajkowski@samsung.com</dd>
<dt>Date</dt> <dd>2015-02-16 00:25:52 -0800 (Mon, 16 Feb 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Removing text node does not remove its associated markers
https://bugs.webkit.org/show_bug.cgi?id=140999

Reviewed by Ryosuke Niwa.

Removing text node via script does not remove its markers.
For example, running the following script:

&lt;script&gt;
    var div = document.getElementById(&quot;testElement&quot;);
    div.focus();
    document.execCommand(&quot;InsertText&quot;, false, &quot;welllcome &quot;);

    // Give a time async spellchecker to show its markers and
    // remove the node.
    setTimeout(function() { div.removeChild(div.firstChild); }, 100);
&lt;/script&gt;

will cause that DocumentMarkerController still stores the markers for
detached node.

The same issue occurs when the text gets cleared, for example,
&lt;script&gt;
    input.value = &quot;&quot;; // for HTMLTextAreaElement, HTMLInputElement
    // or
    div.innerHTML = &quot;&quot;; // for content editable
&lt;/script&gt;

No new tests. Internals marker APIs operate on text node attached
to the element. To test it we could expose document().markers().hasMarkers()
but there is no more useful cases where it could be used.
Another obstacle is that we are in isInShadowTree() so that there is
no possible to register on &quot;DOMSubtreeModified&quot; event.
Test cases attached to the bug:
1. input.value = &quot;&quot;  https://bug-140999-attachments.webkit.org/attachment.cgi?id=245704
2. elem.removeChild(textNode) https://bug-140999-attachments.webkit.org/attachment.cgi?id=246515

Remove markers when text nodes are about to remove.
* dom/Document.cpp:
(WebCore::Document::nodeChildrenWillBeRemoved):
Fixes input.value = &quot;&quot;
(WebCore::Document::nodeWillBeRemoved):
Fixes elem.removeChild(textNode)</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (180138 => 180139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-02-16 06:20:51 UTC (rev 180138)
+++ trunk/Source/WebCore/ChangeLog        2015-02-16 08:25:52 UTC (rev 180139)
</span><span class="lines">@@ -1,3 +1,49 @@
</span><ins>+2015-02-13  Grzegorz Czajkowski  &lt;g.czajkowski@samsung.com&gt;
+
+        Removing text node does not remove its associated markers
+        https://bugs.webkit.org/show_bug.cgi?id=140999
+
+        Reviewed by Ryosuke Niwa.
+
+        Removing text node via script does not remove its markers.
+        For example, running the following script:
+
+        &lt;script&gt;
+            var div = document.getElementById(&quot;testElement&quot;);
+            div.focus();
+            document.execCommand(&quot;InsertText&quot;, false, &quot;welllcome &quot;);
+
+            // Give a time async spellchecker to show its markers and
+            // remove the node.
+            setTimeout(function() { div.removeChild(div.firstChild); }, 100);
+        &lt;/script&gt;
+
+        will cause that DocumentMarkerController still stores the markers for
+        detached node.
+
+        The same issue occurs when the text gets cleared, for example,
+        &lt;script&gt;
+            input.value = &quot;&quot;; // for HTMLTextAreaElement, HTMLInputElement
+            // or
+            div.innerHTML = &quot;&quot;; // for content editable
+        &lt;/script&gt;
+
+        No new tests. Internals marker APIs operate on text node attached
+        to the element. To test it we could expose document().markers().hasMarkers()
+        but there is no more useful cases where it could be used.
+        Another obstacle is that we are in isInShadowTree() so that there is
+        no possible to register on &quot;DOMSubtreeModified&quot; event.
+        Test cases attached to the bug:
+        1. input.value = &quot;&quot;  https://bug-140999-attachments.webkit.org/attachment.cgi?id=245704
+        2. elem.removeChild(textNode) https://bug-140999-attachments.webkit.org/attachment.cgi?id=246515
+
+        Remove markers when text nodes are about to remove.
+        * dom/Document.cpp:
+        (WebCore::Document::nodeChildrenWillBeRemoved):
+        Fixes input.value = &quot;&quot;
+        (WebCore::Document::nodeWillBeRemoved):
+        Fixes elem.removeChild(textNode)
+
</ins><span class="cx"> 2015-02-15  David Kilzer  &lt;ddkilzer@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION (r180082): WebCore Debug builds fail on Mavericks due to weak export symbols
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (180138 => 180139)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2015-02-16 06:20:51 UTC (rev 180138)
+++ trunk/Source/WebCore/dom/Document.cpp        2015-02-16 08:25:52 UTC (rev 180139)
</span><span class="lines">@@ -145,6 +145,7 @@
</span><span class="cx"> #include &quot;StyleResolver.h&quot;
</span><span class="cx"> #include &quot;StyleSheetContents.h&quot;
</span><span class="cx"> #include &quot;StyleSheetList.h&quot;
</span><ins>+#include &quot;TextNodeTraversal.h&quot;
</ins><span class="cx"> #include &quot;TextResourceDecoder.h&quot;
</span><span class="cx"> #include &quot;TransformSource.h&quot;
</span><span class="cx"> #include &quot;TreeWalker.h&quot;
</span><span class="lines">@@ -3684,6 +3685,11 @@
</span><span class="cx">             frame-&gt;page()-&gt;dragCaretController().nodeWillBeRemoved(*n);
</span><span class="cx">         }
</span><span class="cx">     }
</span><ins>+
+    if (m_markers-&gt;hasMarkers()) {
+        for (Text* textNode = TextNodeTraversal::firstChild(container); textNode; textNode = TextNodeTraversal::nextSibling(*textNode))
+            m_markers-&gt;removeMarkers(textNode);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Document::nodeWillBeRemoved(Node&amp; n)
</span><span class="lines">@@ -3703,6 +3709,9 @@
</span><span class="cx">         frame-&gt;selection().nodeWillBeRemoved(n);
</span><span class="cx">         frame-&gt;page()-&gt;dragCaretController().nodeWillBeRemoved(n);
</span><span class="cx">     }
</span><ins>+
+    if (is&lt;Text&gt;(n))
+        m_markers-&gt;removeMarkers(&amp;n);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Document::textInserted(Node* text, unsigned offset, unsigned length)
</span></span></pre>
</div>
</div>

</body>
</html>