<!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>[205060] 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/205060">205060</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2016-08-26 17:04:08 -0700 (Fri, 26 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Adopted custom element's callbacks should continue to work
https://bugs.webkit.org/show_bug.cgi?id=161065

Reviewed by Andreas Kling.

Source/WebCore:

When a custom element is adopted into another document, its reaction callbacks need to continue to work.
Because a different document may have its own global object, each custom element needs to remember its
original global object or JSCustomElementInterface. This patch adds the latter to the element rare data.

Tests: fast/custom-elements/connected-callbacks.html
       fast/custom-elements/disconnected-callbacks.html

* bindings/js/JSCustomElementInterface.cpp:
(WebCore::JSCustomElementInterface::constructElement):
(WebCore::JSCustomElementInterface::upgradeElement):
* dom/CustomElementReactionQueue.cpp:
(WebCore::findInterfaceForCustomElement): Deleted.
(WebCore::CustomElementReactionQueue::enqueueConnectedCallbackIfNeeded):
(WebCore::CustomElementReactionQueue::enqueueDisconnectedCallbackIfNeeded):
(WebCore::CustomElementReactionQueue::enqueueAttributeChangedCallbackIfNeeded):
* dom/Element.cpp:
(WebCore::Element::insertedInto): Invoke callbacks even when the current document is not a HTML document.
(WebCore::Element::removedFrom): Ditto.
(WebCore::Element::setCustomElementIsResolved): Moved from Node. Add the element interface to the rare data.
(WebCore::Element::customElementInterface): Added.
* dom/Element.h:
* dom/ElementRareData.cpp:
* dom/ElementRareData.h:
(WebCore::ElementRareData::customElementInterface): Added.
(WebCore::ElementRareData::setCustomElementInterface): Added.
* dom/Node.h:
((WebCore::Node::setCustomElementIsResolved): Deleted.

LayoutTests:

Added test cases for adopting custom elements into various kinds of documents.

* fast/custom-elements/connected-callbacks-expected.txt:
* fast/custom-elements/connected-callbacks.html:
* fast/custom-elements/defined-pseudo-class-expected.txt:
* fast/custom-elements/defined-pseudo-class.html:
* fast/custom-elements/disconnected-callbacks-expected.txt:
* fast/custom-elements/disconnected-callbacks.html:
* fast/custom-elements/resources/document-types.js: Added.
* fast/custom-elements/resources/empty-html-document.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsconnectedcallbacksexpectedtxt">trunk/LayoutTests/fast/custom-elements/connected-callbacks-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsconnectedcallbackshtml">trunk/LayoutTests/fast/custom-elements/connected-callbacks.html</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsdefinedpseudoclassexpectedtxt">trunk/LayoutTests/fast/custom-elements/defined-pseudo-class-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsdefinedpseudoclasshtml">trunk/LayoutTests/fast/custom-elements/defined-pseudo-class.html</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsdisconnectedcallbacksexpectedtxt">trunk/LayoutTests/fast/custom-elements/disconnected-callbacks-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsdisconnectedcallbackshtml">trunk/LayoutTests/fast/custom-elements/disconnected-callbacks.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSCustomElementInterfacecpp">trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp</a></li>
<li><a href="#trunkSourceWebCoredomCustomElementReactionQueuecpp">trunk/Source/WebCore/dom/CustomElementReactionQueue.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementcpp">trunk/Source/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementh">trunk/Source/WebCore/dom/Element.h</a></li>
<li><a href="#trunkSourceWebCoredomElementRareDatacpp">trunk/Source/WebCore/dom/ElementRareData.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementRareDatah">trunk/Source/WebCore/dom/ElementRareData.h</a></li>
<li><a href="#trunkSourceWebCoredomNodeh">trunk/Source/WebCore/dom/Node.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/fast/custom-elements/resources/</li>
<li><a href="#trunkLayoutTestsfastcustomelementsresourcesdocumenttypesjs">trunk/LayoutTests/fast/custom-elements/resources/document-types.js</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsresourcesemptyhtmldocumenthtml">trunk/LayoutTests/fast/custom-elements/resources/empty-html-document.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/LayoutTests/ChangeLog        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2016-08-23  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        Adopted custom element's callbacks should continue to work
+        https://bugs.webkit.org/show_bug.cgi?id=161065
+
+        Reviewed by Andreas Kling.
+
+        Added test cases for adopting custom elements into various kinds of documents.
+
+        * fast/custom-elements/connected-callbacks-expected.txt:
+        * fast/custom-elements/connected-callbacks.html:
+        * fast/custom-elements/defined-pseudo-class-expected.txt:
+        * fast/custom-elements/defined-pseudo-class.html:
+        * fast/custom-elements/disconnected-callbacks-expected.txt:
+        * fast/custom-elements/disconnected-callbacks.html:
+        * fast/custom-elements/resources/document-types.js: Added.
+        * fast/custom-elements/resources/empty-html-document.html: Added.
+
</ins><span class="cx"> 2016-08-26  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Marking webgl/max-active-contexts-webglcontextlost-prevent-default.html as flaky on mac-wk1.
</span></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsconnectedcallbacksexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/custom-elements/connected-callbacks-expected.txt (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/connected-callbacks-expected.txt        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/LayoutTests/fast/custom-elements/connected-callbacks-expected.txt        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -1,10 +1,43 @@
</span><span class="cx"> 
</span><span class="cx"> PASS Inserting a custom element into a document must enqueue and invoke connectedCallback 
</span><del>-PASS Inserting a custom element into a detached node must not enqueue and invoke connectedCallback 
-FAIL Inserting a custom element into a window-less document must enqueue and invoke connectedCallback assert_array_equals: lengths differ, expected 2 got 0
-PASS Inserting an ancestor of a custom element into a document must enqueue and invoke connectedCallback 
-FAIL Inserting an ancestor of custom element into a window-less document must enqueue and invoke connectedCallback assert_array_equals: lengths differ, expected 2 got 0
-PASS Inserting a custom element into a connected shadow tree must enqueue and invoke connectedCallback 
-PASS Inserting the shadow host of a shadow tree with a custom element into a document must enqueue and invoke connectedCallback 
-PASS Inserting a custom element into a detached shadow tree must not enqueue and invoke connectedCallback 
</del><ins>+PASS Inserting an ancestor of custom element into a document must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a shadow tree in a document must enqueue and invoke connectedCallback 
+PASS Inserting the shadow host of a custom element into a document must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a detached shadow tree that belongs to a document must not enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a document of a template element must enqueue and invoke connectedCallback 
+PASS Inserting an ancestor of custom element into a document of a template element must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a shadow tree in a document of a template element must enqueue and invoke connectedCallback 
+PASS Inserting the shadow host of a custom element into a document of a template element must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a detached shadow tree that belongs to a document of a template element must not enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a new document must enqueue and invoke connectedCallback 
+PASS Inserting an ancestor of custom element into a new document must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a shadow tree in a new document must enqueue and invoke connectedCallback 
+PASS Inserting the shadow host of a custom element into a new document must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a detached shadow tree that belongs to a new document must not enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a cloned document must enqueue and invoke connectedCallback 
+PASS Inserting an ancestor of custom element into a cloned document must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a shadow tree in a cloned document must enqueue and invoke connectedCallback 
+PASS Inserting the shadow host of a custom element into a cloned document must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a detached shadow tree that belongs to a cloned document must not enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a document created by createHTMLDocument must enqueue and invoke connectedCallback 
+PASS Inserting an ancestor of custom element into a document created by createHTMLDocument must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a shadow tree in a document created by createHTMLDocument must enqueue and invoke connectedCallback 
+PASS Inserting the shadow host of a custom element into a document created by createHTMLDocument must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a detached shadow tree that belongs to a document created by createHTMLDocument must not enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a HTML document created by createDocument must enqueue and invoke connectedCallback 
+PASS Inserting an ancestor of custom element into a HTML document created by createDocument must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a shadow tree in a HTML document created by createDocument must enqueue and invoke connectedCallback 
+PASS Inserting the shadow host of a custom element into a HTML document created by createDocument must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a detached shadow tree that belongs to a HTML document created by createDocument must not enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a document in an iframe must enqueue and invoke connectedCallback 
+PASS Inserting an ancestor of custom element into a document in an iframe must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a shadow tree in a document in an iframe must enqueue and invoke connectedCallback 
+PASS Inserting the shadow host of a custom element into a document in an iframe must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a detached shadow tree that belongs to a document in an iframe must not enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a HTML document fetched by XHR must enqueue and invoke connectedCallback 
+PASS Inserting an ancestor of custom element into a HTML document fetched by XHR must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a shadow tree in a HTML document fetched by XHR must enqueue and invoke connectedCallback 
+PASS Inserting the shadow host of a custom element into a HTML document fetched by XHR must enqueue and invoke connectedCallback 
+PASS Inserting a custom element into a detached shadow tree that belongs to a HTML document fetched by XHR must not enqueue and invoke connectedCallback 
</ins><span class="cx"> 
</span><ins>+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsconnectedcallbackshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/custom-elements/connected-callbacks.html (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/connected-callbacks.html        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/LayoutTests/fast/custom-elements/connected-callbacks.html        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -7,6 +7,7 @@
</span><span class="cx"> &lt;link rel=&quot;help&quot; href=&quot;https://w3c.github.io/webcomponents/spec/custom/#dfn-connected-callback&quot;&gt;
</span><span class="cx"> &lt;script src=&quot;../../resources/testharness.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> &lt;script src=&quot;../../resources/testharnessreport.js&quot;&gt;&lt;/script&gt;
</span><ins>+&lt;script src=&quot;./resources/document-types.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> &lt;link rel='stylesheet' href='../../resources/testharness.css'&gt;
</span><span class="cx"> &lt;/head&gt;
</span><span class="cx"> &lt;body&gt;
</span><span class="lines">@@ -20,85 +21,69 @@
</span><span class="cx"> }
</span><span class="cx"> customElements.define('my-custom-element', MyCustomElement);
</span><span class="cx"> 
</span><del>-test(function () {
-    var instance = document.createElement('my-custom-element');
</del><ins>+DocumentTypes.forEach(function (entry) {
+    var documentName = entry.name;
+    var getDocument = entry.create;
</ins><span class="cx"> 
</span><del>-    calls = [];
-    document.body.appendChild(instance);
-    assert_array_equals(calls, ['connected', instance]);
-}, 'Inserting a custom element into a document must enqueue and invoke connectedCallback');
</del><ins>+    promise_test(function () {
+        return getDocument().then(function (doc) {
+            var instance = document.createElement('my-custom-element');
+            calls = [];
+            doc.documentElement.appendChild(instance);
+            assert_array_equals(calls, ['connected', instance]);
+        });
+    }, 'Inserting a custom element into a ' + documentName + ' must enqueue and invoke connectedCallback');
</ins><span class="cx"> 
</span><del>-test(function () {
-    var instance = document.createElement('my-custom-element');
</del><ins>+    promise_test(function () {
+        return getDocument().then(function (doc) {
+            var instance = document.createElement('my-custom-element');
+            var parent = document.createElement('div');
+            parent.appendChild(instance);
+            calls = [];
+            doc.documentElement.appendChild(parent);
+            assert_array_equals(calls, ['connected', instance]);
+        });
+    }, 'Inserting an ancestor of custom element into a ' + documentName + ' must enqueue and invoke connectedCallback');
</ins><span class="cx"> 
</span><del>-    calls = [];
-    var parent = document.createElement('div');
-    parent.appendChild(instance);
-    assert_array_equals(calls, []);
-}, 'Inserting a custom element into a detached node must not enqueue and invoke connectedCallback');
</del><ins>+    promise_test(function () {
+        return getDocument().then(function (doc) {
+            var instance = document.createElement('my-custom-element');
+            var host = doc.createElementNS('http://www.w3.org/1999/xhtml', 'div');
+            var shadowRoot = host.attachShadow({mode: 'closed'});
+            doc.documentElement.appendChild(host);
</ins><span class="cx"> 
</span><del>-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var documentWithoutWindow = document.implementation.createHTMLDocument();
</del><ins>+            calls = [];
+            shadowRoot.appendChild(instance);
+            assert_array_equals(calls, ['connected', instance]);
+        });
+    }, 'Inserting a custom element into a shadow tree in a ' + documentName + ' must enqueue and invoke connectedCallback');
</ins><span class="cx"> 
</span><del>-    calls = [];
-    documentWithoutWindow.body.appendChild(instance);
-    assert_array_equals(calls, ['connected', instance]);
-}, 'Inserting a custom element into a window-less document must enqueue and invoke connectedCallback');
</del><ins>+    promise_test(function () {
+        return getDocument().then(function (doc) {
+            var instance = document.createElement('my-custom-element');
+            var host = doc.createElementNS('http://www.w3.org/1999/xhtml', 'div');
+            var shadowRoot = host.attachShadow({mode: 'closed'});
+            shadowRoot.appendChild(instance);
</ins><span class="cx"> 
</span><del>-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var parent = document.createElement('div');
-    parent.appendChild(instance);
</del><ins>+            calls = [];
+            doc.documentElement.appendChild(host);
+            assert_array_equals(calls, ['connected', instance]);
+        });
+    }, 'Inserting the shadow host of a custom element into a ' + documentName + ' must enqueue and invoke connectedCallback');
</ins><span class="cx"> 
</span><del>-    calls = [];
-    document.body.appendChild(parent);
-    assert_array_equals(calls, ['connected', instance]);
-}, 'Inserting an ancestor of a custom element into a document must enqueue and invoke connectedCallback');
</del><ins>+    promise_test(function () {
+        return getDocument().then(function (doc) {
+            var instance = document.createElement('my-custom-element');
+            var host = doc.createElementNS('http://www.w3.org/1999/xhtml', 'div');
+            var shadowRoot = host.attachShadow({mode: 'closed'});
</ins><span class="cx"> 
</span><del>-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var parent = document.createElement('div');
-    parent.appendChild(instance);
-    var documentWithoutWindow = document.implementation.createHTMLDocument();
</del><ins>+            calls = [];
+            shadowRoot.appendChild(instance);
+            assert_array_equals(calls, []);
+        });
+    }, 'Inserting a custom element into a detached shadow tree that belongs to a ' + documentName + ' must not enqueue and invoke connectedCallback');
+});
</ins><span class="cx"> 
</span><del>-    calls = [];
-    documentWithoutWindow.body.appendChild(parent);
-    assert_array_equals(calls, ['connected', instance]);
-}, 'Inserting an ancestor of custom element into a window-less document must enqueue and invoke connectedCallback');
-
-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var host = document.createElement('div');
-    var shadowRoot = host.attachShadow({mode: 'closed'});
-    document.body.appendChild(host);
-
-    calls = [];
-    shadowRoot.appendChild(instance);
-    assert_array_equals(calls, ['connected', instance]);
-}, 'Inserting a custom element into a connected shadow tree must enqueue and invoke connectedCallback');
-
-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var host = document.createElement('div');
-    var shadowRoot = host.attachShadow({mode: 'closed'});
-    shadowRoot.appendChild(instance);
-
-    calls = [];
-    document.body.appendChild(host);
-    assert_array_equals(calls, ['connected', instance]);
-}, 'Inserting the shadow host of a shadow tree with a custom element into a document must enqueue and invoke connectedCallback');
-
-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var host = document.createElement('div');
-    var shadowRoot = host.attachShadow({mode: 'closed'});
-
-    calls = [];
-    shadowRoot.appendChild(instance);
-    assert_array_equals(calls, []);
-}, 'Inserting a custom element into a detached shadow tree must not enqueue and invoke connectedCallback');
-
</del><span class="cx"> &lt;/script&gt;
</span><span class="cx"> &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsdefinedpseudoclassexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/custom-elements/defined-pseudo-class-expected.txt (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/defined-pseudo-class-expected.txt        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/LayoutTests/fast/custom-elements/defined-pseudo-class-expected.txt        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> 
</span><del>-PASS The defined flag of a custom element must be set if a custom element has not been upgraded yet 
</del><ins>+PASS The defined flag of a custom element must not be set if a custom element has not been upgraded yet 
</ins><span class="cx"> PASS The defined flag of a custom element must be set when a custom element is successfully upgraded 
</span><span class="cx"> PASS The defined flag of a custom element must be set if there is a matching definition 
</span><span class="cx"> PASS The defined flag of a custom element created by HTML parser must be unset if there is no matching definition 
</span></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsdefinedpseudoclasshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/custom-elements/defined-pseudo-class.html (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/defined-pseudo-class.html        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/LayoutTests/fast/custom-elements/defined-pseudo-class.html        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -16,7 +16,7 @@
</span><span class="cx"> 
</span><span class="cx"> test(function () {
</span><span class="cx">     assert_false(upgradeCandidate.matches(':defined'));
</span><del>-}, 'The defined flag of a custom element must be set if a custom element has not been upgraded yet');
</del><ins>+}, 'The defined flag of a custom element must not be set if a custom element has not been upgraded yet');
</ins><span class="cx"> 
</span><span class="cx"> var matchInsideConstructor;
</span><span class="cx"> class MyElement extends HTMLElement {
</span></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsdisconnectedcallbacksexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/custom-elements/disconnected-callbacks-expected.txt (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/disconnected-callbacks-expected.txt        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/LayoutTests/fast/custom-elements/disconnected-callbacks-expected.txt        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -1,10 +1,43 @@
</span><span class="cx"> 
</span><span class="cx"> PASS Removing a custom element from a document must enqueue and invoke disconnectedCallback 
</span><del>-PASS Removing a custom element from a detahed node must not enqueue and invoke connectedCallback 
-FAIL Removing a custom element from a window-less document must enqueue and invoke disconnectedCallback assert_array_equals: lengths differ, expected 2 got 0
-PASS Removing an ancestor of a custom element from a document must enqueue and invoke disconnectedCallback 
-FAIL Removing an ancestor of custom element from a a window-less document must enqueue and invoke disconnectedCallback assert_array_equals: lengths differ, expected 2 got 0
-PASS Removing a custom element from a connected shadow tree must enqueue and invoke disconnectedCallback 
-PASS Removing the shadow host of a shadow tree with a custom element from a document must enqueue and invoke disconnectedCallback 
-PASS Removing a custom element from a detached shadow tree must not enqueue and invoke disconnectedCallback 
</del><ins>+PASS Removing an ancestor of custom element from a document must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a shadow tree in a document must enqueue and invoke disconnectedCallback 
+PASS Removing the shadow host of a custom element from adocument must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a detached shadow tree that belongs to a document must not enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a document of a template element must enqueue and invoke disconnectedCallback 
+PASS Removing an ancestor of custom element from a document of a template element must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a shadow tree in a document of a template element must enqueue and invoke disconnectedCallback 
+PASS Removing the shadow host of a custom element from adocument of a template element must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a detached shadow tree that belongs to a document of a template element must not enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a new document must enqueue and invoke disconnectedCallback 
+PASS Removing an ancestor of custom element from a new document must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a shadow tree in a new document must enqueue and invoke disconnectedCallback 
+PASS Removing the shadow host of a custom element from anew document must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a detached shadow tree that belongs to a new document must not enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a cloned document must enqueue and invoke disconnectedCallback 
+PASS Removing an ancestor of custom element from a cloned document must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a shadow tree in a cloned document must enqueue and invoke disconnectedCallback 
+PASS Removing the shadow host of a custom element from acloned document must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a detached shadow tree that belongs to a cloned document must not enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a document created by createHTMLDocument must enqueue and invoke disconnectedCallback 
+PASS Removing an ancestor of custom element from a document created by createHTMLDocument must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a shadow tree in a document created by createHTMLDocument must enqueue and invoke disconnectedCallback 
+PASS Removing the shadow host of a custom element from adocument created by createHTMLDocument must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a detached shadow tree that belongs to a document created by createHTMLDocument must not enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a HTML document created by createDocument must enqueue and invoke disconnectedCallback 
+PASS Removing an ancestor of custom element from a HTML document created by createDocument must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a shadow tree in a HTML document created by createDocument must enqueue and invoke disconnectedCallback 
+PASS Removing the shadow host of a custom element from aHTML document created by createDocument must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a detached shadow tree that belongs to a HTML document created by createDocument must not enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a document in an iframe must enqueue and invoke disconnectedCallback 
+PASS Removing an ancestor of custom element from a document in an iframe must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a shadow tree in a document in an iframe must enqueue and invoke disconnectedCallback 
+PASS Removing the shadow host of a custom element from adocument in an iframe must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a detached shadow tree that belongs to a document in an iframe must not enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a HTML document fetched by XHR must enqueue and invoke disconnectedCallback 
+PASS Removing an ancestor of custom element from a HTML document fetched by XHR must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a shadow tree in a HTML document fetched by XHR must enqueue and invoke disconnectedCallback 
+PASS Removing the shadow host of a custom element from aHTML document fetched by XHR must enqueue and invoke disconnectedCallback 
+PASS Removing a custom element from a detached shadow tree that belongs to a HTML document fetched by XHR must not enqueue and invoke disconnectedCallback 
</ins><span class="cx"> 
</span><ins>+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsdisconnectedcallbackshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/custom-elements/disconnected-callbacks.html (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/disconnected-callbacks.html        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/LayoutTests/fast/custom-elements/disconnected-callbacks.html        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -7,6 +7,7 @@
</span><span class="cx"> &lt;link rel=&quot;help&quot; href=&quot;https://w3c.github.io/webcomponents/spec/custom/#dfn-connected-callback&quot;&gt;
</span><span class="cx"> &lt;script src=&quot;../../resources/testharness.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> &lt;script src=&quot;../../resources/testharnessreport.js&quot;&gt;&lt;/script&gt;
</span><ins>+&lt;script src=&quot;./resources/document-types.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> &lt;link rel='stylesheet' href='../../resources/testharness.css'&gt;
</span><span class="cx"> &lt;/head&gt;
</span><span class="cx"> &lt;body&gt;
</span><span class="lines">@@ -20,94 +21,74 @@
</span><span class="cx"> }
</span><span class="cx"> customElements.define('my-custom-element', MyCustomElement);
</span><span class="cx"> 
</span><del>-test(function () {
-    var instance = document.createElement('my-custom-element');
-    document.body.appendChild(instance);
</del><ins>+DocumentTypes.forEach(function (entry) {
+    var documentName = entry.name;
+    var getDocument = entry.create;
</ins><span class="cx"> 
</span><del>-    calls = [];
-    document.body.removeChild(instance);
-    assert_array_equals(calls, ['disconnected', instance]);
-}, 'Removing a custom element from a document must enqueue and invoke disconnectedCallback');
</del><ins>+    promise_test(function () {
+        return getDocument().then(function (doc) {
+            var instance = document.createElement('my-custom-element');
+            doc.documentElement.appendChild(instance);
+            calls = [];
+            doc.documentElement.removeChild(instance);
+            assert_array_equals(calls, ['disconnected', instance]);
+        });
+    }, 'Removing a custom element from a ' + documentName + ' must enqueue and invoke disconnectedCallback');
</ins><span class="cx"> 
</span><del>-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var parent = document.createElement('div');
-    parent.appendChild(instance);
</del><ins>+    promise_test(function () {
+        return getDocument().then(function (doc) {
+            var instance = document.createElement('my-custom-element');
+            var parent = document.createElement('div');
+            parent.appendChild(instance);
+            doc.documentElement.appendChild(parent);
+            calls = [];
+            doc.documentElement.removeChild(parent);
+            assert_array_equals(calls, ['disconnected', instance]);
+        });
+    }, 'Removing an ancestor of custom element from a ' + documentName + ' must enqueue and invoke disconnectedCallback');
</ins><span class="cx"> 
</span><del>-    calls = [];
-    parent.removeChild(instance);
-    assert_array_equals(calls, []);
-}, 'Removing a custom element from a detahed node must not enqueue and invoke connectedCallback');
</del><ins>+    promise_test(function () {
+        return getDocument().then(function (doc) {
+            var instance = document.createElement('my-custom-element');
+            var host = doc.createElementNS('http://www.w3.org/1999/xhtml', 'div');
+            var shadowRoot = host.attachShadow({mode: 'closed'});
+            doc.documentElement.appendChild(host);
+            shadowRoot.appendChild(instance);
</ins><span class="cx"> 
</span><del>-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var documentWithoutWindow = document.implementation.createHTMLDocument();
-    documentWithoutWindow.body.appendChild(instance);
</del><ins>+            calls = [];
+            shadowRoot.removeChild(instance);
+            assert_array_equals(calls, ['disconnected', instance]);
+        });
+    }, 'Removing a custom element from a shadow tree in a ' + documentName + ' must enqueue and invoke disconnectedCallback');
</ins><span class="cx"> 
</span><del>-    calls = [];
-    documentWithoutWindow.body.removeChild(instance);
-    assert_array_equals(calls, ['disconnected', instance]);
-}, 'Removing a custom element from a window-less document must enqueue and invoke disconnectedCallback');
</del><ins>+    promise_test(function () {
+        return getDocument().then(function (doc) {
+            var instance = document.createElement('my-custom-element');
+            var host = doc.createElementNS('http://www.w3.org/1999/xhtml', 'div');
+            var shadowRoot = host.attachShadow({mode: 'closed'});
+            shadowRoot.appendChild(instance);
+            doc.documentElement.appendChild(host);
</ins><span class="cx"> 
</span><del>-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var parent = document.createElement('div');
-    parent.appendChild(instance);
-    document.body.appendChild(parent);
</del><ins>+            calls = [];
+            doc.documentElement.removeChild(host);
+            assert_array_equals(calls, ['disconnected', instance]);
+        });
+    }, 'Removing the shadow host of a custom element from a' + documentName + ' must enqueue and invoke disconnectedCallback');
</ins><span class="cx"> 
</span><del>-    calls = [];
-    document.body.removeChild(parent);
-    assert_array_equals(calls, ['disconnected', instance]);
-}, 'Removing an ancestor of a custom element from a document must enqueue and invoke disconnectedCallback');
</del><ins>+    promise_test(function () {
+        return getDocument().then(function (doc) {
+            var instance = document.createElement('my-custom-element');
+            var host = doc.createElementNS('http://www.w3.org/1999/xhtml', 'div');
+            var shadowRoot = host.attachShadow({mode: 'closed'});
+            shadowRoot.appendChild(instance);
</ins><span class="cx"> 
</span><del>-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var parent = document.createElement('div');
-    parent.appendChild(instance);
-    var documentWithoutWindow = document.implementation.createHTMLDocument();
-    documentWithoutWindow.body.appendChild(parent);
</del><ins>+            calls = [];
+            shadowRoot.removeChild(instance);
+            assert_array_equals(calls, []);
+        });
+    }, 'Removing a custom element from a detached shadow tree that belongs to a ' + documentName + ' must not enqueue and invoke disconnectedCallback');
+});
</ins><span class="cx"> 
</span><del>-    calls = [];
-    documentWithoutWindow.body.removeChild(parent);
-    assert_array_equals(calls, ['disconnected', instance]);
-}, 'Removing an ancestor of custom element from a a window-less document must enqueue and invoke disconnectedCallback');
-
-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var host = document.createElement('div');
-    document.body.appendChild(host);
-    var shadowRoot = host.attachShadow({mode: 'closed'});
-    shadowRoot.appendChild(instance);
-
-    calls = [];
-    shadowRoot.removeChild(instance);
-    assert_array_equals(calls, ['disconnected', instance]);
-}, 'Removing a custom element from a connected shadow tree must enqueue and invoke disconnectedCallback');
-
-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var host = document.createElement('div');
-    var shadowRoot = host.attachShadow({mode: 'closed'});
-    shadowRoot.appendChild(instance);
-    document.body.appendChild(host);
-
-    calls = [];
-    document.body.removeChild(host);
-    assert_array_equals(calls, ['disconnected', instance]);
-}, 'Removing the shadow host of a shadow tree with a custom element from a document must enqueue and invoke disconnectedCallback');
-
-test(function () {
-    var instance = document.createElement('my-custom-element');
-    var host = document.createElement('div');
-    var shadowRoot = host.attachShadow({mode: 'closed'});
-    shadowRoot.appendChild(instance);
-
-    calls = [];
-    shadowRoot.removeChild(instance);
-    assert_array_equals(calls, []);
-}, 'Removing a custom element from a detached shadow tree must not enqueue and invoke disconnectedCallback');
-
-
</del><span class="cx"> &lt;/script&gt;
</span><span class="cx"> &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsresourcesdocumenttypesjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/custom-elements/resources/document-types.js (0 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/resources/document-types.js                                (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/resources/document-types.js        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+const DocumentTypes = [
+    {
+        name: 'document',
+        create: function () { return Promise.resolve(document); }
+    },
+    {
+        name: 'document of a template element',
+        create: function () {
+            return new Promise(function (resolve) {
+                var template = document.createElementNS('http://www.w3.org/1999/xhtml', 'template');
+                var doc = template.content.ownerDocument;
+                if (!doc.documentElement)
+                    doc.appendChild(doc.createElement('html'));
+                resolve(doc);
+            });
+        }
+    },
+    {
+        name: 'new document',
+        create: function () {
+            return new Promise(function (resolve) {
+                var doc = new Document();
+                doc.appendChild(doc.createElement('html'));
+                resolve(doc);
+            });
+        }
+    },
+    {
+        name: 'cloned document',
+        create: function () {
+            return new Promise(function (resolve) {
+                var doc = document.cloneNode(false);
+                doc.appendChild(doc.createElement('html'));
+                resolve(doc);
+            });
+        }
+    },
+    {
+        name: 'document created by createHTMLDocument',
+        create: function () {
+            return Promise.resolve(document.implementation.createHTMLDocument());
+        }
+    },
+    {
+        name: 'HTML document created by createDocument',
+        create: function () {
+            return Promise.resolve(document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null));
+        }
+    },
+    {
+        name: 'document in an iframe',
+        create: function () {
+            return new Promise(function (resolve, reject) {
+                var iframe = document.createElement('iframe');
+                iframe.onload = function () { resolve(iframe.contentDocument); }
+                iframe.onerror = function () { reject('Failed to load an empty iframe'); }
+                document.body.appendChild(iframe);
+            });
+        }
+    },
+    {
+        name: 'HTML document fetched by XHR',
+        create: function () {
+            return new Promise(function (resolve, reject) {
+                var xhr = new XMLHttpRequest();
+                xhr.open('GET', 'resources/empty-html-document.html');
+                xhr.overrideMimeType('text/xml');
+                xhr.onload = function () { resolve(xhr.responseXML); }
+                xhr.onerror = function () { reject('Failed to fetch the document'); }
+                xhr.send();
+            });
+        }
+    }
+];
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsresourcesemptyhtmldocumenthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/custom-elements/resources/empty-html-document.html (0 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/resources/empty-html-document.html                                (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/resources/empty-html-document.html        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/Source/WebCore/ChangeLog        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -1,3 +1,38 @@
</span><ins>+2016-08-23  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        Adopted custom element's callbacks should continue to work
+        https://bugs.webkit.org/show_bug.cgi?id=161065
+
+        Reviewed by Andreas Kling.
+
+        When a custom element is adopted into another document, its reaction callbacks need to continue to work.
+        Because a different document may have its own global object, each custom element needs to remember its
+        original global object or JSCustomElementInterface. This patch adds the latter to the element rare data.
+
+        Tests: fast/custom-elements/connected-callbacks.html
+               fast/custom-elements/disconnected-callbacks.html
+
+        * bindings/js/JSCustomElementInterface.cpp:
+        (WebCore::JSCustomElementInterface::constructElement):
+        (WebCore::JSCustomElementInterface::upgradeElement):
+        * dom/CustomElementReactionQueue.cpp:
+        (WebCore::findInterfaceForCustomElement): Deleted.
+        (WebCore::CustomElementReactionQueue::enqueueConnectedCallbackIfNeeded):
+        (WebCore::CustomElementReactionQueue::enqueueDisconnectedCallbackIfNeeded):
+        (WebCore::CustomElementReactionQueue::enqueueAttributeChangedCallbackIfNeeded):
+        * dom/Element.cpp:
+        (WebCore::Element::insertedInto): Invoke callbacks even when the current document is not a HTML document.
+        (WebCore::Element::removedFrom): Ditto.
+        (WebCore::Element::setCustomElementIsResolved): Moved from Node. Add the element interface to the rare data.
+        (WebCore::Element::customElementInterface): Added.
+        * dom/Element.h:
+        * dom/ElementRareData.cpp:
+        * dom/ElementRareData.h:
+        (WebCore::ElementRareData::customElementInterface): Added.
+        (WebCore::ElementRareData::setCustomElementInterface): Added.
+        * dom/Node.h:
+        ((WebCore::Node::setCustomElementIsResolved): Deleted.
+
</ins><span class="cx"> 2016-08-26  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         ASSERT_NOT_REACHED() is touched in WebCore::minimumValueForLength
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSCustomElementInterfacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -98,7 +98,7 @@
</span><span class="cx">     Element* wrappedElement = JSElement::toWrapped(newElement);
</span><span class="cx">     if (!wrappedElement)
</span><span class="cx">         return nullptr;
</span><del>-    wrappedElement-&gt;setCustomElementIsResolved();
</del><ins>+    wrappedElement-&gt;setCustomElementIsResolved(*this);
</ins><span class="cx">     return wrappedElement;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -147,8 +147,7 @@
</span><span class="cx">         throwInvalidStateError(*state, &quot;Custom element constructor failed to upgrade an element&quot;);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-    wrappedElement-&gt;setCustomElementIsResolved();
-    ASSERT(wrappedElement-&gt;isCustomElement());
</del><ins>+    wrappedElement-&gt;setCustomElementIsResolved(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSCustomElementInterface::invokeCallback(Element&amp; element, JSObject* callback, const WTF::Function&lt;void(ExecState*, MarkedArgumentBuffer&amp;)&gt;&amp; addArguments)
</span></span></pre></div>
<a id="trunkSourceWebCoredomCustomElementReactionQueuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/CustomElementReactionQueue.cpp (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/CustomElementReactionQueue.cpp        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/Source/WebCore/dom/CustomElementReactionQueue.cpp        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -106,23 +106,9 @@
</span><span class="cx">         queue-&gt;m_items.append({CustomElementReactionQueueItem::Type::ElementUpgrade, element, elementInterface});
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static JSCustomElementInterface* findInterfaceForCustomElement(Element&amp; element)
-{
-    ASSERT(element.isCustomElement());
-    auto* window = element.document().domWindow();
-    if (!window)
-        return nullptr;
-
-    auto* registry = window-&gt;customElementRegistry();
-    if (!registry)
-        return nullptr;
-
-    return registry-&gt;findInterface(element.tagQName());
-}
-
</del><span class="cx"> void CustomElementReactionQueue::enqueueConnectedCallbackIfNeeded(Element&amp; element)
</span><span class="cx"> {
</span><del>-    auto* elementInterface = findInterfaceForCustomElement(element);
</del><ins>+    auto* elementInterface = element.customElementInterface();
</ins><span class="cx">     if (!elementInterface)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -132,7 +118,7 @@
</span><span class="cx"> 
</span><span class="cx"> void CustomElementReactionQueue::enqueueDisconnectedCallbackIfNeeded(Element&amp; element)
</span><span class="cx"> {
</span><del>-    auto* elementInterface = findInterfaceForCustomElement(element);
</del><ins>+    auto* elementInterface = element.customElementInterface();
</ins><span class="cx">     if (!elementInterface)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -142,7 +128,7 @@
</span><span class="cx"> 
</span><span class="cx"> void CustomElementReactionQueue::enqueueAttributeChangedCallbackIfNeeded(Element&amp; element, const QualifiedName&amp; attributeName, const AtomicString&amp; oldValue, const AtomicString&amp; newValue)
</span><span class="cx"> {
</span><del>-    auto* elementInterface = findInterfaceForCustomElement(element);
</del><ins>+    auto* elementInterface = element.customElementInterface();
</ins><span class="cx">     if (!elementInterface || !elementInterface-&gt;observesAttribute(attributeName.localName()))
</span><span class="cx">         return;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.cpp (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.cpp        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/Source/WebCore/dom/Element.cpp        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -1574,7 +1574,8 @@
</span><span class="cx">     // This element is new to the shadow tree (and its tree scope) only if the parent into which this element
</span><span class="cx">     // or its ancestor is inserted belongs to the same tree scope as this element's.
</span><span class="cx">     TreeScope* newScope = &amp;insertionPoint.treeScope();
</span><del>-    HTMLDocument* newDocument = !wasInDocument &amp;&amp; inDocument() &amp;&amp; is&lt;HTMLDocument&gt;(newScope-&gt;documentScope()) ? &amp;downcast&lt;HTMLDocument&gt;(newScope-&gt;documentScope()) : nullptr;
</del><ins>+    bool becomeConnected = !wasInDocument &amp;&amp; inDocument();
+    HTMLDocument* newDocument = becomeConnected &amp;&amp; is&lt;HTMLDocument&gt;(newScope-&gt;documentScope()) ? &amp;downcast&lt;HTMLDocument&gt;(newScope-&gt;documentScope()) : nullptr;
</ins><span class="cx">     if (newScope != &amp;treeScope())
</span><span class="cx">         newScope = nullptr;
</span><span class="cx"> 
</span><span class="lines">@@ -1600,7 +1601,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CUSTOM_ELEMENTS)
</span><del>-    if (newDocument &amp;&amp; UNLIKELY(isCustomElement()))
</del><ins>+    if (becomeConnected &amp;&amp; UNLIKELY(isCustomElement()))
</ins><span class="cx">         CustomElementReactionQueue::enqueueConnectedCallbackIfNeeded(*this);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -1622,7 +1623,8 @@
</span><span class="cx"> 
</span><span class="cx">     if (insertionPoint.isInTreeScope()) {
</span><span class="cx">         TreeScope* oldScope = &amp;insertionPoint.treeScope();
</span><del>-        HTMLDocument* oldDocument = inDocument() &amp;&amp; is&lt;HTMLDocument&gt;(oldScope-&gt;documentScope()) ? &amp;downcast&lt;HTMLDocument&gt;(oldScope-&gt;documentScope()) : nullptr;
</del><ins>+        bool becomeDisconnected = inDocument();
+        HTMLDocument* oldDocument = becomeDisconnected &amp;&amp; is&lt;HTMLDocument&gt;(oldScope-&gt;documentScope()) ? &amp;downcast&lt;HTMLDocument&gt;(oldScope-&gt;documentScope()) : nullptr;
</ins><span class="cx"> 
</span><span class="cx">         // ContainerNode::removeBetween always sets the removed chid's tree scope to Document's but InTreeScope flag is unset in Node::removedFrom.
</span><span class="cx">         // So this element has been removed from the old tree scope only if InTreeScope flag is set and this element's tree scope is Document's.
</span><span class="lines">@@ -1651,7 +1653,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CUSTOM_ELEMENTS)
</span><del>-        if (oldDocument &amp;&amp; UNLIKELY(isCustomElement()))
</del><ins>+        if (becomeDisconnected &amp;&amp; UNLIKELY(isCustomElement()))
</ins><span class="cx">             CustomElementReactionQueue::enqueueDisconnectedCallbackIfNeeded(*this);
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="lines">@@ -1821,6 +1823,27 @@
</span><span class="cx">     return *shadowRoot;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+    
+#if ENABLE(CUSTOM_ELEMENTS)
+
+void Element::setCustomElementIsResolved(JSCustomElementInterface&amp; elementInterface)
+{
+    clearFlag(IsEditingTextOrUnresolvedCustomElementFlag);
+    setFlag(IsCustomElement);
+    ensureElementRareData().setCustomElementInterface(elementInterface);
+}
+
+JSCustomElementInterface* Element::customElementInterface() const
+{
+    ASSERT(isCustomElement());
+    if (!hasRareData())
+        return nullptr;
+    return elementRareData()-&gt;customElementInterface();
+}
+
+#endif
+
+
</ins><span class="cx"> const AtomicString&amp; Element::shadowPseudoId() const
</span><span class="cx"> {
</span><span class="cx">     return pseudo();
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.h (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.h        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/Source/WebCore/dom/Element.h        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx"> class ElementRareData;
</span><span class="cx"> class HTMLDocument;
</span><span class="cx"> class IntSize;
</span><ins>+class JSCustomElementInterface;
</ins><span class="cx"> class KeyboardEvent;
</span><span class="cx"> class Locale;
</span><span class="cx"> class PlatformKeyboardEvent;
</span><span class="lines">@@ -272,6 +273,11 @@
</span><span class="cx">     ShadowRoot* userAgentShadowRoot() const;
</span><span class="cx">     WEBCORE_EXPORT ShadowRoot&amp; ensureUserAgentShadowRoot();
</span><span class="cx"> 
</span><ins>+#if ENABLE(CUSTOM_ELEMENTS)
+    void setCustomElementIsResolved(JSCustomElementInterface&amp;);
+    JSCustomElementInterface* customElementInterface() const;
+#endif
+
</ins><span class="cx">     // FIXME: this should not be virtual, do not override this.
</span><span class="cx">     virtual const AtomicString&amp; shadowPseudoId() const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementRareDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ElementRareData.cpp (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ElementRareData.cpp        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/Source/WebCore/dom/ElementRareData.cpp        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -44,7 +44,11 @@
</span><span class="cx">     RegionOversetState regionOversetState;
</span><span class="cx">     LayoutSize sizeForResizing;
</span><span class="cx">     IntPoint savedLayerScrollPosition;
</span><ins>+#if ENABLE(CUSTOM_ELEMENTS)
+    void* pointers[8];
+#else
</ins><span class="cx">     void* pointers[7];
</span><ins>+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static_assert(sizeof(ElementRareData) == sizeof(SameSizeAsElementRareData), &quot;ElementRareData should stay small&quot;);
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementRareDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ElementRareData.h (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ElementRareData.h        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/Source/WebCore/dom/ElementRareData.h        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -24,6 +24,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DOMTokenList.h&quot;
</span><span class="cx"> #include &quot;DatasetDOMStringMap.h&quot;
</span><ins>+#include &quot;JSCustomElementInterface.h&quot;
</ins><span class="cx"> #include &quot;NamedNodeMap.h&quot;
</span><span class="cx"> #include &quot;NodeRareData.h&quot;
</span><span class="cx"> #include &quot;PseudoElement.h&quot;
</span><span class="lines">@@ -93,6 +94,11 @@
</span><span class="cx">     ShadowRoot* shadowRoot() const { return m_shadowRoot.get(); }
</span><span class="cx">     void setShadowRoot(RefPtr&lt;ShadowRoot&gt;&amp;&amp; shadowRoot) { m_shadowRoot = WTFMove(shadowRoot); }
</span><span class="cx"> 
</span><ins>+#if ENABLE(CUSTOM_ELEMENTS)
+    JSCustomElementInterface* customElementInterface() { return m_customElementInterface.get(); }
+    void setCustomElementInterface(JSCustomElementInterface&amp; customElementInterface) { m_customElementInterface = &amp;customElementInterface; }
+#endif
+
</ins><span class="cx">     NamedNodeMap* attributeMap() const { return m_attributeMap.get(); }
</span><span class="cx">     void setAttributeMap(std::unique_ptr&lt;NamedNodeMap&gt; attributeMap) { m_attributeMap = WTFMove(attributeMap); }
</span><span class="cx"> 
</span><span class="lines">@@ -149,6 +155,9 @@
</span><span class="cx">     std::unique_ptr&lt;DatasetDOMStringMap&gt; m_dataset;
</span><span class="cx">     std::unique_ptr&lt;DOMTokenList&gt; m_classList;
</span><span class="cx">     RefPtr&lt;ShadowRoot&gt; m_shadowRoot;
</span><ins>+#if ENABLE(CUSTOM_ELEMENTS)
+    RefPtr&lt;JSCustomElementInterface&gt; m_customElementInterface;
+#endif
</ins><span class="cx">     std::unique_ptr&lt;NamedNodeMap&gt; m_attributeMap;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;PseudoElement&gt; m_beforePseudoElement;
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.h (205059 => 205060)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.h        2016-08-26 23:47:40 UTC (rev 205059)
+++ trunk/Source/WebCore/dom/Node.h        2016-08-27 00:04:08 UTC (rev 205060)
</span><span class="lines">@@ -267,7 +267,6 @@
</span><span class="cx"> 
</span><span class="cx">     bool isUnresolvedCustomElement() const { return isElementNode() &amp;&amp; getFlag(IsEditingTextOrUnresolvedCustomElementFlag); }
</span><span class="cx">     void setIsUnresolvedCustomElement() { setFlag(IsEditingTextOrUnresolvedCustomElementFlag); }
</span><del>-    void setCustomElementIsResolved();
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     // Returns null, a child of ShadowRoot, or a legacy shadow root.
</span><span class="lines">@@ -769,16 +768,6 @@
</span><span class="cx">     return parentNode();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if ENABLE(CUSTOM_ELEMENTS)
-
-inline void Node::setCustomElementIsResolved()
-{
-    clearFlag(IsEditingTextOrUnresolvedCustomElementFlag);
-    setFlag(IsCustomElement);
-}
-
-#endif
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(TREE_DEBUGGING)
</span></span></pre>
</div>
</div>

</body>
</html>