Title: [190323] trunk
Revision
190323
Author
rn...@webkit.org
Date
2015-09-29 13:22:18 -0700 (Tue, 29 Sep 2015)

Log Message

Update style/layout when a slot is added or removed
https://bugs.webkit.org/show_bug.cgi?id=149593

Reviewed by Antti Koivisto.

Source/WebCore:

Fixed the bug by forcing the render tree reconstruction on the shadow host when a slot is inserted or removed.
We should optimize these reconstructions by only triggering them on the affected slot elements in the future.

Also fixed a bug that we were not invalidating the slot assignments when a default slot is introduced dynamically
after the slot assignment algorithm had run.

Test (existing): fast/shadow-dom/shadow-layout-after-slot-changes.html

* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::addSlotElementByName): Passes in ShadowRoot.
(WebCore::ShadowRoot::removeSlotElementByName): Ditto.
* dom/SlotAssignment.cpp:
(WebCore::SlotAssignment::addSlotElementByName): Call setNeedsStyleRecalc.
(WebCore::SlotAssignment::removeSlotElementByName): Call setNeedsStyleRecalc if the host is still alive since this
function can be called while the host is being destructed in which case shadowRoot.host() would be nullptr.
* dom/SlotAssignment.h:

LayoutTests:

Removed failing test expectations from fast/shadow-dom/shadow-layout-after-slot-changes.html

Also added an explicit test case for when a default slot is introduced dynamically after
calling getDistributedNodes() once, thereby forcing the slot assignments.

* fast/shadow-dom/HTMLSlotElement-interface-expected.txt:
* fast/shadow-dom/HTMLSlotElement-interface.html:
* fast/shadow-dom/shadow-layout-after-slot-changes.html:
* platform/mac/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (190322 => 190323)


--- trunk/LayoutTests/ChangeLog	2015-09-29 19:20:36 UTC (rev 190322)
+++ trunk/LayoutTests/ChangeLog	2015-09-29 20:22:18 UTC (rev 190323)
@@ -1,3 +1,20 @@
+2015-09-29  Ryosuke Niwa  <rn...@webkit.org>
+
+        Update style/layout when a slot is added or removed
+        https://bugs.webkit.org/show_bug.cgi?id=149593
+
+        Reviewed by Antti Koivisto.
+
+        Removed failing test expectations from fast/shadow-dom/shadow-layout-after-slot-changes.html
+
+        Also added an explicit test case for when a default slot is introduced dynamically after
+        calling getDistributedNodes() once, thereby forcing the slot assignments.
+
+        * fast/shadow-dom/HTMLSlotElement-interface-expected.txt:
+        * fast/shadow-dom/HTMLSlotElement-interface.html:
+        * fast/shadow-dom/shadow-layout-after-slot-changes.html:
+        * platform/mac/TestExpectations:
+
 2015-09-29  Ryan Haddad  <ryanhad...@apple.com>
 
         Update test expectations to mark quicklook/pages.html as crashing

Modified: trunk/LayoutTests/fast/shadow-dom/HTMLSlotElement-interface-expected.txt (190322 => 190323)


--- trunk/LayoutTests/fast/shadow-dom/HTMLSlotElement-interface-expected.txt	2015-09-29 19:20:36 UTC (rev 190322)
+++ trunk/LayoutTests/fast/shadow-dom/HTMLSlotElement-interface-expected.txt	2015-09-29 20:22:18 UTC (rev 190323)
@@ -3,5 +3,6 @@
 PASS "name" attribute on HTMLSlotElement must reflect "name" attribute 
 PASS getDistributedNodes method on HTMLSlotElement must return the list of distributed nodes 
 PASS getDistributedNodes must update when slot and name attributes are modified 
+PASS getDistributedNodes must update when a default slot is introduced dynamically by a slot rename 
 PASS getDistributedNodes must update when slot elements are inserted or removed 
 

Modified: trunk/LayoutTests/fast/shadow-dom/HTMLSlotElement-interface.html (190322 => 190323)


--- trunk/LayoutTests/fast/shadow-dom/HTMLSlotElement-interface.html	2015-09-29 19:20:36 UTC (rev 190322)
+++ trunk/LayoutTests/fast/shadow-dom/HTMLSlotElement-interface.html	2015-09-29 20:22:18 UTC (rev 190323)
@@ -92,6 +92,23 @@
 
 test(function () {
     var shadowHost = document.createElement('div');
+    var child = document.createElement('span');
+    shadowHost.appendChild(child);
+
+    var shadowRoot = shadowHost.attachShadow({mode: 'open'});
+    var slotElement = document.createElement('slot');
+    slotElement.name = 'foo';
+    shadowRoot.appendChild(slotElement);
+
+    assert_array_equals(slotElement.getDistributedNodes(), [], 'getDistributedNodes must be empty when there are no matching elements for the slot name');
+
+    slotElement.name = null;
+    assert_array_equals(slotElement.getDistributedNodes(), [child], 'getDistributedNodes must be empty when there are no matching elements for the slot name');
+
+}, 'getDistributedNodes must update when a default slot is introduced dynamically by a slot rename');
+
+test(function () {
+    var shadowHost = document.createElement('div');
     var p = document.createElement('p');
     var text = document.createTextNode('');
     var b = document.createElement('b');

Modified: trunk/LayoutTests/platform/mac/TestExpectations (190322 => 190323)


--- trunk/LayoutTests/platform/mac/TestExpectations	2015-09-29 19:20:36 UTC (rev 190322)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2015-09-29 20:22:18 UTC (rev 190323)
@@ -1330,7 +1330,6 @@
 webkit.org/b/149440 fast/shadow-dom/css-scoping-shadow-host-functional-rule.html [ ImageOnlyFailure ]
 webkit.org/b/149441 fast/shadow-dom/css-scoping-shadow-slotted-rule.html [ ImageOnlyFailure ]
 webkit.org/b/149441 fast/shadow-dom/css-scoping-shadow-slot-display-override.html [ ImageOnlyFailure ]
-webkit.org/b/149593 fast/shadow-dom/shadow-layout-after-slot-changes.html [ ImageOnlyFailure ]
 
 webkit.org/b/149510 accessibility/mac/aria-expanded-notifications.html [ Pass Failure ]
 

Modified: trunk/Source/WebCore/ChangeLog (190322 => 190323)


--- trunk/Source/WebCore/ChangeLog	2015-09-29 19:20:36 UTC (rev 190322)
+++ trunk/Source/WebCore/ChangeLog	2015-09-29 20:22:18 UTC (rev 190323)
@@ -1,3 +1,27 @@
+2015-09-29  Ryosuke Niwa  <rn...@webkit.org>
+
+        Update style/layout when a slot is added or removed
+        https://bugs.webkit.org/show_bug.cgi?id=149593
+
+        Reviewed by Antti Koivisto.
+
+        Fixed the bug by forcing the render tree reconstruction on the shadow host when a slot is inserted or removed.
+        We should optimize these reconstructions by only triggering them on the affected slot elements in the future.
+
+        Also fixed a bug that we were not invalidating the slot assignments when a default slot is introduced dynamically
+        after the slot assignment algorithm had run.
+
+        Test (existing): fast/shadow-dom/shadow-layout-after-slot-changes.html
+
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::addSlotElementByName): Passes in ShadowRoot.
+        (WebCore::ShadowRoot::removeSlotElementByName): Ditto.
+        * dom/SlotAssignment.cpp:
+        (WebCore::SlotAssignment::addSlotElementByName): Call setNeedsStyleRecalc.
+        (WebCore::SlotAssignment::removeSlotElementByName): Call setNeedsStyleRecalc if the host is still alive since this
+        function can be called while the host is being destructed in which case shadowRoot.host() would be nullptr.
+        * dom/SlotAssignment.h:
+
 2015-09-29  Youenn Fablet  <youenn.fab...@crf.canon.fr>
 
         Improve binding of JSBuiltinConstructor classes

Modified: trunk/Source/WebCore/dom/ShadowRoot.cpp (190322 => 190323)


--- trunk/Source/WebCore/dom/ShadowRoot.cpp	2015-09-29 19:20:36 UTC (rev 190322)
+++ trunk/Source/WebCore/dom/ShadowRoot.cpp	2015-09-29 20:22:18 UTC (rev 190323)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -189,12 +190,12 @@
     if (!m_slotAssignments)
         m_slotAssignments = std::make_unique<SlotAssignment>();
 
-    return m_slotAssignments->addSlotElementByName(name, slot);
+    return m_slotAssignments->addSlotElementByName(name, slot, *this);
 }
 
 void ShadowRoot::removeSlotElementByName(const AtomicString& name, HTMLSlotElement& slot)
 {
-    return m_slotAssignments->removeSlotElementByName(name, slot);
+    return m_slotAssignments->removeSlotElementByName(name, slot, *this);
 }
 
 void ShadowRoot::invalidateSlotAssignments()

Modified: trunk/Source/WebCore/dom/SlotAssignment.cpp (190322 => 190323)


--- trunk/Source/WebCore/dom/SlotAssignment.cpp	2015-09-29 19:20:36 UTC (rev 190322)
+++ trunk/Source/WebCore/dom/SlotAssignment.cpp	2015-09-29 20:22:18 UTC (rev 190323)
@@ -51,16 +51,22 @@
     return findFirstSlotElement(*it->value, shadowRoot);
 }
 
-void SlotAssignment::addSlotElementByName(const AtomicString& name, HTMLSlotElement& slotElement)
+void SlotAssignment::addSlotElementByName(const AtomicString& name, HTMLSlotElement& slotElement, ShadowRoot& shadowRoot)
 {
 #ifndef NDEBUG
     ASSERT(!m_slotElementsForConsistencyCheck.contains(&slotElement));
     m_slotElementsForConsistencyCheck.add(&slotElement);
 #endif
 
-    auto addResult = m_slots.add(treatNullAsEmpty(name), std::unique_ptr<SlotInfo>());
+    // FIXME: We should be able to do a targeted reconstruction.
+    shadowRoot.host()->setNeedsStyleRecalc(ReconstructRenderTree);
+
+    const AtomicString& key = treatNullAsEmpty(name);
+    auto addResult = m_slots.add(key, std::unique_ptr<SlotInfo>());
     if (addResult.isNewEntry) {
         addResult.iterator->value = std::make_unique<SlotInfo>(slotElement);
+        if (key == emptyAtom) // Because assignSlots doesn't collect nodes assgined to the default slot as an optimzation.
+            m_slotAssignmentsIsValid = false;
         return;
     }
 
@@ -77,13 +83,16 @@
     slotInfo.elementCount++;
 }
 
-void SlotAssignment::removeSlotElementByName(const AtomicString& name, HTMLSlotElement& slotElement)
+void SlotAssignment::removeSlotElementByName(const AtomicString& name, HTMLSlotElement& slotElement, ShadowRoot& shadowRoot)
 {
 #ifndef NDEBUG
     ASSERT(m_slotElementsForConsistencyCheck.contains(&slotElement));
     m_slotElementsForConsistencyCheck.remove(&slotElement);
 #endif
 
+    if (auto* host = shadowRoot.host()) // FIXME: We should be able to do a targeted reconstruction.
+        host->setNeedsStyleRecalc(ReconstructRenderTree);
+
     auto it = m_slots.find(treatNullAsEmpty(name));
     RELEASE_ASSERT(it != m_slots.end());
 

Modified: trunk/Source/WebCore/dom/SlotAssignment.h (190322 => 190323)


--- trunk/Source/WebCore/dom/SlotAssignment.h	2015-09-29 19:20:36 UTC (rev 190322)
+++ trunk/Source/WebCore/dom/SlotAssignment.h	2015-09-29 20:22:18 UTC (rev 190323)
@@ -47,8 +47,8 @@
 
     HTMLSlotElement* findAssignedSlot(const Node&, ShadowRoot&);
 
-    void addSlotElementByName(const AtomicString&, HTMLSlotElement&);
-    void removeSlotElementByName(const AtomicString&, HTMLSlotElement&);
+    void addSlotElementByName(const AtomicString&, HTMLSlotElement&, ShadowRoot&);
+    void removeSlotElementByName(const AtomicString&, HTMLSlotElement&, ShadowRoot&);
 
     const Vector<Node*>* assignedNodesForSlot(const HTMLSlotElement&, ShadowRoot&);
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to