Changeset 223810 in webkit
- Timestamp:
- Oct 21, 2017 1:15:10 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r223809 r223810 1 2017-10-21 Antti Koivisto <antti@apple.com> 2 3 Support ::before/::after pseudo elements with display:contents 4 https://bugs.webkit.org/show_bug.cgi?id=178584 5 6 Reviewed by Ryosuke Niwa. 7 8 * TestExpectations: Enable imported/w3c/web-platform-tests/css/css-display-3/display-contents-before-after-002.html 9 1 10 2017-10-20 Joseph Pecoraro <pecoraro@apple.com> 2 11 -
trunk/LayoutTests/TestExpectations
r223748 r223810 1270 1270 webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-table-002-none.html [ ImageOnlyFailure ] 1271 1271 webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-flex-003.html [ ImageOnlyFailure ] 1272 webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-before-after-002.html [ ImageOnlyFailure ]1273 1272 webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-table-001-inline.html [ ImageOnlyFailure ] 1274 1273 webkit.org/b/157477 imported/w3c/web-platform-tests/css/css-display-3/display-contents-dynamic-flex-002-none.html [ ImageOnlyFailure ] -
trunk/Source/WebCore/ChangeLog
r223805 r223810 1 2017-10-21 Antti Koivisto <antti@apple.com> 2 3 Support ::before/::after pseudo elements with display:contents 4 https://bugs.webkit.org/show_bug.cgi?id=178584 5 6 Reviewed by Ryosuke Niwa. 7 8 This is cases like 9 10 ::before { display:contents; content:'foo' } 11 12 * css/StyleResolver.cpp: 13 (WebCore::StyleResolver::adjustDisplayContentsStyle): Added. 14 15 Allow display:contents on pseudo elements. 16 Factor into function. 17 18 (WebCore::StyleResolver::adjustRenderStyle): 19 * dom/PseudoElement.h: 20 21 Add a weak vector of content renderers. 22 23 * style/RenderTreePosition.h: 24 (WebCore::RenderTreePosition::moveToLastChild): 25 26 Add a way to set a valid render tree position without a node. 27 28 * style/RenderTreeUpdaterGeneratedContent.cpp: 29 (WebCore::createContentRenderers): 30 31 Take RenderTreePosition. 32 33 (WebCore::updateStyleForContentRenderers): 34 35 Update based on the content renderer vector instead of doing a tree walk. 36 37 (WebCore::removeAndDestroyContentRenderers): 38 39 Helper for destroying content renderers. 40 41 (WebCore::RenderTreeUpdater::GeneratedContent::updatePseudoElement): 42 43 In the normal case create a render tree position for the pseudo element renderer and 44 use RenderTreePosition::moveToLastChild to make it a valid position. (The existing 45 RenderTreePosition interface didn't have way to move to positions in anonymous boxes) 46 47 In the case of a non box generating display:contents pseudo element, use the current 48 render tree position instead. 49 50 Ensure that pseudo element renderers are destroyed before creating the new ones since in 51 display:contents case they are not descendants of the pseudo renderer and don't get cleared 52 automatically. 53 1 54 2017-10-20 Zalan Bujtas <zalan@apple.com> 2 55 -
trunk/Source/WebCore/css/StyleResolver.cpp
r223728 r223810 790 790 } 791 791 792 static void adjustDisplayContentsStyle(RenderStyle& style, const Element* element) 793 { 794 bool displayContentsEnabled = is<HTMLSlotElement>(element) || RuntimeEnabledFeatures::sharedFeatures().displayContentsEnabled(); 795 if (!displayContentsEnabled) { 796 style.setDisplay(INLINE); 797 return; 798 } 799 if (!element) { 800 if (style.styleType() != BEFORE && style.styleType() != AFTER) 801 style.setDisplay(NONE); 802 return; 803 } 804 if (hasEffectiveDisplayNoneForDisplayContents(*element)) 805 style.setDisplay(NONE); 806 } 807 792 808 void StyleResolver::adjustRenderStyle(RenderStyle& style, const RenderStyle& parentStyle, const RenderStyle* parentBoxStyle, const Element* element) 793 809 { … … 800 816 style.setOriginalDisplay(style.display()); 801 817 802 if (style.display() == CONTENTS) { 803 bool elementSupportsDisplayContents = is<HTMLSlotElement>(element) || RuntimeEnabledFeatures::sharedFeatures().displayContentsEnabled(); 804 if (!elementSupportsDisplayContents) 805 style.setDisplay(INLINE); 806 else if (!element || hasEffectiveDisplayNoneForDisplayContents(*element)) 807 style.setDisplay(NONE); 808 } 818 if (style.display() == CONTENTS) 819 adjustDisplayContentsStyle(style, element); 809 820 810 821 if (style.display() != NONE && style.display() != CONTENTS) { -
trunk/Source/WebCore/dom/PseudoElement.h
r223604 r223810 45 45 bool canContainRangeEndPoint() const override { return false; } 46 46 47 auto& contentRenderers() { return m_contentRenderers; } 48 47 49 static String pseudoElementNameForEvents(PseudoId); 48 50 … … 54 56 Element* m_hostElement; 55 57 PseudoId m_pseudoId; 58 Vector<WeakPtr<RenderObject>> m_contentRenderers; 56 59 }; 57 60 -
trunk/Source/WebCore/style/RenderTreePosition.h
r222679 r223810 35 35 class RenderTreePosition { 36 36 public: 37 explicit RenderTreePosition(RenderView& root)38 : m_parent(root)39 , m_hasValidNextSibling(true)40 {41 }42 43 37 explicit RenderTreePosition(RenderElement& parent) 44 38 : m_parent(parent) … … 52 46 53 47 void computeNextSibling(const Node&); 48 void moveToLastChild(); 54 49 void invalidateNextSibling() { m_hasValidNextSibling = false; } 55 50 void invalidateNextSibling(const RenderObject&); … … 66 61 #endif 67 62 }; 63 64 inline void RenderTreePosition::moveToLastChild() 65 { 66 m_nextSibling = nullptr; 67 m_hasValidNextSibling = true; 68 } 68 69 69 70 inline bool RenderTreePosition::canInsert(RenderElement& renderer) const -
trunk/Source/WebCore/style/RenderTreeUpdaterGeneratedContent.cpp
r223748 r223810 70 70 } 71 71 72 static void createContentRenderers( RenderElement& renderer)72 static void createContentRenderers(PseudoElement& pseudoElement, const RenderStyle& style, RenderTreePosition& renderTreePosition) 73 73 { 74 auto& style = renderer.style();75 74 ASSERT(style.contentData()); 76 75 77 76 for (const ContentData* content = style.contentData(); content; content = content->next()) { 78 auto child = content->createContentRenderer(renderer.document(), style); 79 if (renderer.isChildAllowed(*child, style)) 80 renderer.addChild(WTFMove(child)); 77 auto child = content->createContentRenderer(renderTreePosition.parent().document(), style); 78 pseudoElement.contentRenderers().append(makeWeakPtr(*child)); 79 if (renderTreePosition.parent().isChildAllowed(*child, style)) 80 renderTreePosition.insert(WTFMove(child)); 81 81 } 82 82 } 83 83 84 static void updateStyleForContentRenderers( RenderElement& renderer)84 static void updateStyleForContentRenderers(PseudoElement& pseudoElement, const RenderStyle& style) 85 85 { 86 for (auto* child = renderer.nextInPreOrder(&renderer); child; child = child->nextInPreOrder(&renderer)) { 86 for (auto& contentRenderer : pseudoElement.contentRenderers()) { 87 if (!contentRenderer) 88 continue; 87 89 // We only manage the style for the generated content which must be images or text. 88 if (!is<RenderImage>(*c hild) && !is<RenderQuote>(*child))90 if (!is<RenderImage>(*contentRenderer) && !is<RenderQuote>(*contentRenderer)) 89 91 continue; 90 auto createdStyle = RenderStyle::createStyleInheritingFromPseudoStyle( renderer.style());91 downcast<RenderElement>(*c hild).setStyle(WTFMove(createdStyle));92 auto createdStyle = RenderStyle::createStyleInheritingFromPseudoStyle(style); 93 downcast<RenderElement>(*contentRenderer).setStyle(WTFMove(createdStyle)); 92 94 } 95 } 96 97 static void removeAndDestroyContentRenderers(PseudoElement& pseudoElement) 98 { 99 for (auto& contentRenderer : pseudoElement.contentRenderers()) { 100 if (!contentRenderer) 101 continue; 102 contentRenderer->removeFromParentAndDestroy(); 103 } 104 pseudoElement.contentRenderers().clear(); 93 105 } 94 106 … … 102 114 if (!needsPseudoElement(update)) { 103 115 if (pseudoElement) { 116 removeAndDestroyContentRenderers(*pseudoElement); 117 104 118 if (pseudoId == BEFORE) 105 119 current.clearBeforePseudoElement(); … … 128 142 m_updater.updateElementRenderer(*pseudoElement, *update); 129 143 130 auto* pseudo Renderer = pseudoElement->renderer();131 if (!pseudo Renderer)144 auto* pseudoElementRenderer = pseudoElement->renderer(); 145 if (!pseudoElementRenderer && update->style->display() != CONTENTS) 132 146 return; 133 147 134 if (update->change == Style::Detach) 135 createContentRenderers(*pseudoRenderer); 136 else 137 updateStyleForContentRenderers(*pseudoRenderer); 148 auto renderTreePosition = pseudoElementRenderer ? RenderTreePosition(*pseudoElementRenderer) : m_updater.renderTreePosition(); 149 150 if (update->change == Style::Detach) { 151 removeAndDestroyContentRenderers(*pseudoElement); 152 153 if (pseudoElementRenderer) 154 renderTreePosition.moveToLastChild(); 155 else 156 renderTreePosition.computeNextSibling(*pseudoElement); 157 158 createContentRenderers(*pseudoElement, *update->style, renderTreePosition); 159 } else 160 updateStyleForContentRenderers(*pseudoElement, *update->style); 138 161 139 162 if (m_updater.renderView().hasQuotesNeedingUpdate()) { 140 for (auto& child : descendantsOfType<RenderQuote>( *pseudoRenderer))163 for (auto& child : descendantsOfType<RenderQuote>(renderTreePosition.parent())) 141 164 updateQuotesUpTo(&child); 142 165 } 143 if (is<RenderListItem>( *pseudoRenderer))144 ListItem::updateMarker(downcast<RenderListItem>( *pseudoRenderer));166 if (is<RenderListItem>(renderTreePosition.parent())) 167 ListItem::updateMarker(downcast<RenderListItem>(renderTreePosition.parent())); 145 168 } 146 169
Note: See TracChangeset
for help on using the changeset viewer.