<!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>[197528] 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/197528">197528</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2016-03-03 16:28:44 -0800 (Thu, 03 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Source/WebCore:
Disallow custom elements inside a window-less documents
https://bugs.webkit.org/show_bug.cgi?id=154944
&lt;rdar://problem/24944875&gt;

Reviewed by Antti Koivisto.

Disallow custom elements inside a window-less documents such as the shared inert document of template elements
and the ones created by DOMImplementation.createDocument and DOMImplementation.createHTMLDocument.

Throw NotSupportedError in defineCustomElement when it's called in such a document as discussed in:
https://github.com/w3c/webcomponents/issues/369

Tests: fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html
       fast/custom-elements/parser/parser-uses-registry-of-owner-document.html

* bindings/js/JSDOMBinding.cpp:
(WebCore::throwNotSupportedError): Added.
* bindings/js/JSDOMBinding.h:
* bindings/js/JSDocumentCustom.cpp:
(WebCore::JSDocument::defineCustomElement): Throw NotSupportedError when the context object's document doesn't
have a browsing context (i.e. window-less).
* html/parser/HTMLDocumentParser.cpp:
(WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder): Replaced a FIXME with an assertion now that we
disallow instantiation of custom elements inside a template element.

LayoutTests:
Disallow custom elements inside template elements and share the registry for windowless documents
https://bugs.webkit.org/show_bug.cgi?id=154944
&lt;rdar://problem/24944875&gt;

Reviewed by Antti Koivisto.

Added various tests to ensure the custom elements registry is not shared between documents with
distinct browsing context (e.g. iframes) but shared among the ones that share a single browsing context
(e.g. documents created by DOMImplementation).

Also added a test case for defineCustomElement to ensure it throws NotSupportedError when it's called on
a template element's inert owner document as well as a basic test case for document.write.

* fast/custom-elements/Document-defineCustomElement-expected.txt:
* fast/custom-elements/Document-defineCustomElement.html: Added a new test case.
* fast/custom-elements/parser/parser-constructs-custom-element-in-document-write-expected.txt: Added.
* fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html: Added.
* fast/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt: Added.
* fast/custom-elements/parser/parser-uses-registry-of-owner-document.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsDocumentdefineCustomElementexpectedtxt">trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsDocumentdefineCustomElementhtml">trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingcpp">trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingh">trunk/Source/WebCore/bindings/js/JSDOMBinding.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDocumentCustomcpp">trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLDocumentParsercpp">trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLTreeBuilderh">trunk/Source/WebCore/html/parser/HTMLTreeBuilder.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastcustomelementsparserparserconstructscustomelementindocumentwriteexpectedtxt">trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsparserparserconstructscustomelementindocumentwritehtml">trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsparserparserusesregistryofownerdocumentexpectedtxt">trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcustomelementsparserparserusesregistryofownerdocumenthtml">trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (197527 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-03-04 00:26:23 UTC (rev 197527)
+++ trunk/LayoutTests/ChangeLog        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2016-03-02  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        Disallow custom elements inside template elements and share the registry for windowless documents
+        https://bugs.webkit.org/show_bug.cgi?id=154944
+        &lt;rdar://problem/24944875&gt;
+
+        Reviewed by Antti Koivisto.
+
+        Added various tests to ensure the custom elements registry is not shared between documents with
+        distinct browsing context (e.g. iframes) but shared among the ones that share a single browsing context
+        (e.g. documents created by DOMImplementation).
+
+        Also added a test case for defineCustomElement to ensure it throws NotSupportedError when it's called on
+        a template element's inert owner document as well as a basic test case for document.write.
+
+        * fast/custom-elements/Document-defineCustomElement-expected.txt:
+        * fast/custom-elements/Document-defineCustomElement.html: Added a new test case.
+        * fast/custom-elements/parser/parser-constructs-custom-element-in-document-write-expected.txt: Added.
+        * fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html: Added.
+        * fast/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt: Added.
+        * fast/custom-elements/parser/parser-uses-registry-of-owner-document.html: Added.
+
</ins><span class="cx"> 2016-03-03  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Subpixel rendering: Make collapsed borders painting subpixel aware.
</span></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsDocumentdefineCustomElementexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement-expected.txt (197527 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement-expected.txt        2016-03-04 00:26:23 UTC (rev 197527)
+++ trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement-expected.txt        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -2,6 +2,9 @@
</span><span class="cx"> PASS Check the existence of defineCustomElement on Document interface 
</span><span class="cx"> PASS document.defineCustomElement should throw with an invalid name 
</span><span class="cx"> PASS document.defineCustomElement should throw with a duplicate name 
</span><ins>+PASS document.defineCustomElement must throw a NotSupportedError when the context object is an associated inert template document 
+PASS document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createHTMLDocument 
+PASS document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createDocument 
</ins><span class="cx"> PASS document.defineCustomElement should throw when the element interface is not a constructor 
</span><span class="cx"> PASS document.defineCustomElement should define an instantiatable custom element 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsDocumentdefineCustomElementhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement.html (197527 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement.html        2016-03-04 00:26:23 UTC (rev 197527)
+++ trunk/LayoutTests/fast/custom-elements/Document-defineCustomElement.html        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -58,6 +58,36 @@
</span><span class="cx"> }, 'document.defineCustomElement should throw with a duplicate name');
</span><span class="cx"> 
</span><span class="cx"> test(function () {
</span><ins>+    class SomeCustomElement extends HTMLElement {};
+
+    var templateContentOwnerDocument = document.createElement('template').content.ownerDocument;
+    assert_throws({'name': 'NotSupportedError'}, function () {
+        templateContentOwnerDocument.defineCustomElement('some-custom-element', SomeCustomElement);
+    });
+
+}, 'document.defineCustomElement must throw a NotSupportedError when the context object is an associated inert template document');
+
+test(function () {
+    class SomeCustomElement extends HTMLElement {};
+
+    var windowlessDocument = document.implementation.createHTMLDocument();
+    assert_throws({'name': 'NotSupportedError'}, function () {
+        windowlessDocument.defineCustomElement('some-custom-element', SomeCustomElement);
+    });
+
+}, 'document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createHTMLDocument');
+
+test(function () {
+    class SomeCustomElement extends HTMLElement {};
+
+    var windowlessDocument = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null)
+    assert_throws({'name': 'NotSupportedError'}, function () {
+        windowlessDocument.defineCustomElement('some-custom-element', SomeCustomElement);
+    });
+
+}, 'document.defineCustomElement must throw a NotSupportedError when the context object is created by DOMImplementation.createDocument');
+
+test(function () {
</ins><span class="cx">     assert_throws({'name': 'TypeError'}, function () { document.defineCustomElement('invalid-element', 1); },
</span><span class="cx">         'document.defineCustomElement must throw a TypeError when the element interface is a number');
</span><span class="cx">     assert_throws({'name': 'TypeError'}, function () { document.defineCustomElement('invalid-element', '123'); },
</span></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsparserparserconstructscustomelementindocumentwriteexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write-expected.txt (0 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write-expected.txt        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+
+PASS HTML parser must instantiate custom elements inside document.write 
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsparserparserconstructscustomelementindocumentwritehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html (0 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html                                (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;Custom Elements: Changes to the HTML parser&lt;/title&gt;
+&lt;meta name=&quot;author&quot; title=&quot;Ryosuke Niwa&quot; href=&quot;mailto:rniwa@webkit.org&quot;&gt;
+&lt;meta name=&quot;assert&quot; content=&quot;HTML parser must construct custom elements inside document.write&quot;&gt;
+&lt;script src=&quot;../../../resources/testharness.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../../resources/testharnessreport.js&quot;&gt;&lt;/script&gt;
+&lt;link rel='stylesheet' href='../../../resources/testharness.css'&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div id=&quot;log&quot;&gt;&lt;/div&gt;
+&lt;script&gt;
+
+class MyCustomElement extends HTMLElement { }
+document.defineCustomElement('my-custom-element', MyCustomElement);
+
+document.write('&lt;my-custom-element&gt;&lt;/my-custom-element&gt;');
+
+test(function () {
+    var instance = document.querySelector('my-custom-element');
+
+    assert_true(instance instanceof HTMLElement);
+    assert_true(instance instanceof MyCustomElement);
+
+}, 'HTML parser must instantiate custom elements inside document.write');
+
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsparserparserusesregistryofownerdocumentexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt (0 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+
+PASS HTML parser must not instantiate custom elements inside template elements 
+PASS HTML parser must not use the registry of the owner element's document inside an iframe 
+PASS HTML parser must use the registry of the content document inside an iframe 
+PASS HTML parser must not instantiate a custom element defined inside an frame in frame element's owner document 
+PASS HTML parser must use the registry of window.document in a document created by document.implementation.createHTMLDocument() 
+PASS HTML parser must use the registry of window.document in a document created by document.implementation.createXHTMLDocument() 
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcustomelementsparserparserusesregistryofownerdocumenthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document.html (0 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document.html                                (rev 0)
+++ trunk/LayoutTests/fast/custom-elements/parser/parser-uses-registry-of-owner-document.html        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;Custom Elements: Changes to the HTML parser&lt;/title&gt;
+&lt;meta name=&quot;author&quot; title=&quot;Ryosuke Niwa&quot; href=&quot;mailto:rniwa@webkit.org&quot;&gt;
+&lt;meta name=&quot;assert&quot; content=&quot;HTML parser must use the owner document's custom element registry&quot;&gt;
+&lt;script src=&quot;../../../resources/testharness.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../../resources/testharnessreport.js&quot;&gt;&lt;/script&gt;
+&lt;link rel='stylesheet' href='../../../resources/testharness.css'&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div id=&quot;log&quot;&gt;&lt;/div&gt;
+&lt;script&gt;
+
+class MyCustomElement extends HTMLElement { };
+document.defineCustomElement('my-custom-element', MyCustomElement);
+
+document.write('&lt;template&gt;&lt;my-custom-element&gt;&lt;/my-custom-element&gt;&lt;/template&gt;');
+
+test(function () {
+    var template = document.querySelector('template');
+    var instance = template.content.firstChild;
+
+    assert_true(instance instanceof HTMLElement,
+        'A custom element inside a template element must be an instance of HTMLElement');
+    assert_false(instance instanceof MyCustomElement,
+        'A custom element must not be instantiated inside a template element using the registry of the template element\'s owner document');
+    assert_equals(instance.ownerDocument, template.content.ownerDocument,
+        'Custom elements inside a template must use the appropriate template contents owner document as the owner document');
+
+}, 'HTML parser must not instantiate custom elements inside template elements');
+
+var iframe = document.createElement('iframe');
+document.body.appendChild(iframe);
+iframe.contentDocument.body.innerHTML = '&lt;my-custom-element&gt;&lt;/my-custom-element&gt;';
+
+test(function () {
+    var instance = iframe.contentDocument.querySelector('my-custom-element');
+
+    assert_true(instance instanceof iframe.contentWindow.HTMLElement);
+    assert_false(instance instanceof MyCustomElement);
+
+}, 'HTML parser must not use the registry of the owner element\'s document inside an iframe');
+
+class ElementInIFrame extends iframe.contentWindow.HTMLElement { };
+iframe.contentDocument.defineCustomElement('element-in-iframe', ElementInIFrame);
+iframe.contentDocument.body.innerHTML = '&lt;element-in-iframe&gt;&lt;/element-in-iframe&gt;';
+
+test(function () {
+    var instance = iframe.contentDocument.querySelector('element-in-iframe');
+
+    assert_true(instance instanceof iframe.contentWindow.HTMLElement, 'A custom element inside an iframe must be an instance of HTMLElement');
+    assert_true(instance instanceof ElementInIFrame,
+        'A custom element must be instantiated inside an iframe using the registry of the content document');
+    assert_equals(instance.ownerDocument, iframe.contentDocument,
+        'The owner document of custom elements inside an iframe must be the content document of the iframe');
+
+}, 'HTML parser must use the registry of the content document inside an iframe');
+
+document.write('&lt;element-in-iframe&gt;&lt;/element-in-iframe&gt;');
+
+test(function () {
+    var instance = document.querySelector('element-in-iframe');
+
+    assert_true(instance instanceof HTMLElement);
+    assert_false(instance instanceof ElementInIFrame);
+
+}, 'HTML parser must not instantiate a custom element defined inside an frame in frame element\'s owner document');
+
+document.body.removeChild(iframe);
+
+var windowlessDocument = document.implementation.createHTMLDocument();
+windowlessDocument.open();
+windowlessDocument.write('&lt;my-custom-element&gt;&lt;/my-custom-element&gt;');
+windowlessDocument.close();
+
+test(function () {
+    var instance = windowlessDocument.querySelector('my-custom-element');
+
+    assert_true(instance instanceof HTMLElement);
+    assert_false(instance instanceof MyCustomElement);
+
+}, 'HTML parser must use the registry of window.document in a document created by document.implementation.createHTMLDocument()');
+
+windowlessDocument = document.implementation.createDocument ('http://www.w3.org/1999/xhtml', 'html', null);
+windowlessDocument.documentElement.innerHTML = '&lt;my-custom-element&gt;&lt;/my-custom-element&gt;';
+
+test(function () {
+    var instance = windowlessDocument.querySelector('my-custom-element');
+
+    assert_true(instance instanceof HTMLElement);
+    assert_false(instance instanceof MyCustomElement);
+
+}, 'HTML parser must use the registry of window.document in a document created by document.implementation.createXHTMLDocument()');
+
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (197527 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-03-04 00:26:23 UTC (rev 197527)
+++ trunk/Source/WebCore/ChangeLog        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2016-03-03  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        Disallow custom elements inside a window-less documents
+        https://bugs.webkit.org/show_bug.cgi?id=154944
+        &lt;rdar://problem/24944875&gt;
+
+        Reviewed by Antti Koivisto.
+
+        Disallow custom elements inside a window-less documents such as the shared inert document of template elements
+        and the ones created by DOMImplementation.createDocument and DOMImplementation.createHTMLDocument.
+
+        Throw NotSupportedError in defineCustomElement when it's called in such a document as discussed in:
+        https://github.com/w3c/webcomponents/issues/369
+
+        Tests: fast/custom-elements/parser/parser-constructs-custom-element-in-document-write.html
+               fast/custom-elements/parser/parser-uses-registry-of-owner-document.html
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::throwNotSupportedError): Added.
+        * bindings/js/JSDOMBinding.h:
+        * bindings/js/JSDocumentCustom.cpp:
+        (WebCore::JSDocument::defineCustomElement): Throw NotSupportedError when the context object's document doesn't
+        have a browsing context (i.e. window-less).
+        * html/parser/HTMLDocumentParser.cpp:
+        (WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder): Replaced a FIXME with an assertion now that we
+        disallow instantiation of custom elements inside a template element.
+
</ins><span class="cx"> 2016-03-03  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Move SPI to CFNetworkSPI.h
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (197527 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2016-03-04 00:26:23 UTC (rev 197527)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -635,6 +635,13 @@
</span><span class="cx">     context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, makeString(&quot;Deprecated attempt to set property '&quot;, attributeName, &quot;' on a non-&quot;, interfaceName, &quot; object.&quot;));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void throwNotSupportedError(JSC::ExecState&amp; state, const char* message)
+{
+    ASSERT(!state.hadException());
+    String messageString(message);
+    state.vm().throwException(&amp;state, createDOMException(&amp;state, NOT_SUPPORTED_ERR, &amp;messageString));
+}
+
</ins><span class="cx"> JSC::EncodedJSValue throwArgumentMustBeEnumError(JSC::ExecState&amp; state, unsigned argumentIndex, const char* argumentName, const char* functionInterfaceName, const char* functionName, const char* expectedValues)
</span><span class="cx"> {
</span><span class="cx">     StringBuilder builder;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (197527 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2016-03-04 00:26:23 UTC (rev 197527)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -84,6 +84,7 @@
</span><span class="cx"> WEBCORE_EXPORT JSC::EncodedJSValue reportDeprecatedGetterError(JSC::ExecState&amp;, const char* interfaceName, const char* attributeName);
</span><span class="cx"> WEBCORE_EXPORT void reportDeprecatedSetterError(JSC::ExecState&amp;, const char* interfaceName, const char* attributeName);
</span><span class="cx"> 
</span><ins>+void throwNotSupportedError(JSC::ExecState&amp;, const char* message);
</ins><span class="cx"> void throwArrayElementTypeError(JSC::ExecState&amp;);
</span><span class="cx"> void throwAttributeTypeError(JSC::ExecState&amp;, const char* interfaceName, const char* attributeName, const char* expectedType);
</span><span class="cx"> WEBCORE_EXPORT void throwSequenceTypeError(JSC::ExecState&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDocumentCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp (197527 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp        2016-03-04 00:26:23 UTC (rev 197527)
+++ trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -147,6 +147,11 @@
</span><span class="cx">         return throwTypeError(&amp;state, &quot;The second argument must be a constructor&quot;);
</span><span class="cx"> 
</span><span class="cx">     Document&amp; document = wrapped();
</span><ins>+    if (!document.domWindow()) {
+        throwNotSupportedError(state, &quot;Cannot define a custom element in a docuemnt without a browsing context&quot;);
+        return jsUndefined();
+    }
+
</ins><span class="cx">     switch (CustomElementDefinitions::checkName(tagName)) {
</span><span class="cx">     case CustomElementDefinitions::NameStatus::Valid:
</span><span class="cx">         break;
</span><span class="lines">@@ -161,10 +166,7 @@
</span><span class="cx">     QualifiedName name(nullAtom, tagName, HTMLNames::xhtmlNamespaceURI);
</span><span class="cx">     auto&amp; definitions = document.ensureCustomElementDefinitions();
</span><span class="cx">     if (definitions.findInterface(tagName)) {
</span><del>-        ExceptionCodeWithMessage ec;
-        ec.code = NOT_SUPPORTED_ERR;
-        ec.message = &quot;Cannot define multiple custom elements with the same tag name&quot;;
-        setDOMException(&amp;state, ec);
</del><ins>+        throwNotSupportedError(state, &quot;Cannot define multiple custom elements with the same tag name&quot;);
</ins><span class="cx">         return jsUndefined();
</span><span class="cx">     }
</span><span class="cx">     definitions.defineElement(name, JSCustomElementInterface::create(object, globalObject()));
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLDocumentParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp (197527 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp        2016-03-04 00:26:23 UTC (rev 197527)
+++ trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -196,7 +196,7 @@
</span><span class="cx"> 
</span><span class="cx">         RefPtr&lt;Element&gt; newElement = constructionData-&gt;interface-&gt;constructElement(constructionData-&gt;name, JSCustomElementInterface::ShouldClearException::Clear);
</span><span class="cx">         if (!newElement) {
</span><del>-            // FIXME: This call to docuemnt() is wrong for elements inside a template element.
</del><ins>+            ASSERT(!m_treeBuilder-&gt;isParsingTemplateContents());
</ins><span class="cx">             newElement = HTMLUnknownElement::create(QualifiedName(nullAtom, constructionData-&gt;name, xhtmlNamespaceURI), *document());
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLTreeBuilderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLTreeBuilder.h (197527 => 197528)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLTreeBuilder.h        2016-03-04 00:26:23 UTC (rev 197527)
+++ trunk/Source/WebCore/html/parser/HTMLTreeBuilder.h        2016-03-04 00:28:44 UTC (rev 197528)
</span><span class="lines">@@ -61,6 +61,7 @@
</span><span class="cx"> 
</span><span class="cx">     void constructTree(AtomicHTMLToken&amp;);
</span><span class="cx"> 
</span><ins>+    bool isParsingTemplateContents() const;
</ins><span class="cx">     bool hasParserBlockingScriptWork() const;
</span><span class="cx"> 
</span><span class="cx">     // Must be called to take the parser-blocking script before calling the parser again.
</span><span class="lines">@@ -107,7 +108,6 @@
</span><span class="cx">         AfterAfterFrameset,
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    bool isParsingTemplateContents() const;
</del><span class="cx">     bool isParsingFragmentOrTemplateContents() const;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(TELEPHONE_NUMBER_DETECTION) &amp;&amp; PLATFORM(IOS)
</span></span></pre>
</div>
</div>

</body>
</html>