<!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>[189271] trunk</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/189271">189271</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2015-09-02 20:08:13 -0700 (Wed, 02 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>MutationObserver should accept attributeFilter, attributeOldValue, and characterDataOldValue on their own
https://bugs.webkit.org/show_bug.cgi?id=148716

Reviewed by Chris Dumez.

Source/WebCore:

According to DOM4 [1], MutationObserver accepts characterDataOldValue, attributeOldValue and attributeFilter options
on their own when characterData and attributes options are omitted. It throws only when characterData and attributes
options are explicitly set to false.

Fixed our implementation accordingly. Existing tests as well as ones imported from W3C covers this.

[1] http://www.w3.org/TR/2015/WD-dom-20150618/#interface-mutationobserver

* dom/MutationObserver.cpp:
(WebCore::MutationObserver::observe):

LayoutTests:

Updated the expected results.

Also added test cases to make sure explicitly setting attributes and characterData options to false along
with attributeOldValue, attributeFilter, and characterDataOldValue would throw.

* fast/dom/MutationObserver/observe-exceptions-expected.txt:
* fast/dom/MutationObserver/observe-exceptions.html:
* http/tests/w3c/dom/nodes/MutationObserver-attributes-expected.txt:
* http/tests/w3c/dom/nodes/MutationObserver-characterData-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastdomMutationObserverobserveexceptionsexpectedtxt">trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastdomMutationObserverobserveexceptionshtml">trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions.html</a></li>
<li><a href="#trunkLayoutTestshttptestsw3cdomnodesMutationObserverattributesexpectedtxt">trunk/LayoutTests/http/tests/w3c/dom/nodes/MutationObserver-attributes-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsw3cdomnodesMutationObservercharacterDataexpectedtxt">trunk/LayoutTests/http/tests/w3c/dom/nodes/MutationObserver-characterData-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomMutationObservercpp">trunk/Source/WebCore/dom/MutationObserver.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (189270 => 189271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-09-03 02:58:14 UTC (rev 189270)
+++ trunk/LayoutTests/ChangeLog        2015-09-03 03:08:13 UTC (rev 189271)
</span><span class="lines">@@ -1,5 +1,22 @@
</span><span class="cx"> 2015-09-02  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><ins>+        MutationObserver should accept attributeFilter, attributeOldValue, and characterDataOldValue on their own
+        https://bugs.webkit.org/show_bug.cgi?id=148716
+
+        Reviewed by Chris Dumez.
+
+        Updated the expected results.
+
+        Also added test cases to make sure explicitly setting attributes and characterData options to false along
+        with attributeOldValue, attributeFilter, and characterDataOldValue would throw.
+
+        * fast/dom/MutationObserver/observe-exceptions-expected.txt:
+        * fast/dom/MutationObserver/observe-exceptions.html:
+        * http/tests/w3c/dom/nodes/MutationObserver-attributes-expected.txt:
+        * http/tests/w3c/dom/nodes/MutationObserver-characterData-expected.txt:
+
+2015-09-02  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
</ins><span class="cx">         Node.textContent = undefined should be equivalent to textContent = &quot;&quot;
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=148729
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsfastdomMutationObserverobserveexceptionsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions-expected.txt (189270 => 189271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions-expected.txt        2015-09-03 02:58:14 UTC (rev 189270)
+++ trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions-expected.txt        2015-09-03 03:08:13 UTC (rev 189271)
</span><span class="lines">@@ -12,9 +12,12 @@
</span><span class="cx"> PASS observer.observe(null, {attributes: true}) threw exception Error: NotFoundError: DOM Exception 8.
</span><span class="cx"> PASS observer.observe(undefined, {attributes: true}) threw exception Error: NotFoundError: DOM Exception 8.
</span><span class="cx"> PASS observer.observe(document.body, {subtree: true}) threw exception Error: SyntaxError: DOM Exception 12.
</span><del>-PASS observer.observe(document.body, {childList: true, attributeOldValue: true}) threw exception Error: SyntaxError: DOM Exception 12.
-PASS observer.observe(document.body, {attributes: true, characterDataOldValue: true}) threw exception Error: SyntaxError: DOM Exception 12.
-PASS observer.observe(document.body, {characterData: true, attributeFilter: [&quot;id&quot;]}) threw exception Error: SyntaxError: DOM Exception 12.
</del><ins>+PASS observer.observe(document.body, {childList: true, attributeOldValue: true}) did not throw exception.
+PASS observer.observe(document.body, {attributes: true, characterDataOldValue: true}) did not throw exception.
+PASS observer.observe(document.body, {characterData: true, attributeFilter: [&quot;id&quot;]}) did not throw exception.
+PASS observer.observe(document.body, {attributes: false, attributeOldValue: true}) threw exception Error: SyntaxError: DOM Exception 12.
+PASS observer.observe(document.body, {attributes: false, attributeFilter: [&quot;id&quot;]}) threw exception Error: SyntaxError: DOM Exception 12.
+PASS observer.observe(document.body, {characterData: false, characterDataOldValue: true}) threw exception Error: SyntaxError: DOM Exception 12.
</ins><span class="cx"> PASS successfullyParsed is true
</span><span class="cx"> 
</span><span class="cx"> TEST COMPLETE
</span></span></pre></div>
<a id="trunkLayoutTestsfastdomMutationObserverobserveexceptionshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions.html (189270 => 189271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions.html        2015-09-03 02:58:14 UTC (rev 189270)
+++ trunk/LayoutTests/fast/dom/MutationObserver/observe-exceptions.html        2015-09-03 03:08:13 UTC (rev 189271)
</span><span class="lines">@@ -21,9 +21,13 @@
</span><span class="cx">     shouldThrow('observer.observe(null, {attributes: true})');
</span><span class="cx">     shouldThrow('observer.observe(undefined, {attributes: true})');
</span><span class="cx">     shouldThrow('observer.observe(document.body, {subtree: true})');
</span><del>-    shouldThrow('observer.observe(document.body, {childList: true, attributeOldValue: true})');
-    shouldThrow('observer.observe(document.body, {attributes: true, characterDataOldValue: true})');
-    shouldThrow('observer.observe(document.body, {characterData: true, attributeFilter: [&quot;id&quot;]})');
</del><ins>+    shouldNotThrow('observer.observe(document.body, {childList: true, attributeOldValue: true})');
+    shouldNotThrow('observer.observe(document.body, {attributes: true, characterDataOldValue: true})');
+    shouldNotThrow('observer.observe(document.body, {characterData: true, attributeFilter: [&quot;id&quot;]})');
+
+    shouldThrow('observer.observe(document.body, {attributes: false, attributeOldValue: true})');
+    shouldThrow('observer.observe(document.body, {attributes: false, attributeFilter: [&quot;id&quot;]})');
+    shouldThrow('observer.observe(document.body, {characterData: false, characterDataOldValue: true})');
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> description('Test that WebKitMutationObserver.observe throws exceptions appropriately');
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsw3cdomnodesMutationObserverattributesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/w3c/dom/nodes/MutationObserver-attributes-expected.txt (189270 => 189271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/w3c/dom/nodes/MutationObserver-attributes-expected.txt        2015-09-03 02:58:14 UTC (rev 189270)
+++ trunk/LayoutTests/http/tests/w3c/dom/nodes/MutationObserver-attributes-expected.txt        2015-09-03 03:08:13 UTC (rev 189271)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> PASS attributes Element.removeAttributeNS: prefixed attribute removal no mutation 
</span><span class="cx"> PASS attributes/attributeFilter Element.id/Element.className: update mutation 
</span><span class="cx"> PASS attributes/attributeFilter Element.id/Element.className: multiple filter update mutation 
</span><del>-FAIL attributeOldValue alone Element.id: update mutation SyntaxError: DOM Exception 12
-FAIL attributeFilter alone Element.id/Element.className: multiple filter update mutation SyntaxError: DOM Exception 12
</del><ins>+PASS attributeOldValue alone Element.id: update mutation 
+PASS attributeFilter alone Element.id/Element.className: multiple filter update mutation 
</ins><span class="cx"> PASS childList false: no childList mutation 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsw3cdomnodesMutationObservercharacterDataexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/w3c/dom/nodes/MutationObserver-characterData-expected.txt (189270 => 189271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/w3c/dom/nodes/MutationObserver-characterData-expected.txt        2015-09-03 02:58:14 UTC (rev 189270)
+++ trunk/LayoutTests/http/tests/w3c/dom/nodes/MutationObserver-characterData-expected.txt        2015-09-03 03:08:13 UTC (rev 189271)
</span><span class="lines">@@ -23,5 +23,5 @@
</span><span class="cx"> PASS characterData Range.extractContents: child and data removal mutation 
</span><span class="cx"> PASS Range (r81) is created 
</span><span class="cx"> PASS characterData Range.extractContents: child and data removal mutation (2) 
</span><del>-FAIL characterData/characterDataOldValue alone Text.data: simple mutation SyntaxError: DOM Exception 12
</del><ins>+PASS characterData/characterDataOldValue alone Text.data: simple mutation 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (189270 => 189271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-09-03 02:58:14 UTC (rev 189270)
+++ trunk/Source/WebCore/ChangeLog        2015-09-03 03:08:13 UTC (rev 189271)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2015-09-02  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        MutationObserver should accept attributeFilter, attributeOldValue, and characterDataOldValue on their own
+        https://bugs.webkit.org/show_bug.cgi?id=148716
+
+        Reviewed by Chris Dumez.
+
+        According to DOM4 [1], MutationObserver accepts characterDataOldValue, attributeOldValue and attributeFilter options
+        on their own when characterData and attributes options are omitted. It throws only when characterData and attributes
+        options are explicitly set to false.
+
+        Fixed our implementation accordingly. Existing tests as well as ones imported from W3C covers this.
+
+        [1] http://www.w3.org/TR/2015/WD-dom-20150618/#interface-mutationobserver
+
+        * dom/MutationObserver.cpp:
+        (WebCore::MutationObserver::observe):
+
</ins><span class="cx"> 2015-09-02  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         ScrollbarThemes should be returned by reference.
</span></span></pre></div>
<a id="trunkSourceWebCoredomMutationObservercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/MutationObserver.cpp (189270 => 189271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/MutationObserver.cpp        2015-09-03 02:58:14 UTC (rev 189270)
+++ trunk/Source/WebCore/dom/MutationObserver.cpp        2015-09-03 03:08:13 UTC (rev 189271)
</span><span class="lines">@@ -82,15 +82,13 @@
</span><span class="cx">         MutationObserverOptions value;
</span><span class="cx">     } booleanOptions[] = {
</span><span class="cx">         { &quot;childList&quot;, ChildList },
</span><del>-        { &quot;attributes&quot;, Attributes },
-        { &quot;characterData&quot;, CharacterData },
</del><span class="cx">         { &quot;subtree&quot;, Subtree },
</span><span class="cx">         { &quot;attributeOldValue&quot;, AttributeOldValue },
</span><span class="cx">         { &quot;characterDataOldValue&quot;, CharacterDataOldValue }
</span><span class="cx">     };
</span><span class="cx">     MutationObserverOptions options = 0;
</span><ins>+    bool value = false;
</ins><span class="cx">     for (unsigned i = 0; i &lt; sizeof(booleanOptions) / sizeof(booleanOptions[0]); ++i) {
</span><del>-        bool value = false;
</del><span class="cx">         if (optionsDictionary.get(booleanOptions[i].name, value) &amp;&amp; value)
</span><span class="cx">             options |= booleanOptions[i].value;
</span><span class="cx">     }
</span><span class="lines">@@ -99,6 +97,14 @@
</span><span class="cx">     if (optionsDictionary.get(&quot;attributeFilter&quot;, attributeFilter))
</span><span class="cx">         options |= AttributeFilter;
</span><span class="cx"> 
</span><ins>+    bool attributesOptionIsSet = optionsDictionary.get(&quot;attributes&quot;, value);
+    if ((attributesOptionIsSet &amp;&amp; value) || (!attributesOptionIsSet &amp;&amp; (options &amp; (AttributeFilter | AttributeOldValue))))
+        options |= Attributes;
+
+    bool characterDataOptionIsSet = optionsDictionary.get(&quot;characterData&quot;, value);
+    if ((characterDataOptionIsSet &amp;&amp; value) || (!characterDataOptionIsSet &amp;&amp; (options &amp; CharacterDataOldValue)))
+        options |= CharacterData;
+
</ins><span class="cx">     if (!validateOptions(options)) {
</span><span class="cx">         ec = SYNTAX_ERR;
</span><span class="cx">         return;
</span></span></pre>
</div>
</div>

</body>
</html>