WebKit Bugzilla
Attachment 340824 Details for
Bug 185811
: [LFC] Add FormattingContext::validateGeometryConstraintsAfterLayout
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185811-20180520220705.patch (text/plain), 19.27 KB, created by
zalan
on 2018-05-20 22:07:06 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
zalan
Created:
2018-05-20 22:07:06 PDT
Size:
19.27 KB
patch
obsolete
>Subversion Revision: 231958 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 9bf9345096d71de059c60de0ab1827c87a58e7df..d387a7e0a2b8dc2282a8a6018c9e726110b3dea5 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,42 @@ >+2018-05-20 Zalan Bujtas <zalan@apple.com> >+ >+ [LFC] Add FormattingContext::validateGeometryConstraintsAfterLayout >+ https://bugs.webkit.org/show_bug.cgi?id=185811 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Also implement LayoutDescendantIterator and fix LayoutIterator. >+ >+ * WebCore.xcodeproj/project.pbxproj: >+ * layout/FormattingContext.cpp: >+ (WebCore::Layout::FormattingContext::validateGeometryConstraintsAfterLayout const): >+ * layout/FormattingContext.h: >+ * layout/blockformatting/BlockFormattingContext.cpp: >+ (WebCore::Layout::BlockFormattingContext::layout const): >+ * layout/layouttree/LayoutDescendantIterator.h: Added. >+ (WebCore::Layout::LayoutDescendantIterator<T>::LayoutDescendantIterator): >+ (WebCore::Layout::LayoutDescendantIterator<T>::operator): >+ (WebCore::Layout::LayoutDescendantIteratorAdapter<T>::LayoutDescendantIteratorAdapter): >+ (WebCore::Layout::LayoutDescendantIteratorAdapter<T>::begin): >+ (WebCore::Layout::LayoutDescendantIteratorAdapter<T>::end): >+ (WebCore::Layout::LayoutDescendantIteratorAdapter<T>::at): >+ (WebCore::Layout::descendantsOfType): >+ * layout/layouttree/LayoutIterator.h: >+ (WebCore::Layout::LayoutBoxTraversal::firstChild): >+ (WebCore::Layout::LayoutBoxTraversal::nextAncestorSibling): >+ (WebCore::Layout::LayoutBoxTraversal::next): >+ (WebCore::Layout::LayoutBoxTraversal::nextSkippingChildren): >+ (WebCore::Layout::Traversal::firstChild): >+ (WebCore::Layout::Traversal::nextSibling): >+ (WebCore::Layout::Traversal::previousSibling): >+ (WebCore::Layout::Traversal::findAncestorOfType): >+ (WebCore::Layout::Traversal::firstWithin): >+ (WebCore::Layout::Traversal::next): >+ (WebCore::Layout::LayoutIterator<T>::traversePreviousSibling): >+ (WebCore::Layout::LayoutIterator<T>::traverseAncestor): >+ (WebCore::Layout::Traversal::nextAncestorSibling): Deleted. >+ (WebCore::Layout::Traversal::nextWithin): Deleted. >+ > 2018-05-18 Zalan Bujtas <zalan@apple.com> > > [LFC] Implement height computation for non-replaced floating elements. >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index b5104d1d4a71c3893c35e9d60d53797a8341fcb0..8514c3fb86d609cf81b2455ffad713fe14ed107c 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -5776,6 +5776,7 @@ > 1199FA52208E38D3002358CC /* LayoutInlineBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutInlineBox.cpp; sourceTree = "<group>"; }; > 1199FA59208E3C7F002358CC /* DisplayBox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayBox.h; sourceTree = "<group>"; }; > 1199FA5A208E3C7F002358CC /* DisplayBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayBox.cpp; sourceTree = "<group>"; }; >+ 11B042FB20B0E21400828A6B /* LayoutDescendantIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutDescendantIterator.h; sourceTree = "<group>"; }; > 11C5F1162003E7750001AE60 /* RenderTreeBuilderInline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderInline.cpp; sourceTree = "<group>"; }; > 11C5F1182003E7760001AE60 /* RenderTreeBuilderInline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderInline.h; sourceTree = "<group>"; }; > 11C5F11D2003F69E0001AE60 /* RenderTreeBuilderBlockFlow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderBlockFlow.h; sourceTree = "<group>"; }; >@@ -15697,6 +15698,7 @@ > 11100FC920927CBC0081AA6C /* LayoutChildIterator.h */, > 1199FA45208E35A3002358CC /* LayoutContainer.cpp */, > 1199FA44208E35A3002358CC /* LayoutContainer.h */, >+ 11B042FB20B0E21400828A6B /* LayoutDescendantIterator.h */, > 1199FA52208E38D3002358CC /* LayoutInlineBox.cpp */, > 1199FA51208E38D3002358CC /* LayoutInlineBox.h */, > 1199FA4E208E3899002358CC /* LayoutInlineContainer.cpp */, >@@ -26931,8 +26933,6 @@ > isa = PBXHeadersBuildPhase; > buildActionMask = 2147483647; > files = ( >- 29A812490FBB9CA900510293 /* WebAccessibilityObjectWrapperBase.h in Headers */, >- AA478A7F16CD70C3007D1BB4 /* WebAccessibilityObjectWrapperMac.h in Headers */, > 7CD0E2B81F80A4820016A4CE /* AbortController.h in Headers */, > 7CD0E2BF1F80A56E0016A4CE /* AbortSignal.h in Headers */, > 46B95195207D633400A7D2DD /* AbstractDOMWindow.h in Headers */, >@@ -30725,7 +30725,9 @@ > FD7F299213D4C0CB00AD9535 /* WaveShaperDSPKernel.h in Headers */, > FD7F299413D4C0CB00AD9535 /* WaveShaperNode.h in Headers */, > FD7F299713D4C0CB00AD9535 /* WaveShaperProcessor.h in Headers */, >+ 29A812490FBB9CA900510293 /* WebAccessibilityObjectWrapperBase.h in Headers */, > AAA728F716D1D8BC00D3BBC6 /* WebAccessibilityObjectWrapperIOS.h in Headers */, >+ AA478A7F16CD70C3007D1BB4 /* WebAccessibilityObjectWrapperMac.h in Headers */, > 2D3EF4481917915C00034184 /* WebActionDisablingCALayerDelegate.h in Headers */, > 71025ED31F99F0CE004A250C /* WebAnimation.h in Headers */, > 7132445120109DA500AE7FB2 /* WebAnimationUtilities.h in Headers */, >diff --git a/Source/WebCore/layout/FormattingContext.cpp b/Source/WebCore/layout/FormattingContext.cpp >index b197ea56318e4ae450bbb403c42620054ad5cb4b..fe07e807cd19bcae6b2ee19239efc54f8fc7770f 100644 >--- a/Source/WebCore/layout/FormattingContext.cpp >+++ b/Source/WebCore/layout/FormattingContext.cpp >@@ -32,6 +32,7 @@ > #include "LayoutBox.h" > #include "LayoutContainer.h" > #include "LayoutContext.h" >+#include "LayoutDescendantIterator.h" > #include <wtf/IsoMallocInlines.h> > > namespace WebCore { >@@ -442,6 +443,39 @@ LayoutUnit FormattingContext::shrinkToFitWidth(LayoutContext&, const Box&) const > return 0; > } > >+#ifndef NDEBUG >+void FormattingContext::validateGeometryConstraintsAfterLayout(const LayoutContext& layoutContext) const >+{ >+ if (!is<Container>(root())) >+ return; >+ auto& formattingContextRoot = downcast<Container>(root()); >+ // FIXME: add a descendantsOfType<> flavor that stops at nested formatting contexts >+ for (auto& layoutBox : descendantsOfType<Box>(formattingContextRoot)) { >+ if (&layoutBox.formattingContextRoot() != &formattingContextRoot) >+ continue; >+ auto* containingBlock = layoutBox.containingBlock(); >+ ASSERT(containingBlock); >+ auto containingBlockSize = layoutContext.displayBoxForLayoutBox(*containingBlock)->size(); >+ auto* displayBox = layoutContext.displayBoxForLayoutBox(layoutBox); >+ ASSERT(displayBox); >+ >+ // 10.3.3 Block-level, non-replaced elements in normal flow >+ // 10.3.7 Absolutely positioned, non-replaced elements >+ if ((layoutBox.isBlockLevelBox() || layoutBox.isOutOfFlowPositioned()) && !layoutBox.replaced()) { >+ // margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right = width of containing block >+ ASSERT(displayBox->marginLeft() + displayBox->borderLeft() + displayBox->paddingLeft() + displayBox->width() >+ + displayBox->paddingRight() + displayBox->borderRight() + displayBox->marginRight() == containingBlockSize.width()); >+ } >+ >+ // 10.6.4 Absolutely positioned, non-replaced elements >+ if (layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced()) { >+ // top + margin-top + border-top-width + padding-top + height + padding-bottom + border-bottom-width + margin-bottom + bottom = height of containing block >+ ASSERT(displayBox->top() + displayBox->marginTop() + displayBox->borderTop() + displayBox->paddingTop() >+ + displayBox->paddingBottom() + displayBox->borderBottom() + displayBox->marginBottom() == containingBlockSize.height()); >+ } >+ } >+} >+#endif > } > } > #endif >diff --git a/Source/WebCore/layout/FormattingContext.h b/Source/WebCore/layout/FormattingContext.h >index ee0ed554b6b84f138fc904c47fd66959eb7137ca..4f90be842cdba271fc0f15ffc414481810270c7d 100644 >--- a/Source/WebCore/layout/FormattingContext.h >+++ b/Source/WebCore/layout/FormattingContext.h >@@ -90,6 +90,10 @@ protected: > void computeReplacedHeight(LayoutContext&, const Box&, Display::Box&) const; > void computeReplacedWidth(LayoutContext&, const Box&, Display::Box&) const; > >+#ifndef NDEBUG >+ virtual void validateGeometryConstraintsAfterLayout(const LayoutContext&) const; >+#endif >+ > private: > void computeOutOfFlowNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const; > void computeOutOfFlowNonReplacedWidth(LayoutContext&, const Box&, Display::Box&) const; >diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >index c5dd1444e82ab807c355343729d9f6a894af9534..cd048fbb3ab0f9f723a0fc6ce5eab3e004459440 100644 >--- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >@@ -112,6 +112,9 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat > placeInFlowPositionedChildren(formattingRoot); > // And take care of out-of-flow boxes as the final step. > layoutOutOfFlowDescendants(layoutContext); >+#ifndef NDEBUG >+ validateGeometryConstraintsAfterLayout(layoutContext); >+#endif > } > > std::unique_ptr<FormattingState> BlockFormattingContext::createFormattingState(Ref<FloatingState>&& floatingState) const >diff --git a/Source/WebCore/layout/layouttree/LayoutDescendantIterator.h b/Source/WebCore/layout/layouttree/LayoutDescendantIterator.h >new file mode 100644 >index 0000000000000000000000000000000000000000..b5ebcec77012b2db4916ad89273484b47188ca08 >--- /dev/null >+++ b/Source/WebCore/layout/layouttree/LayoutDescendantIterator.h >@@ -0,0 +1,113 @@ >+/* >+ * Copyright (C) 2018 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 met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "LayoutIterator.h" >+ >+#if ENABLE(LAYOUT_FORMATTING_CONTEXT) >+ >+namespace WebCore { >+namespace Layout { >+ >+template <typename T> >+class LayoutDescendantIterator : public LayoutIterator<T> { >+public: >+ LayoutDescendantIterator(const Container& root); >+ LayoutDescendantIterator(const Container& root, const T* current); >+ LayoutDescendantIterator& operator++(); >+}; >+ >+template <typename T> >+class LayoutDescendantIteratorAdapter { >+public: >+ LayoutDescendantIteratorAdapter(const Container& root); >+ LayoutDescendantIterator<T> begin(); >+ LayoutDescendantIterator<T> end(); >+ LayoutDescendantIterator<T> at(const T&); >+ >+private: >+ const Container& m_root; >+}; >+ >+template <typename T> LayoutDescendantIteratorAdapter<T> descendantsOfType(const Box&); >+ >+// LayoutDescendantIterator >+ >+template <typename T> >+inline LayoutDescendantIterator<T>::LayoutDescendantIterator(const Container& root) >+ : LayoutIterator<T>(&root) >+{ >+} >+ >+template <typename T> >+inline LayoutDescendantIterator<T>::LayoutDescendantIterator(const Container& root, const T* current) >+ : LayoutIterator<T>(&root, current) >+{ >+} >+ >+template <typename T> >+inline LayoutDescendantIterator<T>& LayoutDescendantIterator<T>::operator++() >+{ >+ return static_cast<LayoutDescendantIterator<T>&>(LayoutIterator<T>::traverseNext()); >+} >+ >+// LayoutDescendantIteratorAdapter >+ >+template <typename T> >+inline LayoutDescendantIteratorAdapter<T>::LayoutDescendantIteratorAdapter(const Container& root) >+ : m_root(root) >+{ >+} >+ >+template <typename T> >+inline LayoutDescendantIterator<T> LayoutDescendantIteratorAdapter<T>::begin() >+{ >+ return LayoutDescendantIterator<T>(m_root, Traversal::firstWithin<T>(m_root)); >+} >+ >+template <typename T> >+inline LayoutDescendantIterator<T> LayoutDescendantIteratorAdapter<T>::end() >+{ >+ return LayoutDescendantIterator<T>(m_root); >+} >+ >+template <typename T> >+inline LayoutDescendantIterator<T> LayoutDescendantIteratorAdapter<T>::at(const T& current) >+{ >+ return LayoutDescendantIterator<T>(m_root, ¤t); >+} >+ >+// Standalone functions >+ >+template <typename T> >+inline LayoutDescendantIteratorAdapter<T> descendantsOfType(const Container& root) >+{ >+ return LayoutDescendantIteratorAdapter<T>(root); >+} >+ >+} >+} >+#endif >diff --git a/Source/WebCore/layout/layouttree/LayoutIterator.h b/Source/WebCore/layout/layouttree/LayoutIterator.h >index 80894b827c74e739eb275386d2c1b64fee89ac22..ebbcb63599ac3ad0ea92a0cba94f8e7d03895560 100644 >--- a/Source/WebCore/layout/layouttree/LayoutIterator.h >+++ b/Source/WebCore/layout/layouttree/LayoutIterator.h >@@ -56,13 +56,64 @@ private: > template <typename T, typename U> > inline bool isLayoutBoxOfType(const U& layoutBox) { return TypeCastTraits<const T, const U>::isOfType(layoutBox); } > >+namespace LayoutBoxTraversal { >+ >+template <typename U> >+inline const Box* firstChild(U& object) >+{ >+ return object.firstChild(); >+} >+ >+inline const Box* firstChild(const Box&) >+{ >+ return nullptr; >+} >+ >+inline const Box* nextAncestorSibling(const Box& current, const Container* stayWithin) >+{ >+ for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) { >+ if (ancestor == stayWithin) >+ return nullptr; >+ if (auto* sibling = ancestor->nextSibling()) >+ return sibling; >+ } >+ return nullptr; >+} >+ >+template <typename U> >+inline const Box* next(const U& current, const Container* stayWithin) >+{ >+ if (auto* child = firstChild(current)) >+ return child; >+ >+ if (¤t == stayWithin) >+ return nullptr; >+ >+ if (auto* sibling = current.nextSibling()) >+ return sibling; >+ >+ return nextAncestorSibling(current, stayWithin); >+} >+ >+inline const Box* nextSkippingChildren(Box& current, const Container* stayWithin) >+{ >+ if (¤t == stayWithin) >+ return nullptr; >+ >+ if (auto* sibling = current.nextSibling()) >+ return sibling; >+ >+ return nextAncestorSibling(current, stayWithin); >+} >+ >+} > // Traversal helpers > namespace Traversal { > > template <typename T, typename U> > inline const T* firstChild(U& current) > { >- auto* object = current.firstChild(); >+ auto* object = LayoutBoxTraversal::firstChild(current); > while (object && !isLayoutBoxOfType<T>(*object)) > object = object->nextSibling(); > return static_cast<const T*>(object); >@@ -77,8 +128,8 @@ inline const T* lastChild(U& current) > return static_cast<const T*>(object); > } > >-template <typename T, typename U> >-inline const T* nextSibling(U& current) >+template <typename T> >+inline const T* nextSibling(const T& current) > { > auto* object = current.nextSibling(); > while (object && !isLayoutBoxOfType<T>(*object)) >@@ -87,7 +138,7 @@ inline const T* nextSibling(U& current) > } > > template <typename T, typename U> >-inline const T* previousSibling(U& current) >+inline const T* previousSibling(const T& current) > { > auto* object = current.previousSibling(); > while (object && !isLayoutBoxOfType<T>(*object)) >@@ -95,8 +146,8 @@ inline const T* previousSibling(U& current) > return static_cast<const T*>(object); > } > >-template <typename T> >-inline const T* findAncestorOfType(const Box& current) >+template <typename T, typename U> >+inline const T* findAncestorOfType(const T& current) > { > for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) { > if (isLayoutBoxOfType<T>(*ancestor)) >@@ -106,47 +157,20 @@ inline const T* findAncestorOfType(const Box& current) > } > > template <typename T, typename U> >-inline const T* nextAncestorSibling(U& current, const Container* stayWithin) >-{ >- for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) { >- if (ancestor == stayWithin) >- return nullptr; >- if (auto* sibling = ancestor->nextSibling()) >- return sibling; >- } >- return nullptr; >-} >- >-template <typename T, typename U> >-inline const T* nextWithin(U& current, const Container* stayWithin) >-{ >- if (auto* child = firstChild(current)) >- return child; >- >- if (¤t == stayWithin) >- return nullptr; >- >- if (auto* sibling = current.nextSibling()) >- return sibling; >- >- return nextAncestorSibling(current, stayWithin); >-} >- >-template <typename T, typename U> >-inline const T* firstWithin(U& current) >+inline const T* firstWithin(const U& stayWithin) > { >- auto* descendant = current.fistChild(); >+ auto* descendant = LayoutBoxTraversal::firstChild(stayWithin); > while (descendant && !isLayoutBoxOfType<T>(*descendant)) >- descendant = nextWithin(*descendant, ¤t); >+ descendant = LayoutBoxTraversal::next(*descendant, &stayWithin); > return static_cast<const T*>(descendant); > } > > template <typename T, typename U> >-inline const T* next(U& current, const RenderObject* stayWithin) >+inline const T* next(const U& current, const Container* stayWithin) > { >- auto* descendant = nextWithin(current, stayWithin); >+ auto* descendant = LayoutBoxTraversal::next(current, stayWithin); > while (descendant && !isLayoutBoxOfType<T>(*descendant)) >- descendant = nextWithin(*descendant, stayWithin); >+ descendant = LayoutBoxTraversal::next(*descendant, stayWithin); > return static_cast<const T*>(descendant); > } > >@@ -188,17 +212,16 @@ template <typename T> > inline LayoutIterator<T>& LayoutIterator<T>::traversePreviousSibling() > { > ASSERT(m_current); >- m_current = Traversal::previousSibling<T>(m_current); >+ m_current = Traversal::previousSibling<T>(*m_current); > return *this; > } > >- > template <typename T> > inline LayoutIterator<T>& LayoutIterator<T>::traverseAncestor() > { > ASSERT(m_current); > ASSERT(m_current != m_root); >- m_current = Traversal::findAncestorOfType<const T>(*m_current); >+ m_current = Traversal::findAncestorOfType<T>(*m_current); > return *this; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185811
: 340824