<!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>[210284] 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/210284">210284</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2017-01-04 13:26:05 -0800 (Wed, 04 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Assertion hit on redfin.com: ASSERTION FAILED: collection-&gt;length() &gt; 1
https://bugs.webkit.org/show_bug.cgi?id=166687
&lt;rdar://problem/29865854&gt;

Reviewed by Darin Adler.

Source/WebCore:

We were mistakenly calling Document::addWindowNamedItem() / Document::removeWindowNamedItem()
for elements in Shadow DOMs. As a result, the windowNamedItem DocumentOrderedMap would
contain elements in shadow DOMs. This would cause the assertion to be hit in window's
named property getter because of the length mismatch between the windowNamedItem
DocumentOrderedMap and the WindowNameCollection.

Tests: fast/shadow-dom/document-named-property.html
       fast/shadow-dom/window-named-property.html

* dom/Element.cpp:
(WebCore::Element::updateNameForDocument):
(WebCore::Element::updateIdForDocument):
* html/HTMLImageElement.cpp:
(WebCore::HTMLImageElement::parseAttribute):
* html/HTMLObjectElement.cpp:
(WebCore::HTMLObjectElement::updateDocNamedItem):

LayoutTests:

Add layout test coverage.

* fast/shadow-dom/document-named-property-expected.txt: Added.
* fast/shadow-dom/document-named-property.html: Added.
* fast/shadow-dom/window-named-property-expected.txt: Added.
* fast/shadow-dom/window-named-property.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomElementcpp">trunk/Source/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLImageElementcpp">trunk/Source/WebCore/html/HTMLImageElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLObjectElementcpp">trunk/Source/WebCore/html/HTMLObjectElement.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastshadowdomdocumentnamedpropertyexpectedtxt">trunk/LayoutTests/fast/shadow-dom/document-named-property-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastshadowdomdocumentnamedpropertyhtml">trunk/LayoutTests/fast/shadow-dom/document-named-property.html</a></li>
<li><a href="#trunkLayoutTestsfastshadowdomwindownamedpropertyexpectedtxt">trunk/LayoutTests/fast/shadow-dom/window-named-property-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastshadowdomwindownamedpropertyhtml">trunk/LayoutTests/fast/shadow-dom/window-named-property.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (210283 => 210284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-01-04 20:57:54 UTC (rev 210283)
+++ trunk/LayoutTests/ChangeLog        2017-01-04 21:26:05 UTC (rev 210284)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-01-04  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Assertion hit on redfin.com: ASSERTION FAILED: collection-&gt;length() &gt; 1
+        https://bugs.webkit.org/show_bug.cgi?id=166687
+        &lt;rdar://problem/29865854&gt;
+
+        Reviewed by Darin Adler.
+
+        Add layout test coverage.
+
+        * fast/shadow-dom/document-named-property-expected.txt: Added.
+        * fast/shadow-dom/document-named-property.html: Added.
+        * fast/shadow-dom/window-named-property-expected.txt: Added.
+        * fast/shadow-dom/window-named-property.html: Added.
+
</ins><span class="cx"> 2017-01-04  Manuel Rego Casasnovas  &lt;rego@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Two editing tests are passing but marked as failure
</span></span></pre></div>
<a id="trunkLayoutTestsfastshadowdomdocumentnamedpropertyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shadow-dom/document-named-property-expected.txt (0 => 210284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shadow-dom/document-named-property-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/document-named-property-expected.txt        2017-01-04 21:26:05 UTC (rev 210284)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+
+
+
+
+
+PASS Document's named property getter should not return elements in shadow DOMs by id 
+PASS Document's named property getter should not return elements in shadow DOMs by id (duplicate id) 
+PASS Document's named property getter should not return elements in shadow DOMs by id (id attribute update) 
+PASS Document's named property getter should not return elements in shadow DOMs by id (duplicate id attribute update) 
+PASS Document's named property getter should not return elements in shadow DOMs by id (image name change) 
+PASS Document's named property getter should not return elements in shadow DOMs by id (image name change with duplicate id) 
+PASS Document's named property getter should not return elements in shadow DOMs by id (object children change) 
+PASS Document's named property getter should not return elements in shadow DOMs by id (object children change with duplicate id) 
+PASS Document's named property getter should not return elements in shadow DOMs by name 
+PASS Document's named property getter should not return elements in shadow DOMs by name (duplicate name) 
+PASS Document's named property getter should not return elements in shadow DOMs by name (name attribute update) 
+PASS Document's named property getter should not return elements in shadow DOMs by name (duplicate name attribute update) 
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshadowdomdocumentnamedpropertyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shadow-dom/document-named-property.html (0 => 210284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shadow-dom/document-named-property.html                                (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/document-named-property.html        2017-01-04 21:26:05 UTC (rev 210284)
</span><span class="lines">@@ -0,0 +1,187 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+&lt;script src='../../resources/testharness.js'&gt;&lt;/script&gt;
+&lt;script src='../../resources/testharnessreport.js'&gt;&lt;/script&gt;
+&lt;div id=&quot;container&quot;&gt;&lt;/div&gt;
+&lt;script&gt;
+var container = document.getElementById('container');
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;img id=&quot;foo&quot; name=&quot;test2&quot;&gt;&lt;/img&gt;';
+    container.appendChild(header);
+
+    assert_equals(document.foo, undefined);
+}, &quot;Document's named property getter should not return elements in shadow DOMs by id&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;img id=&quot;foo1&quot; name=&quot;test2&quot;&gt;&lt;/img&gt;';
+    container.appendChild(header);
+
+    var img = document.createElement(&quot;img&quot;);
+    img.id = 'foo1';
+    img.name = 'test1'
+    container.appendChild(img);
+
+    assert_equals(document.foo1, img);
+    assert_equals(shadowRoot.firstChild.id, 'foo1');
+    shadowRoot.removeChild(shadowRoot.firstChild);
+    assert_equals(document.foo1, img);
+}, &quot;Document's named property getter should not return elements in shadow DOMs by id (duplicate id)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;img name=&quot;test2&quot;&gt;&lt;/img&gt;';
+    container.appendChild(header);
+
+    assert_equals(document.foo2, undefined);
+    shadowRoot.firstChild.id = 'foo2';
+    assert_equals(document.foo2, undefined);
+
+}, &quot;Document's named property getter should not return elements in shadow DOMs by id (id attribute update)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;img name=&quot;test2&quot;&gt;&lt;/img&gt;';
+    container.appendChild(header);
+
+    var img = document.createElement(&quot;img&quot;);
+    img.id = 'foo3';
+    img.setAttribute('name', 'test1');
+    container.appendChild(img);
+
+    assert_equals(document.foo3, img);
+    shadowRoot.firstChild.id = 'foo3';
+    assert_equals(document.foo3, img);
+
+    shadowRoot.firstChild.id = 'other';
+    assert_equals(document.foo3, img);
+}, &quot;Document's named property getter should not return elements in shadow DOMs by id (duplicate id attribute update)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;img&gt;&lt;/img&gt;';
+    container.appendChild(header);
+
+    assert_equals(document.foo4, undefined);
+    shadowRoot.firstChild.id = 'foo4';
+    assert_equals(document.foo4, undefined);
+    shadowRoot.firstChild.setAttribute('name', 'test3');
+    assert_equals(document.foo4, undefined);
+
+}, &quot;Document's named property getter should not return elements in shadow DOMs by id (image name change)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;img&gt;&lt;/img&gt;';
+    container.appendChild(header);
+
+    var img = document.createElement(&quot;img&quot;);
+    img.id = 'foo5';
+    img.setAttribute('name', 'test1');
+    container.appendChild(img);
+
+    assert_equals(document.foo5, img);
+    shadowRoot.firstChild.id = 'foo5';
+    assert_equals(document.foo5, img);
+    shadowRoot.firstChild.setAttribute('name', 'test3');
+    assert_equals(document.foo5, img);
+
+    shadowRoot.firstChild.removeAttribute('name');
+    assert_equals(document.foo5, img);
+}, &quot;Document's named property getter should not return elements in shadow DOMs by id (image name change with duplicate id)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;object id=&quot;foo6&quot;&gt;text&lt;/object&gt;';
+    container.appendChild(header);
+
+    assert_equals(document.foo6, undefined);
+    assert_equals(shadowRoot.firstChild.firstChild.data, &quot;text&quot;);
+    shadowRoot.firstChild.removeChild(shadowRoot.firstChild.firstChild);
+    assert_equals(document.foo6, undefined);
+}, &quot;Document's named property getter should not return elements in shadow DOMs by id (object children change)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;object id=&quot;foo7&quot;&gt;text&lt;/object&gt;';
+    container.appendChild(header);
+
+    var object = document.createElement(&quot;object&quot;);
+    object.id = 'foo7';
+    container.appendChild(object);
+
+    assert_equals(document.foo7, object);
+    assert_equals(shadowRoot.firstChild.firstChild.data, &quot;text&quot;);
+    shadowRoot.firstChild.removeChild(shadowRoot.firstChild.firstChild);
+    assert_equals(document.foo7, object);
+    shadowRoot.firstChild.appendChild(document.createElement(&quot;a&quot;));
+    assert_equals(document.foo7, object);
+}, &quot;Document's named property getter should not return elements in shadow DOMs by id (object children change with duplicate id)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;img name=&quot;bar&quot;&gt;&lt;/img&gt;';
+    document.body.appendChild(header);
+
+    assert_equals(document.bar, undefined);
+}, &quot;Document's named property getter should not return elements in shadow DOMs by name&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;img name=&quot;bar1&quot;&gt;&lt;/img&gt;';
+    document.body.appendChild(header);
+
+    var img = document.createElement(&quot;img&quot;);
+    img.setAttribute('name', 'bar1');
+    container.appendChild(img);
+
+    assert_equals(document.bar1, img);
+    assert_equals(shadowRoot.firstChild.getAttribute('name'), 'bar1');
+    shadowRoot.removeChild(shadowRoot.firstChild);
+    assert_equals(document.bar1, img);
+}, &quot;Document's named property getter should not return elements in shadow DOMs by name (duplicate name)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;img&gt;&lt;/img&gt;';
+    document.body.appendChild(header);
+
+    assert_equals(document.bar2, undefined);
+    shadowRoot.firstChild.setAttribute('name', 'bar2');
+    assert_equals(document.bar2, undefined);
+}, &quot;Document's named property getter should not return elements in shadow DOMs by name (name attribute update)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;img&gt;&lt;/img&gt;';
+    document.body.appendChild(header);
+
+    var img = document.createElement(&quot;img&quot;);
+    img.setAttribute('name', 'bar3');
+    container.appendChild(img);
+
+    assert_equals(document.bar3, img);
+    shadowRoot.firstChild.setAttribute('name', 'bar3');
+    assert_equals(document.bar3, img);
+
+    shadowRoot.firstChild.setAttribute('name', 'other');
+    assert_equals(document.bar3, img);
+}, &quot;Document's named property getter should not return elements in shadow DOMs by name (duplicate name attribute update)&quot;);
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshadowdomwindownamedpropertyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shadow-dom/window-named-property-expected.txt (0 => 210284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shadow-dom/window-named-property-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/window-named-property-expected.txt        2017-01-04 21:26:05 UTC (rev 210284)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+
+PASS Window's named property getter should not return elements in shadow DOMs by id 
+PASS Window's named property getter should not return elements in shadow DOMs by id (duplicate id) 
+PASS Window's named property getter should not return elements in shadow DOMs by id (id attribute update) 
+PASS Window's named property getter should not return elements in shadow DOMs by id (duplicate id attribute update) 
+PASS Window's named property getter should not return elements in shadow DOMs by name 
+PASS Window's named property getter should not return elements in shadow DOMs by name (duplicate name) 
+PASS Window's named property getter should not return elements in shadow DOMs by name (name attribute update) 
+PASS Window's named property getter should not return elements in shadow DOMs by name (duplicate name attribute update) 
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshadowdomwindownamedpropertyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shadow-dom/window-named-property.html (0 => 210284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shadow-dom/window-named-property.html                                (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/window-named-property.html        2017-01-04 21:26:05 UTC (rev 210284)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+&lt;script src='../../resources/testharness.js'&gt;&lt;/script&gt;
+&lt;script src='../../resources/testharnessreport.js'&gt;&lt;/script&gt;
+&lt;div id=&quot;container&quot;&gt;&lt;/div&gt;
+&lt;script&gt;
+var container = document.getElementById('container');
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;span id=&quot;foo&quot;&gt;&lt;/span&gt;';
+    container.appendChild(header);
+
+    assert_equals(window.foo, undefined);
+}, &quot;Window's named property getter should not return elements in shadow DOMs by id&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;span id=&quot;foo1&quot;&gt;&lt;/span&gt;';
+    container.appendChild(header);
+
+    var span = document.createElement(&quot;span&quot;);
+    span.id = 'foo1';
+    container.appendChild(span);
+
+    assert_equals(window.foo1, span);
+    assert_equals(shadowRoot.firstChild.id, 'foo1');
+    shadowRoot.removeChild(shadowRoot.firstChild);
+    assert_equals(window.foo1, span);
+}, &quot;Window's named property getter should not return elements in shadow DOMs by id (duplicate id)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;span&gt;&lt;/span&gt;';
+    container.appendChild(header);
+
+    assert_equals(window.foo2, undefined);
+    shadowRoot.firstChild.id = 'foo2';
+    assert_equals(window.foo2, undefined);
+}, &quot;Window's named property getter should not return elements in shadow DOMs by id (id attribute update)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;span&gt;&lt;/span&gt;';
+    container.appendChild(header);
+
+    var span = document.createElement(&quot;span&quot;);
+    span.id = 'foo3';
+    container.appendChild(span);
+
+    assert_equals(window.foo3, span);
+    shadowRoot.firstChild.id = 'foo3';
+    assert_equals(window.foo3, span);
+
+    shadowRoot.firstChild.id = 'other';
+    assert_equals(window.foo3, span);
+}, &quot;Window's named property getter should not return elements in shadow DOMs by id (duplicate id attribute update)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;form name=&quot;bar&quot;&gt;&lt;/form&gt;';
+    document.body.appendChild(header);
+
+    assert_equals(window.bar, undefined);
+}, &quot;Window's named property getter should not return elements in shadow DOMs by name&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;form name=&quot;bar1&quot;&gt;&lt;/form&gt;';
+    document.body.appendChild(header);
+
+    var form = document.createElement(&quot;form&quot;);
+    form.setAttribute('name', 'bar1');
+    container.appendChild(form);
+
+    assert_equals(window.bar1, form);
+    assert_equals(shadowRoot.firstChild.getAttribute('name'), 'bar1');
+    shadowRoot.removeChild(shadowRoot.firstChild);
+    assert_equals(window.bar1, form);
+}, &quot;Window's named property getter should not return elements in shadow DOMs by name (duplicate name)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;form&gt;&lt;/form&gt;';
+    document.body.appendChild(header);
+
+    assert_equals(window.bar2, undefined);
+    shadowRoot.firstChild.setAttribute('name', 'bar2');
+    assert_equals(window.bar2, undefined);
+}, &quot;Window's named property getter should not return elements in shadow DOMs by name (name attribute update)&quot;);
+
+test(function () {
+    var header = document.createElement('header');
+    var shadowRoot = header.attachShadow({mode: 'open'});
+    shadowRoot.innerHTML = '&lt;form&gt;&lt;/form&gt;';
+    document.body.appendChild(header);
+
+    var form = document.createElement(&quot;form&quot;);
+    form.setAttribute('name', 'bar3');
+    container.appendChild(form);
+
+    assert_equals(window.bar3, form);
+    shadowRoot.firstChild.setAttribute('name', 'bar3');
+    assert_equals(window.bar3, form);
+
+    shadowRoot.firstChild.setAttribute('name', 'other');
+    assert_equals(window.bar3, form);
+}, &quot;Window's named property getter should not return elements in shadow DOMs by name (duplicate name attribute update)&quot;);
+&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 (210283 => 210284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-01-04 20:57:54 UTC (rev 210283)
+++ trunk/Source/WebCore/ChangeLog        2017-01-04 21:26:05 UTC (rev 210284)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2017-01-04  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Assertion hit on redfin.com: ASSERTION FAILED: collection-&gt;length() &gt; 1
+        https://bugs.webkit.org/show_bug.cgi?id=166687
+        &lt;rdar://problem/29865854&gt;
+
+        Reviewed by Darin Adler.
+
+        We were mistakenly calling Document::addWindowNamedItem() / Document::removeWindowNamedItem()
+        for elements in Shadow DOMs. As a result, the windowNamedItem DocumentOrderedMap would
+        contain elements in shadow DOMs. This would cause the assertion to be hit in window's
+        named property getter because of the length mismatch between the windowNamedItem
+        DocumentOrderedMap and the WindowNameCollection.
+
+        Tests: fast/shadow-dom/document-named-property.html
+               fast/shadow-dom/window-named-property.html
+
+        * dom/Element.cpp:
+        (WebCore::Element::updateNameForDocument):
+        (WebCore::Element::updateIdForDocument):
+        * html/HTMLImageElement.cpp:
+        (WebCore::HTMLImageElement::parseAttribute):
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::updateDocNamedItem):
+
</ins><span class="cx"> 2017-01-04  John Wilander  &lt;wilander@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Validate the BCP47-ness of the language string passed to TrackBase::setLanguage()
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.cpp (210283 => 210284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.cpp        2017-01-04 20:57:54 UTC (rev 210283)
+++ trunk/Source/WebCore/dom/Element.cpp        2017-01-04 21:26:05 UTC (rev 210284)
</span><span class="lines">@@ -3222,6 +3222,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(oldName != newName);
</span><span class="cx"> 
</span><ins>+    if (isInShadowTree())
+        return;
+
</ins><span class="cx">     if (WindowNameCollection::elementMatchesIfNameAttributeMatch(*this)) {
</span><span class="cx">         const AtomicString&amp; id = WindowNameCollection::elementMatchesIfIdAttributeMatch(*this) ? getIdAttribute() : nullAtom;
</span><span class="cx">         if (!oldName.isEmpty() &amp;&amp; oldName != id)
</span><span class="lines">@@ -3272,6 +3275,9 @@
</span><span class="cx">     ASSERT(inDocument());
</span><span class="cx">     ASSERT(oldId != newId);
</span><span class="cx"> 
</span><ins>+    if (isInShadowTree())
+        return;
+
</ins><span class="cx">     if (WindowNameCollection::elementMatchesIfIdAttributeMatch(*this)) {
</span><span class="cx">         const AtomicString&amp; name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute &amp;&amp; WindowNameCollection::elementMatchesIfNameAttributeMatch(*this) ? getNameAttribute() : nullAtom;
</span><span class="cx">         if (!oldId.isEmpty() &amp;&amp; oldId != name)
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLImageElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLImageElement.cpp (210283 => 210284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLImageElement.cpp        2017-01-04 20:57:54 UTC (rev 210283)
+++ trunk/Source/WebCore/html/HTMLImageElement.cpp        2017-01-04 21:26:05 UTC (rev 210284)
</span><span class="lines">@@ -226,7 +226,7 @@
</span><span class="cx">     } else {
</span><span class="cx">         if (name == nameAttr) {
</span><span class="cx">             bool willHaveName = !value.isNull();
</span><del>-            if (m_hadNameBeforeAttributeChanged != willHaveName &amp;&amp; inDocument() &amp;&amp; is&lt;HTMLDocument&gt;(document())) {
</del><ins>+            if (m_hadNameBeforeAttributeChanged != willHaveName &amp;&amp; inDocument() &amp;&amp; !isInShadowTree() &amp;&amp; is&lt;HTMLDocument&gt;(document())) {
</ins><span class="cx">                 HTMLDocument&amp; document = downcast&lt;HTMLDocument&gt;(this-&gt;document());
</span><span class="cx">                 const AtomicString&amp; id = getIdAttribute();
</span><span class="cx">                 if (!id.isEmpty() &amp;&amp; id != getNameAttribute()) {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLObjectElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLObjectElement.cpp (210283 => 210284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLObjectElement.cpp        2017-01-04 20:57:54 UTC (rev 210283)
+++ trunk/Source/WebCore/html/HTMLObjectElement.cpp        2017-01-04 21:26:05 UTC (rev 210284)
</span><span class="lines">@@ -445,7 +445,7 @@
</span><span class="cx">             isNamedItem = false;
</span><span class="cx">         child = child-&gt;nextSibling();
</span><span class="cx">     }
</span><del>-    if (isNamedItem != wasNamedItem &amp;&amp; inDocument() &amp;&amp; is&lt;HTMLDocument&gt;(document())) {
</del><ins>+    if (isNamedItem != wasNamedItem &amp;&amp; inDocument() &amp;&amp; !isInShadowTree() &amp;&amp; is&lt;HTMLDocument&gt;(document())) {
</ins><span class="cx">         HTMLDocument&amp; document = downcast&lt;HTMLDocument&gt;(this-&gt;document());
</span><span class="cx"> 
</span><span class="cx">         const AtomicString&amp; id = getIdAttribute();
</span></span></pre>
</div>
</div>

</body>
</html>