<!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>[197887] 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/197887">197887</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2016-03-09 14:29:33 -0800 (Wed, 09 Mar 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Rename Node.treeRoot to rootNode and turn it on by default
https://bugs.webkit.org/show_bug.cgi?id=155226
Reviewed by Antonio Gomes.
Source/WebCore:
Node.prototype.treeRoot has been merged into DOM spec from Shadow DOM spec and renamed to rootNode:
https://dom.spec.whatwg.org/#dom-node-rootnode
Rename the method and expose it unconditionally on Node.prototype.
Tests: fast/dom/Node/rootNode.html
fast/shadow-dom/Node-interface-rootNode.html
* dom/ContainerNode.h:
(WebCore::Node::highestAncestor): Deleted. There is no need for this function to be inlined.
* dom/Document.h: Now that both TreeScope and Node defines rootNode, we need to pick either.
Here, we pick TreeScope's definition since Document is by definition always in a document so there is
no need to even check inTreeScope().
* dom/Node.cpp:
(WebCore::Node::rootNode): Moved here. Also added a fast path for when "this" node is in a document
or a shadow root since TreeScope stores its root node as a member variable (m_rootNode).
* dom/Node.h:
* dom/Node.idl: Renamed the method and removed Conditional=SHADOW_DOM.
* dom/ShadowRoot.h: Similar to the change in Document.h. See above.
* editing/Editor.cpp:
(WebCore::correctSpellcheckingPreservingTextCheckingParagraph): Use rootNode instead of free function
defined in htmlediting.cpp, which was removed in this patch.
* editing/htmlediting.cpp:
(WebCore::highestAncestor): Deleted.
* editing/htmlediting.h:
* html/FormAssociatedElement.cpp:
(WebCore::computeRootNode): Added.
(WebCore::FormAssociatedElement::removedFrom): We can't use Node::rootNode here because this function
is called in the middle of removing a subtree, and some associated form element's inDocument flag may
not have been updated yet. So use computeRootNode to manually find the highest ancestor.
(WebCore::FormAssociatedElement::formRemovedFromTree): Ditto.
* xml/XPathPath.cpp:
(WebCore::XPath::LocationPath::evaluate):
LayoutTests:
Split Node-interface-treeRoot.html into two pieces, the one that doesn't invoke shadow DOM and the other that tests
shadow DOM related cases. I intend to upstream these tests to W3C at some point so keep them in testharness.js form.
* fast/dom/Node/rootNode-expected.txt: Added.
* fast/dom/Node/rootNode.html: Copied from LayoutTests/fast/shadow-dom/Node-interface-treeRoot.html.
* fast/shadow-dom/Node-interface-rootNode-expected.txt: Renamed from Node-interface-treeRoot-expected.txt.
* fast/shadow-dom/Node-interface-rootNode.html: Renamed from LayoutTests/fast/shadow-dom/Node-interface-treeRoot.html.
* js/dom/dom-static-property-for-in-iteration-expected.txt:
* platform/efl/js/dom/dom-static-property-for-in-iteration-expected.txt:
* platform/gtk/js/dom/dom-static-property-for-in-iteration-expected.txt:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsdomdomstaticpropertyforiniterationexpectedtxt">trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformefljsdomdomstaticpropertyforiniterationexpectedtxt">trunk/LayoutTests/platform/efl/js/dom/dom-static-property-for-in-iteration-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformgtkjsdomdomstaticpropertyforiniterationexpectedtxt">trunk/LayoutTests/platform/gtk/js/dom/dom-static-property-for-in-iteration-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomContainerNodeh">trunk/Source/WebCore/dom/ContainerNode.h</a></li>
<li><a href="#trunkSourceWebCoredomDocumenth">trunk/Source/WebCore/dom/Document.h</a></li>
<li><a href="#trunkSourceWebCoredomNodecpp">trunk/Source/WebCore/dom/Node.cpp</a></li>
<li><a href="#trunkSourceWebCoredomNodeh">trunk/Source/WebCore/dom/Node.h</a></li>
<li><a href="#trunkSourceWebCoredomNodeidl">trunk/Source/WebCore/dom/Node.idl</a></li>
<li><a href="#trunkSourceWebCoredomShadowRooth">trunk/Source/WebCore/dom/ShadowRoot.h</a></li>
<li><a href="#trunkSourceWebCoreeditingEditorcpp">trunk/Source/WebCore/editing/Editor.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditinghtmleditingcpp">trunk/Source/WebCore/editing/htmlediting.cpp</a></li>
<li><a href="#trunkSourceWebCoreeditinghtmleditingh">trunk/Source/WebCore/editing/htmlediting.h</a></li>
<li><a href="#trunkSourceWebCorehtmlFormAssociatedElementcpp">trunk/Source/WebCore/html/FormAssociatedElement.cpp</a></li>
<li><a href="#trunkSourceWebCorexmlXPathPathcpp">trunk/Source/WebCore/xml/XPathPath.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastdomNoderootNodeexpectedtxt">trunk/LayoutTests/fast/dom/Node/rootNode-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastdomNoderootNodehtml">trunk/LayoutTests/fast/dom/Node/rootNode.html</a></li>
<li><a href="#trunkLayoutTestsfastshadowdomNodeinterfacerootNodeexpectedtxt">trunk/LayoutTests/fast/shadow-dom/Node-interface-rootNode-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastshadowdomNodeinterfacerootNodehtml">trunk/LayoutTests/fast/shadow-dom/Node-interface-rootNode.html</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastshadowdomNodeinterfacetreeRootexpectedtxt">trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastshadowdomNodeinterfacetreeRoothtml">trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/LayoutTests/ChangeLog        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2016-03-09 Ryosuke Niwa <rniwa@webkit.org>
+
+ Rename Node.treeRoot to rootNode and turn it on by default
+ https://bugs.webkit.org/show_bug.cgi?id=155226
+
+ Reviewed by Antonio Gomes.
+
+ Split Node-interface-treeRoot.html into two pieces, the one that doesn't invoke shadow DOM and the other that tests
+ shadow DOM related cases. I intend to upstream these tests to W3C at some point so keep them in testharness.js form.
+
+ * fast/dom/Node/rootNode-expected.txt: Added.
+ * fast/dom/Node/rootNode.html: Copied from LayoutTests/fast/shadow-dom/Node-interface-treeRoot.html.
+ * fast/shadow-dom/Node-interface-rootNode-expected.txt: Renamed from Node-interface-treeRoot-expected.txt.
+ * fast/shadow-dom/Node-interface-rootNode.html: Renamed from LayoutTests/fast/shadow-dom/Node-interface-treeRoot.html.
+ * js/dom/dom-static-property-for-in-iteration-expected.txt:
+ * platform/efl/js/dom/dom-static-property-for-in-iteration-expected.txt:
+ * platform/gtk/js/dom/dom-static-property-for-in-iteration-expected.txt:
+
</ins><span class="cx"> 2016-03-09 Michael Saboff <msaboff@apple.com>
</span><span class="cx">
</span><span class="cx"> [ES6] Implement RegExp sticky flag and related functionality
</span></span></pre></div>
<a id="trunkLayoutTestsfastdomNoderootNodeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/dom/Node/rootNode-expected.txt (0 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/dom/Node/rootNode-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/dom/Node/rootNode-expected.txt        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+
+PASS rootNode attribute must be defined on Node interface
+PASS rootNode attribute must return the context object when it does not have any parent
+PASS rootNode attribute must return the parent node of the context object when the context object has a single ancestor not in a document
+PASS rootNode attribute must return the document when a node is in document
+PASS rootNode attribute must return a document fragment when a node is in the fragment
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastdomNoderootNodehtmlfromrev197834trunkLayoutTestsfastshadowdomNodeinterfacetreeRoothtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/fast/dom/Node/rootNode.html (from rev 197834, trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot.html) (0 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/dom/Node/rootNode.html         (rev 0)
+++ trunk/LayoutTests/fast/dom/Node/rootNode.html        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -0,0 +1,94 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<title>DOM: 4.4. Interface Node</title>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<meta name="assert" content="Node interface must have rootNode attribute">
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-node-rootnode">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<link rel='stylesheet' href='../../../resources/testharness.css'>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+test(function () {
+ assert_true('rootNode' in Node.prototype, 'rootNode must be defined on Node.prototype');
+ assert_true('rootNode' in document.createElement('div'), 'rootNode must be defined on a div element');
+ assert_true('rootNode' in document.createTextNode(''), 'rootNode must be defined on a text node');
+ assert_true('rootNode' in document.createComment(''), 'rootNode must be defined on a comment node');
+ assert_true('rootNode' in document.createProcessingInstruction('target', 'data'), 'rootNode must be defined on a processing instruction node');
+ assert_true('rootNode' in document, 'rootNode must be defined on a document node');
+}, 'rootNode attribute must be defined on Node interface');
+
+test(function () {
+ var element = document.createElement('div');
+ assert_equals(element.rootNode, element, 'rootNode on an element without a parent must return the element itself');
+
+ var text = document.createTextNode('');
+ assert_equals(text.rootNode, text, 'rootNode on a text node without a parent must return the text node itself');
+
+ var processingInstruction = document.createProcessingInstruction('target', 'data');
+ assert_equals(processingInstruction.rootNode, processingInstruction, 'rootNode on a processing instruction node without a parent must return the processing instruction node itself');
+
+ assert_equals(document.rootNode, document, 'rootNode on a document node must return the document itself');
+
+}, 'rootNode attribute must return the context object when it does not have any parent');
+
+test(function () {
+ var parent = document.createElement('div');
+
+ var element = document.createElement('div');
+ parent.appendChild(element);
+ assert_equals(element.rootNode, parent, 'rootNode on an element with a single ancestor must return the parent node');
+
+ var text = document.createTextNode('');
+ parent.appendChild(text);
+ assert_equals(text.rootNode, parent, 'rootNode on a text node with a single ancestor must return the parent node');
+
+ var processingInstruction = document.createProcessingInstruction('target', 'data');
+ parent.appendChild(processingInstruction)
+ assert_equals(processingInstruction.rootNode, parent, 'rootNode on a processing instruction node with a single ancestor must return the parent node');
+
+}, 'rootNode attribute must return the parent node of the context object when the context object has a single ancestor not in a document');
+
+test(function () {
+ var parent = document.createElement('div');
+ document.body.appendChild(parent);
+
+ var element = document.createElement('div');
+ parent.appendChild(element);
+ assert_equals(element.rootNode, document, 'rootNode on an element inside a document must return the document');
+
+ var text = document.createTextNode('');
+ parent.appendChild(text);
+ assert_equals(text.rootNode, document, 'rootNode on a text node inside a document must return the document');
+
+ var processingInstruction = document.createProcessingInstruction('target', 'data');
+ parent.appendChild(processingInstruction)
+ assert_equals(processingInstruction.rootNode, document, 'rootNode on a processing instruction node inside a document must return the document');
+}, 'rootNode attribute must return the document when a node is in document');
+
+test(function () {
+ var fragment = document.createDocumentFragment();
+ var parent = document.createElement('div');
+ fragment.appendChild(parent);
+
+ var element = document.createElement('div');
+ parent.appendChild(element);
+ assert_equals(element.rootNode, fragment, 'rootNode on an element inside a document fragment must return the fragment');
+
+ var text = document.createTextNode('');
+ parent.appendChild(text);
+ assert_equals(text.rootNode, fragment, 'rootNode on a text node inside a document fragment must return the fragment');
+
+ var processingInstruction = document.createProcessingInstruction('target', 'data');
+ parent.appendChild(processingInstruction)
+ assert_equals(processingInstruction.rootNode, fragment,
+ 'rootNode on a processing instruction node inside a document fragment must return the fragment');
+}, 'rootNode attribute must return a document fragment when a node is in the fragment');
+
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshadowdomNodeinterfacerootNodeexpectedtxtfromrev197834trunkLayoutTestsfastshadowdomNodeinterfacetreeRootexpectedtxt"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/fast/shadow-dom/Node-interface-rootNode-expected.txt (from rev 197834, trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot-expected.txt) (0 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shadow-dom/Node-interface-rootNode-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/Node-interface-rootNode-expected.txt        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+
+PASS rootNode attribute must be defined on ShadowRoot interface
+PASS rootNode attribute must return the context object when it does not have any parent
+PASS rootNode attribute must return the parent node of the context object when the context object has a single ancestor not in a document
+PASS rootNode attribute must return the document when a node is in document and not in a shadow tree
+PASS rootNode attribute must return the open shadow root of the context object when the shadow host is in a document
+PASS rootNode attribute must return the closed shadow root of the context object when the shadow host is in a document
+PASS rootNode attribute must return the root node of the context object when the context object is inside a open shadow root whose shadow host is in another open shadow root
+PASS rootNode attribute must return the root node of the context object when the context object is inside a closed shadow root whose shadow host is in another open shadow root
+PASS rootNode attribute must return the root node of the context object when the context object is inside a open shadow root whose shadow host is in another closed shadow root
+PASS rootNode attribute must return the root node of the context object when the context object is inside a closed shadow root whose shadow host is in another closed shadow root
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshadowdomNodeinterfacerootNodehtmlfromrev197834trunkLayoutTestsfastshadowdomNodeinterfacetreeRoothtml"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/fast/shadow-dom/Node-interface-rootNode.html (from rev 197834, trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot.html) (0 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shadow-dom/Node-interface-rootNode.html         (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/Node-interface-rootNode.html        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -0,0 +1,121 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<title>Shadow DOM: Extensions to Node interface</title>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<meta name="assert" content="Node interface must have rootNode attribute">
+<link rel="help" href="http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-node-interface">
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<link rel='stylesheet' href='../../resources/testharness.css'>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+test(function () {
+ assert_true('rootNode' in document.createElement('div').attachShadow({mode: 'closed'}), 'rootNode must be defined on a closed shadow root element');
+ assert_true('rootNode' in document.createElement('div').attachShadow({mode: 'open'}), 'rootNode must be defined on a open shadow root element');
+}, 'rootNode attribute must be defined on ShadowRoot interface');
+
+test(function () {
+ var closedShadowRoot = document.createElement('div').attachShadow({mode: 'closed'});
+ assert_equals(closedShadowRoot.rootNode, closedShadowRoot, 'rootNode on a closed shadow root must return the shadow root itself');
+
+ var openShadowRoot = document.createElement('div').attachShadow({mode: 'open'});
+ assert_equals(openShadowRoot.rootNode, openShadowRoot, 'rootNode on a open shadow root must return the shadow root itself');
+}, 'rootNode attribute must return the context object when it does not have any parent');
+
+test(function () {
+ var parent = document.createElement('div');
+
+ var hostWithClosedShadowRoot = document.createElement('div');
+ parent.appendChild(hostWithClosedShadowRoot);
+ var closedShadowRoot = hostWithClosedShadowRoot.attachShadow({mode: 'closed'});
+ assert_equals(closedShadowRoot.rootNode, closedShadowRoot, 'rootNode on a closed shadow root with a single ancestor on its host must return the shadow root itself');
+
+ var hostWithOpenShadowRoot = document.createElement('div');
+ parent.appendChild(hostWithOpenShadowRoot);
+ var openShadowRoot = hostWithOpenShadowRoot.attachShadow({mode: 'open'});
+ assert_equals(openShadowRoot.rootNode, openShadowRoot, 'rootNode on a open shadow root with a single ancestor on its host must return the shadow root itself');
+}, 'rootNode attribute must return the parent node of the context object when the context object has a single ancestor not in a document');
+
+test(function () {
+ var parent = document.createElement('div');
+ document.body.appendChild(parent);
+
+ var element = document.createElement('div');
+ parent.appendChild(element);
+ assert_equals(element.rootNode, document, 'rootNode on an element inside a document must return the document');
+
+ var text = document.createTextNode('');
+ parent.appendChild(text);
+ assert_equals(text.rootNode, document, 'rootNode on a text node inside a document must return the document');
+
+ var processingInstruction = document.createProcessingInstruction('target', 'data');
+ parent.appendChild(processingInstruction)
+ assert_equals(processingInstruction.rootNode, document, 'rootNode on a processing instruction node inside a document must return the document');
+}, 'rootNode attribute must return the document when a node is in document and not in a shadow tree');
+
+function testrootNodeOnNodeInsideShadowTree(mode) {
+ test(function () {
+ var host = document.createElement('div');
+ document.body.appendChild(host);
+
+ var shadowRoot = host.attachShadow({mode: mode});
+ var parent = document.createElement('p');
+ shadowRoot.appendChild(parent);
+
+ var element = document.createElement('span');
+ parent.appendChild(element);
+ assert_equals(element.rootNode, shadowRoot, 'rootNode on an element inside a shadow tree must return the shadow root');
+
+ var text = document.createTextNode('');
+ parent.appendChild(text);
+ assert_equals(text.rootNode, shadowRoot, 'rootNode on a text node inside a shadow tree must return the shadow root');
+
+ var processingInstruction = document.createProcessingInstruction('target', 'data');
+ parent.appendChild(processingInstruction);
+ assert_equals(processingInstruction.rootNode, shadowRoot, 'rootNode on a processing instruction node inside a shadow tree must return the shadow root');
+ }, 'rootNode attribute must return the ' + mode + ' shadow root of the context object when the shadow host is in a document');
+}
+
+testrootNodeOnNodeInsideShadowTree('open');
+testrootNodeOnNodeInsideShadowTree('closed');
+
+function testrootNodeOnNodeInsideNestedShadowTree(outerMode, innerMode) {
+ test(function () {
+ var outerHost = document.createElement('div');
+ document.body.appendChild(outerHost);
+ var outerShadowRoot = outerHost.attachShadow({mode: outerMode});
+
+ var innerHost = document.createElement('section');
+ outerShadowRoot.appendChild(innerHost);
+ var innerShadowRoot = innerHost.attachShadow({mode: innerMode});
+
+ var parent = document.createElement('p');
+ innerShadowRoot.appendChild(parent);
+
+ var element = document.createElement('span');
+ parent.appendChild(element);
+ assert_equals(element.rootNode, innerShadowRoot, 'rootNode on an element inside a shadow tree must return its root node');
+
+ var text = document.createTextNode('');
+ parent.appendChild(text);
+ assert_equals(text.rootNode, innerShadowRoot, 'rootNode on a text node inside a shadow tree must return its root node');
+
+ var processingInstruction = document.createProcessingInstruction('target', 'data');
+ parent.appendChild(processingInstruction);
+ assert_equals(processingInstruction.rootNode, innerShadowRoot, 'rootNode on a processing instruction node inside a shadow tree must return its root node');
+ }, 'rootNode attribute must return the root node of the context object when the context object is inside a ' + innerMode
+ + ' shadow root whose shadow host is in another ' + outerMode + ' shadow root');
+}
+
+testrootNodeOnNodeInsideNestedShadowTree('open', 'open');
+testrootNodeOnNodeInsideNestedShadowTree('open', 'closed');
+testrootNodeOnNodeInsideNestedShadowTree('closed', 'open');
+testrootNodeOnNodeInsideNestedShadowTree('closed', 'closed');
+
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshadowdomNodeinterfacetreeRootexpectedtxt"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot-expected.txt (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot-expected.txt        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot-expected.txt        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -1,12 +0,0 @@
</span><del>-
-PASS treeRoot attribute must be defined on Node interface
-PASS treeRoot attribute must return the context object when it does not have any parent
-PASS treeRoot attribute must return the parent node of the context object when the context object has a single ancestor not in a document
-PASS treeRoot attribute must return the document when a node is in document and not in a shadow tree
-PASS treeRoot attribute must return the open shadow root of the context object when the shadow host is in a document
-PASS treeRoot attribute must return the closed shadow root of the context object when the shadow host is in a document
-PASS treeRoot attribute must return the root node of the context object when the context object is inside a open shadow root whose shadow host is in another open shadow root
-PASS treeRoot attribute must return the root node of the context object when the context object is inside a closed shadow root whose shadow host is in another open shadow root
-PASS treeRoot attribute must return the root node of the context object when the context object is inside a open shadow root whose shadow host is in another closed shadow root
-PASS treeRoot attribute must return the root node of the context object when the context object is inside a closed shadow root whose shadow host is in another closed shadow root
-
</del></span></pre></div>
<a id="trunkLayoutTestsfastshadowdomNodeinterfacetreeRoothtml"></a>
<div class="delfile"><h4>Deleted: trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot.html (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot.html        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/LayoutTests/fast/shadow-dom/Node-interface-treeRoot.html        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -1,150 +0,0 @@
</span><del>-<!DOCTYPE html>
-<html>
-<head>
-<title>Shadow DOM: Extensions to Node interface</title>
-<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
-<meta name="assert" content="Node interface must have treeRoot attribute">
-<link rel="help" href="http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-node-interface">
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<link rel='stylesheet' href='../../resources/testharness.css'>
-</head>
-<body>
-<div id="log"></div>
-<script>
-
-test(function () {
- assert_true('treeRoot' in Node.prototype, 'treeRoot must be defined on Node.prototype');
- assert_true('treeRoot' in document.createElement('div'), 'treeRoot must be defined on a div element');
- assert_true('treeRoot' in document.createTextNode(''), 'assignedSlot must be defined on a text node');
- assert_true('treeRoot' in document.createComment(''), 'assignedSlot must be defined on a comment node');
- assert_true('treeRoot' in document.createProcessingInstruction('target', 'data'), 'assignedSlot must be defined on a processing instruction node');
- assert_true('treeRoot' in document, 'assignedSlot must be defined on a document node');
- assert_true('treeRoot' in document.createElement('div').attachShadow({mode: 'closed'}), 'treeRoot must be defined on a closed shadow root element');
- assert_true('treeRoot' in document.createElement('div').attachShadow({mode: 'open'}), 'treeRoot must be defined on a open shadow root element');
-}, 'treeRoot attribute must be defined on Node interface');
-
-test(function () {
- var element = document.createElement('div');
- assert_equals(element.treeRoot, element, 'treeRoot on an element without a parent must return the element itself');
-
- var text = document.createTextNode('');
- assert_equals(text.treeRoot, text, 'treeRoot on a text node without a parent must return the text node itself');
-
- var processingInstruction = document.createProcessingInstruction('target', 'data');
- assert_equals(processingInstruction.treeRoot, processingInstruction, 'treeRoot on a processing instruction node without a parent must return the processing instruction node itself');
-
- assert_equals(document.treeRoot, document, 'treeRoot on a document node must return the document itself');
-
- var closedShadowRoot = document.createElement('div').attachShadow({mode: 'closed'});
- assert_equals(closedShadowRoot.treeRoot, closedShadowRoot, 'treeRoot on a closed shadow root must return the shadow root itself');
-
- var openShadowRoot = document.createElement('div').attachShadow({mode: 'open'});
- assert_equals(openShadowRoot.treeRoot, openShadowRoot, 'treeRoot on a open shadow root must return the shadow root itself');
-}, 'treeRoot attribute must return the context object when it does not have any parent');
-
-test(function () {
- var parent = document.createElement('div');
-
- var element = document.createElement('div');
- parent.appendChild(element);
- assert_equals(element.treeRoot, parent, 'treeRoot on an element with a single ancestor must return the parent node');
-
- var text = document.createTextNode('');
- parent.appendChild(text);
- assert_equals(text.treeRoot, parent, 'treeRoot on a text node with a single ancestor must return the parent node');
-
- var processingInstruction = document.createProcessingInstruction('target', 'data');
- parent.appendChild(processingInstruction)
- assert_equals(processingInstruction.treeRoot, parent, 'treeRoot on a processing instruction node with a single ancestor must return the parent node');
-
- var hostWithClosedShadowRoot = document.createElement('div');
- parent.appendChild(hostWithClosedShadowRoot);
- var closedShadowRoot = hostWithClosedShadowRoot.attachShadow({mode: 'closed'});
- assert_equals(closedShadowRoot.treeRoot, closedShadowRoot, 'treeRoot on a closed shadow root with a single ancestor on its host must return the shadow root itself');
-
- var hostWithOpenShadowRoot = document.createElement('div');
- parent.appendChild(hostWithOpenShadowRoot);
- var openShadowRoot = hostWithOpenShadowRoot.attachShadow({mode: 'open'});
- assert_equals(openShadowRoot.treeRoot, openShadowRoot, 'treeRoot on a open shadow root with a single ancestor on its host must return the shadow root itself');
-}, 'treeRoot attribute must return the parent node of the context object when the context object has a single ancestor not in a document');
-
-test(function () {
- var parent = document.createElement('div');
- document.body.appendChild(parent);
-
- var element = document.createElement('div');
- parent.appendChild(element);
- assert_equals(element.treeRoot, document, 'treeRoot on an element inside a document must return the document');
-
- var text = document.createTextNode('');
- parent.appendChild(text);
- assert_equals(text.treeRoot, document, 'treeRoot on a text node inside a document must return the document');
-
- var processingInstruction = document.createProcessingInstruction('target', 'data');
- parent.appendChild(processingInstruction)
- assert_equals(processingInstruction.treeRoot, document, 'treeRoot on a processing instruction node inside a document must return the document');
-}, 'treeRoot attribute must return the document when a node is in document and not in a shadow tree');
-
-function testTreeRootOnNodeInsideShadowTree(mode) {
- test(function () {
- var host = document.createElement('div');
- document.body.appendChild(host);
-
- var shadowRoot = host.attachShadow({mode: mode});
- var parent = document.createElement('p');
- shadowRoot.appendChild(parent);
-
- var element = document.createElement('span');
- parent.appendChild(element);
- assert_equals(element.treeRoot, shadowRoot, 'treeRoot on an element inside a shadow tree must return the shadow root');
-
- var text = document.createTextNode('');
- parent.appendChild(text);
- assert_equals(text.treeRoot, shadowRoot, 'treeRoot on a text node inside a shadow tree must return the shadow root');
-
- var processingInstruction = document.createProcessingInstruction('target', 'data');
- parent.appendChild(processingInstruction);
- assert_equals(processingInstruction.treeRoot, shadowRoot, 'treeRoot on a processing instruction node inside a shadow tree must return the shadow root');
- }, 'treeRoot attribute must return the ' + mode + ' shadow root of the context object when the shadow host is in a document');
-}
-
-testTreeRootOnNodeInsideShadowTree('open');
-testTreeRootOnNodeInsideShadowTree('closed');
-
-function testTreeRootOnNodeInsideNestedShadowTree(outerMode, innerMode) {
- test(function () {
- var outerHost = document.createElement('div');
- document.body.appendChild(outerHost);
- var outerShadowRoot = outerHost.attachShadow({mode: outerMode});
-
- var innerHost = document.createElement('section');
- outerShadowRoot.appendChild(innerHost);
- var innerShadowRoot = innerHost.attachShadow({mode: innerMode});
-
- var parent = document.createElement('p');
- innerShadowRoot.appendChild(parent);
-
- var element = document.createElement('span');
- parent.appendChild(element);
- assert_equals(element.treeRoot, innerShadowRoot, 'treeRoot on an element inside a shadow tree must return its root node');
-
- var text = document.createTextNode('');
- parent.appendChild(text);
- assert_equals(text.treeRoot, innerShadowRoot, 'treeRoot on a text node inside a shadow tree must return its root node');
-
- var processingInstruction = document.createProcessingInstruction('target', 'data');
- parent.appendChild(processingInstruction);
- assert_equals(processingInstruction.treeRoot, innerShadowRoot, 'treeRoot on a processing instruction node inside a shadow tree must return its root node');
- }, 'treeRoot attribute must return the root node of the context object when the context object is inside a ' + innerMode
- + ' shadow root whose shadow host is in another ' + outerMode + ' shadow root');
-}
-
-testTreeRootOnNodeInsideNestedShadowTree('open', 'open');
-testTreeRootOnNodeInsideNestedShadowTree('open', 'closed');
-testTreeRootOnNodeInsideNestedShadowTree('closed', 'open');
-testTreeRootOnNodeInsideNestedShadowTree('closed', 'closed');
-
-</script>
-</body>
-</html>
</del></span></pre></div>
<a id="trunkLayoutTestsjsdomdomstaticpropertyforiniterationexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -142,7 +142,7 @@
</span><span class="cx"> PASS a["previousSibling"] is [object Text]
</span><span class="cx"> PASS a["nextSibling"] is [object Text]
</span><span class="cx"> PASS a["ownerDocument"] is [object HTMLDocument]
</span><del>-PASS a["treeRoot"] is [object HTMLDocument]
</del><ins>+PASS a["rootNode"] is [object HTMLDocument]
</ins><span class="cx"> PASS a["namespaceURI"] is http://www.w3.org/1999/xhtml
</span><span class="cx"> PASS a["prefix"] is null
</span><span class="cx"> PASS a["localName"] is a
</span></span></pre></div>
<a id="trunkLayoutTestsplatformefljsdomdomstaticpropertyforiniterationexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/efl/js/dom/dom-static-property-for-in-iteration-expected.txt (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/efl/js/dom/dom-static-property-for-in-iteration-expected.txt        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/LayoutTests/platform/efl/js/dom/dom-static-property-for-in-iteration-expected.txt        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -77,6 +77,7 @@
</span><span class="cx"> PASS a["childNodes"] is [object NodeList]
</span><span class="cx"> PASS a["nextSibling"] is [object Text]
</span><span class="cx"> PASS a["ownerDocument"] is [object HTMLDocument]
</span><ins>+PASS a["rootNode"] is [object HTMLDocument]
</ins><span class="cx"> PASS a["namespaceURI"] is http://www.w3.org/1999/xhtml
</span><span class="cx"> PASS a["localName"] is a
</span><span class="cx"> PASS a["parentElement"] is [object HTMLBodyElement]
</span></span></pre></div>
<a id="trunkLayoutTestsplatformgtkjsdomdomstaticpropertyforiniterationexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/gtk/js/dom/dom-static-property-for-in-iteration-expected.txt (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/gtk/js/dom/dom-static-property-for-in-iteration-expected.txt        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/LayoutTests/platform/gtk/js/dom/dom-static-property-for-in-iteration-expected.txt        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -81,6 +81,7 @@
</span><span class="cx"> PASS a["previousSibling"] is [object Text]
</span><span class="cx"> PASS a["nextSibling"] is [object Text]
</span><span class="cx"> PASS a["ownerDocument"] is [object HTMLDocument]
</span><ins>+PASS a["rootNode"] is [object HTMLDocument]
</ins><span class="cx"> PASS a["namespaceURI"] is http://www.w3.org/1999/xhtml
</span><span class="cx"> PASS a["prefix"] is null
</span><span class="cx"> PASS a["localName"] is a
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/ChangeLog        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2016-03-09 Ryosuke Niwa <rniwa@webkit.org>
+
+ Rename Node.treeRoot to rootNode and turn it on by default
+ https://bugs.webkit.org/show_bug.cgi?id=155226
+
+ Reviewed by Antonio Gomes.
+
+ Node.prototype.treeRoot has been merged into DOM spec from Shadow DOM spec and renamed to rootNode:
+ https://dom.spec.whatwg.org/#dom-node-rootnode
+
+ Rename the method and expose it unconditionally on Node.prototype.
+
+ Tests: fast/dom/Node/rootNode.html
+ fast/shadow-dom/Node-interface-rootNode.html
+
+ * dom/ContainerNode.h:
+ (WebCore::Node::highestAncestor): Deleted. There is no need for this function to be inlined.
+ * dom/Document.h: Now that both TreeScope and Node defines rootNode, we need to pick either.
+ Here, we pick TreeScope's definition since Document is by definition always in a document so there is
+ no need to even check inTreeScope().
+ * dom/Node.cpp:
+ (WebCore::Node::rootNode): Moved here. Also added a fast path for when "this" node is in a document
+ or a shadow root since TreeScope stores its root node as a member variable (m_rootNode).
+ * dom/Node.h:
+ * dom/Node.idl: Renamed the method and removed Conditional=SHADOW_DOM.
+ * dom/ShadowRoot.h: Similar to the change in Document.h. See above.
+ * editing/Editor.cpp:
+ (WebCore::correctSpellcheckingPreservingTextCheckingParagraph): Use rootNode instead of free function
+ defined in htmlediting.cpp, which was removed in this patch.
+ * editing/htmlediting.cpp:
+ (WebCore::highestAncestor): Deleted.
+ * editing/htmlediting.h:
+ * html/FormAssociatedElement.cpp:
+ (WebCore::computeRootNode): Added.
+ (WebCore::FormAssociatedElement::removedFrom): We can't use Node::rootNode here because this function
+ is called in the middle of removing a subtree, and some associated form element's inDocument flag may
+ not have been updated yet. So use computeRootNode to manually find the highest ancestor.
+ (WebCore::FormAssociatedElement::formRemovedFromTree): Ditto.
+ * xml/XPathPath.cpp:
+ (WebCore::XPath::LocationPath::evaluate):
+
</ins><span class="cx"> 2016-03-09 Konstantin Tokarev <annulen@yandex.ru>
</span><span class="cx">
</span><span class="cx"> [cmake] Fixed All-in-One build.
</span></span></pre></div>
<a id="trunkSourceWebCoredomContainerNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ContainerNode.h (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ContainerNode.h        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/dom/ContainerNode.h        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -212,15 +212,6 @@
</span><span class="cx"> return downcast<ContainerNode>(*this).lastChild();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline Node* Node::highestAncestor() const
-{
- Node* node = const_cast<Node*>(this);
- Node* highest = node;
- for (; node; node = node->parentNode())
- highest = node;
- return highest;
-}
-
</del><span class="cx"> inline bool Node::isTreeScope() const
</span><span class="cx"> {
</span><span class="cx"> return &treeScope().rootNode() == this;
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.h (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.h        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/dom/Document.h        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -340,6 +340,7 @@
</span><span class="cx">
</span><span class="cx"> using ContainerNode::ref;
</span><span class="cx"> using ContainerNode::deref;
</span><ins>+ using TreeScope::rootNode;
</ins><span class="cx">
</span><span class="cx"> bool canContainRangeEndPoint() const final { return true; }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.cpp (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.cpp        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/dom/Node.cpp        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -1110,6 +1110,18 @@
</span><span class="cx"> return downcast<Element>(parent);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+Node* Node::rootNode() const
+{
+ if (isInTreeScope())
+ return &treeScope().rootNode();
+
+ Node* node = const_cast<Node*>(this);
+ Node* highest = node;
+ for (; node; node = node->parentNode())
+ highest = node;
+ return highest;
+}
+
</ins><span class="cx"> Node::InsertionNotificationRequest Node::insertedInto(ContainerNode& insertionPoint)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(insertionPoint.inDocument() || isContainerNode());
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.h (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.h        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/dom/Node.h        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -276,7 +276,7 @@
</span><span class="cx"> ContainerNode* parentOrShadowHostNode() const;
</span><span class="cx"> Element* parentOrShadowHostElement() const;
</span><span class="cx"> void setParentNode(ContainerNode*);
</span><del>- Node* highestAncestor() const;
</del><ins>+ Node* rootNode() const;
</ins><span class="cx">
</span><span class="cx"> // Use when it's guaranteed to that shadowHost is null.
</span><span class="cx"> ContainerNode* parentNodeGuaranteedHostFree() const;
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.idl (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.idl        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/dom/Node.idl        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx"> readonly attribute Node nextSibling;
</span><span class="cx"> readonly attribute Document ownerDocument;
</span><span class="cx">
</span><del>- [Conditional=SHADOW_DOM, ImplementedAs=highestAncestor] readonly attribute Node treeRoot;
</del><ins>+ readonly attribute Node rootNode;
</ins><span class="cx">
</span><span class="cx"> [ObjCLegacyUnnamedParameters, Custom, RaisesException] Node insertBefore([CustomReturn] Node newChild,
</span><span class="cx"> Node refChild);
</span></span></pre></div>
<a id="trunkSourceWebCoredomShadowRooth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ShadowRoot.h (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ShadowRoot.h        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/dom/ShadowRoot.h        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -62,6 +62,8 @@
</span><span class="cx">
</span><span class="cx"> virtual ~ShadowRoot();
</span><span class="cx">
</span><ins>+ using TreeScope::rootNode;
+
</ins><span class="cx"> StyleResolver& styleResolver();
</span><span class="cx"> AuthorStyleSheets& authorStyleSheets();
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingEditorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/Editor.cpp (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/Editor.cpp        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/editing/Editor.cpp        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -2427,7 +2427,7 @@
</span><span class="cx">
</span><span class="cx"> static void correctSpellcheckingPreservingTextCheckingParagraph(TextCheckingParagraph& paragraph, PassRefPtr<Range> rangeToReplace, const String& replacement, int resultLocation, int resultLength)
</span><span class="cx"> {
</span><del>- ContainerNode* scope = downcast<ContainerNode>(highestAncestor(&paragraph.paragraphRange()->startContainer()));
</del><ins>+ ContainerNode* scope = downcast<ContainerNode>(paragraph.paragraphRange()->startContainer().rootNode());
</ins><span class="cx">
</span><span class="cx"> size_t paragraphLocation;
</span><span class="cx"> size_t paragraphLength;
</span></span></pre></div>
<a id="trunkSourceWebCoreeditinghtmleditingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/htmlediting.cpp (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/htmlediting.cpp        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/editing/htmlediting.cpp        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -795,15 +795,6 @@
</span><span class="cx"> // Make sure there is no visible content between this li and the previous list
</span><span class="cx"> }
</span><span class="cx">
</span><del>-Node* highestAncestor(Node* node)
-{
- ASSERT(node);
- Node* parent = node;
- while ((node = node->parentNode()))
- parent = node;
- return parent;
-}
-
</del><span class="cx"> static Node* previousNodeConsideringAtomicNodes(const Node* node)
</span><span class="cx"> {
</span><span class="cx"> if (node->previousSibling()) {
</span></span></pre></div>
<a id="trunkSourceWebCoreeditinghtmleditingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/htmlediting.h (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/htmlediting.h        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/editing/htmlediting.h        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -53,7 +53,6 @@
</span><span class="cx">
</span><span class="cx"> // Functions returning Node
</span><span class="cx">
</span><del>-Node* highestAncestor(Node*);
</del><span class="cx"> Node* highestEditableRoot(const Position&, EditableType = ContentIsEditable);
</span><span class="cx">
</span><span class="cx"> Node* highestEnclosingNodeOfType(const Position&, bool (*nodeIsOfType)(const Node*),
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlFormAssociatedElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/FormAssociatedElement.cpp (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/FormAssociatedElement.cpp        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/html/FormAssociatedElement.cpp        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -82,6 +82,17 @@
</span><span class="cx"> resetFormAttributeTargetObserver();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+// Compute the highest ancestor instead of calling Node::rootNode in removedFrom / formRemovedFromTree
+// since inDocument flag on some form associated elements may not have been updated yet.
+static Node* computeRootNode(Node& node)
+{
+ Node* current = &node;
+ Node* parent = current;
+ while ((current = current->parentNode()))
+ parent = current;
+ return parent;
+}
+
</ins><span class="cx"> void FormAssociatedElement::removedFrom(ContainerNode& insertionPoint)
</span><span class="cx"> {
</span><span class="cx"> HTMLElement& element = asHTMLElement();
</span><span class="lines">@@ -89,7 +100,7 @@
</span><span class="cx"> m_formAttributeTargetObserver = nullptr;
</span><span class="cx"> // If the form and element are both in the same tree, preserve the connection to the form.
</span><span class="cx"> // Otherwise, null out our form and remove ourselves from the form's list of elements.
</span><del>- if (m_form && element.highestAncestor() != m_form->highestAncestor())
</del><ins>+ if (m_form && computeRootNode(element) != computeRootNode(*m_form))
</ins><span class="cx"> setForm(nullptr);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -117,7 +128,7 @@
</span><span class="cx"> void FormAssociatedElement::formRemovedFromTree(const Node* formRoot)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(m_form);
</span><del>- if (asHTMLElement().highestAncestor() != formRoot)
</del><ins>+ if (computeRootNode(asHTMLElement()) != formRoot)
</ins><span class="cx"> setForm(nullptr);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorexmlXPathPathcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/xml/XPathPath.cpp (197886 => 197887)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/xml/XPathPath.cpp        2016-03-09 21:50:04 UTC (rev 197886)
+++ trunk/Source/WebCore/xml/XPathPath.cpp        2016-03-09 22:29:33 UTC (rev 197887)
</span><span class="lines">@@ -88,12 +88,8 @@
</span><span class="cx"> // This is for compatibility with Firefox, and also seems like a more
</span><span class="cx"> // logical treatment of where you would expect the "root" to be.
</span><span class="cx"> Node* context = evaluationContext.node.get();
</span><del>- if (m_isAbsolute && !context->isDocumentNode()) {
- if (context->inDocument())
- context = context->ownerDocument();
- else
- context = context->highestAncestor();
- }
</del><ins>+ if (m_isAbsolute && !context->isDocumentNode())
+ context = context->rootNode();
</ins><span class="cx">
</span><span class="cx"> NodeSet nodes;
</span><span class="cx"> nodes.append(context);
</span></span></pre>
</div>
</div>
</body>
</html>