[LFC][Quirk] Move quirk functions to dedicated classes.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2018 15:28:20 +0000 (15:28 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2018 15:28:20 +0000 (15:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=192133

Reviewed by Antti Koivisto.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/FormattingContext.h:
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::computedHeightValue):
* layout/blockformatting/BlockFormattingContext.h:
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
(WebCore::Layout::initialContainingBlock): Deleted.
(WebCore::Layout::isStretchedToInitialContainingBlock): Deleted.
(WebCore::Layout::stretchHeightToInitialContainingBlockQuirk): Deleted.
(WebCore::Layout::stretchWidthToInitialContainingBlock): Deleted.
* layout/blockformatting/BlockFormattingState.cpp:
* layout/blockformatting/BlockMarginCollapse.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::MarginCollapse::isMarginTopCollapsedWithParent):
(WebCore::Layout::BlockFormattingContext::Geometry::MarginCollapse::marginTop):
(WebCore::Layout::isQuirkContainer): Deleted.
(WebCore::Layout::hasMarginTopQuirkValue): Deleted.
(WebCore::Layout::shouldIgnoreMarginTopInQuirkContext): Deleted.
(WebCore::Layout::isMarginTopCollapsedWithParent): Deleted.
* layout/inlineformatting/InlineFormattingContext.cpp:
* layout/inlineformatting/text/TextUtil.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238667 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/layout/FormattingContext.h
Source/WebCore/layout/FormattingContextGeometry.cpp
Source/WebCore/layout/FormattingContextQuirks.cpp [new file with mode: 0644]
Source/WebCore/layout/blockformatting/BlockFormattingContext.h
Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp
Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp [new file with mode: 0644]
Source/WebCore/layout/blockformatting/BlockFormattingState.cpp
Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp
Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
Source/WebCore/layout/inlineformatting/text/TextUtil.h

index 0f2b337..1b24cf3 100644 (file)
@@ -1,3 +1,34 @@
+2018-11-29  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][Quirk] Move quirk functions to dedicated classes.
+        https://bugs.webkit.org/show_bug.cgi?id=192133
+
+        Reviewed by Antti Koivisto.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/FormattingContext.h:
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::FormattingContext::Geometry::computedHeightValue):
+        * layout/blockformatting/BlockFormattingContext.h:
+        * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin):
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
+        (WebCore::Layout::initialContainingBlock): Deleted.
+        (WebCore::Layout::isStretchedToInitialContainingBlock): Deleted.
+        (WebCore::Layout::stretchHeightToInitialContainingBlockQuirk): Deleted.
+        (WebCore::Layout::stretchWidthToInitialContainingBlock): Deleted.
+        * layout/blockformatting/BlockFormattingState.cpp:
+        * layout/blockformatting/BlockMarginCollapse.cpp:
+        (WebCore::Layout::BlockFormattingContext::Geometry::MarginCollapse::isMarginTopCollapsedWithParent):
+        (WebCore::Layout::BlockFormattingContext::Geometry::MarginCollapse::marginTop):
+        (WebCore::Layout::isQuirkContainer): Deleted.
+        (WebCore::Layout::hasMarginTopQuirkValue): Deleted.
+        (WebCore::Layout::shouldIgnoreMarginTopInQuirkContext): Deleted.
+        (WebCore::Layout::isMarginTopCollapsedWithParent): Deleted.
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        * layout/inlineformatting/text/TextUtil.h:
+
 2018-11-29  Rob Buis  <rbuis@igalia.com>
 
         Remove some superfluous code in ContentSecurityPolicy::upgradeInsecureRequestIfNeeded
index 55d0849..79cdc3e 100644 (file)
@@ -1262,11 +1262,13 @@ inspector/agents/worker/WorkerRuntimeAgent.cpp
 
 layout/FormattingContext.cpp
 layout/FormattingContextGeometry.cpp
+layout/FormattingContextQuirks.cpp
 layout/FormattingState.cpp
 layout/LayoutFormattingState.cpp
 layout/Verification.cpp
 layout/blockformatting/BlockFormattingContext.cpp
 layout/blockformatting/BlockFormattingContextGeometry.cpp
+layout/blockformatting/BlockFormattingContextQuirks.cpp
 layout/blockformatting/BlockFormattingState.cpp
 layout/blockformatting/BlockMarginCollapse.cpp
 layout/blockformatting/BlockInvalidation.cpp
index b41a396..d16d326 100644 (file)
                6F7CA3C5208C2956002F29AB /* LayoutFormattingState.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutFormattingState.cpp; sourceTree = "<group>"; };
                6F7CA3C8208C2B2E002F29AB /* InlineFormattingContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InlineFormattingContext.h; sourceTree = "<group>"; };
                6F7CA3C9208C2B2E002F29AB /* InlineFormattingContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineFormattingContext.cpp; sourceTree = "<group>"; };
+               6F8F460121B03BB40041AC3A /* FormattingContextQuirks.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FormattingContextQuirks.cpp; sourceTree = "<group>"; };
+               6F8F460321B03BC60041AC3A /* BlockFormattingContextQuirks.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BlockFormattingContextQuirks.cpp; sourceTree = "<group>"; };
                6F995A091A7070E600A735F4 /* WebGLQuery.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebGLQuery.idl; sourceTree = "<group>"; };
                6F995A0A1A7070E600A735F4 /* WebGLSampler.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebGLSampler.idl; sourceTree = "<group>"; };
                6F995A0B1A7070E600A735F4 /* WebGLSync.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebGLSync.idl; sourceTree = "<group>"; };
                                115CFA69208AF7D0001E6991 /* FormattingContext.cpp */,
                                115CFA68208AF7D0001E6991 /* FormattingContext.h */,
                                6FBB860520B464B600DAD938 /* FormattingContextGeometry.cpp */,
+                               6F8F460121B03BB40041AC3A /* FormattingContextQuirks.cpp */,
                                115CFA75208AFE30001E6991 /* FormattingState.cpp */,
                                115CFA74208AFE30001E6991 /* FormattingState.h */,
                                115F7805209CBCBD00739C13 /* Invalidation.h */,
                                115CFA6D208AFAB6001E6991 /* BlockFormattingContext.cpp */,
                                115CFA6C208AFAB6001E6991 /* BlockFormattingContext.h */,
                                6F0830DF20B46951008A945B /* BlockFormattingContextGeometry.cpp */,
+                               6F8F460321B03BC60041AC3A /* BlockFormattingContextQuirks.cpp */,
                                115CFA79208B8D9D001E6991 /* BlockFormattingState.cpp */,
                                115CFA78208B8D9D001E6991 /* BlockFormattingState.h */,
                                1123AFDA209ABB2000736ACC /* BlockInvalidation.cpp */,
index e7eb7e9..4f65e56 100644 (file)
@@ -122,6 +122,11 @@ protected:
         static WidthAndMargin floatingNonReplacedWidthAndMargin(LayoutState&, const Box&, std::optional<LayoutUnit> usedWidth = { });
     };
 
+    class Quirks {
+    public:
+        static LayoutUnit heightValueOfNearestContainingBlockWithFixedHeight(const LayoutState&, const Box&);
+    };
+
 private:
     void computeOutOfFlowVerticalGeometry(const Box&) const;
     void computeOutOfFlowHorizontalGeometry(const Box&) const;
index 8c34f05..0a3a883 100644 (file)
@@ -72,35 +72,8 @@ std::optional<LayoutUnit> FormattingContext::Geometry::computedHeightValue(const
         // Containing block's height is already computed since we layout the out-of-flow boxes as the last step.
         containingBlockHeightValue = layoutState.displayBoxForLayoutBox(*layoutBox.containingBlock()).height();
     } else {
-        auto computedHeightValueForQuirksMode = [&]() -> LayoutUnit {
-            // In quirks mode, we go and travers the containing block chain to find a block level box with fixed height value, even if it means leaving
-            // the current formatting context. FIXME: surely we need to do some tricks here when block direction support is added.
-            auto* containingBlock = layoutBox.containingBlock();
-            LayoutUnit bodyAndDocumentVerticalMarginsPaddingsAndBorders;
-            while (containingBlock) {
-                auto containingBlockHeight = containingBlock->style().logicalHeight();
-                if (containingBlockHeight.isFixed())
-                    return containingBlockHeight.value() - bodyAndDocumentVerticalMarginsPaddingsAndBorders;
-
-                // If the only fixed value box we find is the ICB, then ignore the body and the document (vertical) margin, padding and border. So much quirkiness.
-                // -and it's totally insane because now we freely travel across formatting context boundaries and computed margins are nonexistent.
-                if (containingBlock->isBodyBox() || containingBlock->isDocumentBox()) {
-                    auto& displayBox = layoutState.displayBoxForLayoutBox(*containingBlock);
-
-                    auto verticalMargins = computedNonCollapsedVerticalMarginValue(layoutState, *containingBlock);
-                    auto verticalPaddings = displayBox.paddingTop().value_or(0) + displayBox.paddingBottom().value_or(0);
-                    auto verticalBorders = displayBox.borderTop() + displayBox.borderBottom();
-                    bodyAndDocumentVerticalMarginsPaddingsAndBorders += verticalMargins.top + verticalMargins.bottom + verticalPaddings + verticalBorders;
-                }
-
-                containingBlock = containingBlock->containingBlock();
-            }
-            // Initial containing block has to have a height.
-            return layoutState.displayBoxForLayoutBox(layoutBox.initialContainingBlock()).contentBox().height() - bodyAndDocumentVerticalMarginsPaddingsAndBorders;
-        };
-
         if (layoutState.inQuirksMode())
-            containingBlockHeightValue = computedHeightValueForQuirksMode();
+            containingBlockHeightValue = FormattingContext::Quirks::heightValueOfNearestContainingBlockWithFixedHeight(layoutState, layoutBox);
         else {
             auto containingBlockHeight = layoutBox.containingBlock()->style().logicalHeight();
             if (containingBlockHeight.isFixed())
diff --git a/Source/WebCore/layout/FormattingContextQuirks.cpp b/Source/WebCore/layout/FormattingContextQuirks.cpp
new file mode 100644 (file)
index 0000000..f7cbeed
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "FormattingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "LayoutBox.h"
+#include "LayoutContainer.h"
+#include "LayoutFormattingState.h"
+
+namespace WebCore {
+namespace Layout {
+
+LayoutUnit FormattingContext::Quirks::heightValueOfNearestContainingBlockWithFixedHeight(const LayoutState& layoutState, const Box& layoutBox)
+{
+    // In quirks mode, we go and travers the containing block chain to find a block level box with fixed height value, even if it means leaving
+    // the current formatting context. FIXME: surely we need to do some tricks here when block direction support is added.
+    auto* containingBlock = layoutBox.containingBlock();
+    LayoutUnit bodyAndDocumentVerticalMarginsPaddingsAndBorders;
+    while (containingBlock) {
+        auto containingBlockHeight = containingBlock->style().logicalHeight();
+        if (containingBlockHeight.isFixed())
+            return containingBlockHeight.value() - bodyAndDocumentVerticalMarginsPaddingsAndBorders;
+
+        // If the only fixed value box we find is the ICB, then ignore the body and the document (vertical) margin, padding and border. So much quirkiness.
+        // -and it's totally insane because now we freely travel across formatting context boundaries and computed margins are nonexistent.
+        if (containingBlock->isBodyBox() || containingBlock->isDocumentBox()) {
+            auto& displayBox = layoutState.displayBoxForLayoutBox(*containingBlock);
+
+            auto verticalMargins = FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue(layoutState, *containingBlock);
+            auto verticalPaddings = displayBox.paddingTop().value_or(0) + displayBox.paddingBottom().value_or(0);
+            auto verticalBorders = displayBox.borderTop() + displayBox.borderBottom();
+            bodyAndDocumentVerticalMarginsPaddingsAndBorders += verticalMargins.top + verticalMargins.bottom + verticalPaddings + verticalBorders;
+        }
+
+        containingBlock = containingBlock->containingBlock();
+    }
+    // Initial containing block has to have a height.
+    return layoutState.displayBoxForLayoutBox(layoutBox.initialContainingBlock()).contentBox().height() - bodyAndDocumentVerticalMarginsPaddingsAndBorders;
+}
+
+}
+}
+
+#endif
index e2c3d0b..c979c8b 100644 (file)
@@ -100,6 +100,8 @@ private:
 
             static LayoutUnit collapsedMarginTopFromFirstChild(const LayoutState&, const Box&);
             static LayoutUnit nonCollapsedMarginTop(const LayoutState&, const Box&);
+
+            static bool isMarginTopCollapsedWithParent(const LayoutState&, const Box&);
         };
 
         static HeightAndMargin inFlowNonReplacedHeightAndMargin(const LayoutState&, const Box&, std::optional<LayoutUnit> usedHeight = { });
@@ -107,6 +109,14 @@ private:
         static WidthAndMargin inFlowReplacedWidthAndMargin(const LayoutState&, const Box&, std::optional<LayoutUnit> usedWidth = { });
         static Point staticPositionForOutOfFlowPositioned(const LayoutState&, const Box&);
     };
+
+    class Quirks {
+    public:
+        static bool isStretchedToInitialContainingBlock(const LayoutState&, const Box&);
+        static HeightAndMargin stretchedHeight(const LayoutState&, const Box&, HeightAndMargin);
+        static WidthAndMargin stretchedWidth(const LayoutState&, const Box&, WidthAndMargin);
+        static bool shouldIgnoreMarginTop(const LayoutState&, const Box&);
+    };
 };
 
 }
index d599825..00b5c94 100644 (file)
 namespace WebCore {
 namespace Layout {
 
-static const Container& initialContainingBlock(const Box& layoutBox)
-{
-    auto* containingBlock = layoutBox.containingBlock();
-    while (containingBlock->containingBlock())
-        containingBlock = containingBlock->containingBlock();
-    return *containingBlock;
-}
-
-static bool isStretchedToInitialContainingBlock(const LayoutState& layoutState, const Box& layoutBox)
-{
-    ASSERT(layoutBox.isInFlow());
-    // In quirks mode, body and html stretch to the viewport.
-    if (!layoutState.inQuirksMode())
-        return false;
-
-    if (!layoutBox.isDocumentBox() && !layoutBox.isBodyBox())
-        return false;
-
-    return layoutBox.style().logicalHeight().isAuto();
-}
-
-static HeightAndMargin stretchHeightToInitialContainingBlockQuirk(HeightAndMargin heightAndMargin, LayoutUnit initialContainingBlockHeight)
-{
-    // This quirk happens when the body height is 0 which means its vertical margins collapse through (top and bottom margins are adjoining).
-    // However now that we stretch the body they don't collapse through anymore, so we need to use the non-collapsed values instead.
-    ASSERT(initialContainingBlockHeight);
-    auto verticalMargins = heightAndMargin.height ? heightAndMargin.usedMarginValues() : heightAndMargin.margin;
-    auto totalVerticalMargins = verticalMargins.top + verticalMargins.bottom;
-    // Stretch but never overstretch with the margins.
-    if (heightAndMargin.height + totalVerticalMargins < initialContainingBlockHeight)
-        heightAndMargin.height = initialContainingBlockHeight - totalVerticalMargins;
-
-    return heightAndMargin;
-}
-
-static WidthAndMargin stretchWidthToInitialContainingBlock(WidthAndMargin widthAndMargin, LayoutUnit initialContainingBlockWidth)
-{
-    auto horizontalMargins = widthAndMargin.margin.left + widthAndMargin.margin.right;
-    // Stretch but never overstretch with the margins.
-    if (widthAndMargin.width + horizontalMargins < initialContainingBlockWidth)
-        widthAndMargin.width = initialContainingBlockWidth - horizontalMargins;
-
-    return widthAndMargin;
-}
-
 HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin(const LayoutState& layoutState, const Box& layoutBox, std::optional<LayoutUnit> usedHeight)
 {
     ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
@@ -240,13 +195,12 @@ WidthAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin
     };
 
     auto widthAndMargin = compute();
-    if (!isStretchedToInitialContainingBlock(layoutState, layoutBox)) {
+    if (!Quirks::isStretchedToInitialContainingBlock(layoutState, layoutBox)) {
         LOG_WITH_STREAM(FormattingContextLayout, stream << "[Width][Margin] -> inflow non-replaced -> width(" << widthAndMargin.width << "px) margin(" << widthAndMargin.margin.left << "px, " << widthAndMargin.margin.right << "px) -> layoutBox(" << &layoutBox << ")");
         return widthAndMargin;
     }
 
-    auto initialContainingBlockWidth = layoutState.displayBoxForLayoutBox(initialContainingBlock(layoutBox)).contentBoxWidth();
-    widthAndMargin = stretchWidthToInitialContainingBlock(widthAndMargin, initialContainingBlockWidth);
+    widthAndMargin = Quirks::stretchedWidth(layoutState, layoutBox, widthAndMargin);
 
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Width][Margin] -> inflow non-replaced -> streched to viewport-> width(" << widthAndMargin.width << "px) margin(" << widthAndMargin.margin.left << "px, " << widthAndMargin.margin.right << "px) -> layoutBox(" << &layoutBox << ")");
     return widthAndMargin;
@@ -310,11 +264,10 @@ HeightAndMargin BlockFormattingContext::Geometry::inFlowHeightAndMargin(const La
         heightAndMargin = complicatedCases(layoutState, layoutBox, usedHeight);
     }
 
-    if (!isStretchedToInitialContainingBlock(layoutState, layoutBox))
+    if (!Quirks::isStretchedToInitialContainingBlock(layoutState, layoutBox))
         return heightAndMargin;
 
-    auto initialContainingBlockHeight = layoutState.displayBoxForLayoutBox(initialContainingBlock(layoutBox)).contentBoxHeight();
-    heightAndMargin = stretchHeightToInitialContainingBlockQuirk(heightAndMargin, initialContainingBlockHeight);
+    heightAndMargin = Quirks::stretchedHeight(layoutState, layoutBox, heightAndMargin);
 
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow non-replaced -> streched to viewport -> height(" << heightAndMargin.height << "px) margin(" << heightAndMargin.margin.top << "px, " << heightAndMargin.margin.bottom << "px) -> layoutBox(" << &layoutBox << ")");
     return heightAndMargin;
diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingContextQuirks.cpp
new file mode 100644 (file)
index 0000000..d8408a8
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "BlockFormattingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "LayoutBox.h"
+#include "LayoutContainer.h"
+#include "LayoutFormattingState.h"
+
+namespace WebCore {
+namespace Layout {
+
+static const Container& initialContainingBlock(const Box& layoutBox)
+{
+    auto* containingBlock = layoutBox.containingBlock();
+    while (containingBlock->containingBlock())
+        containingBlock = containingBlock->containingBlock();
+    return *containingBlock;
+}
+
+static bool isQuirkContainer(const Box& layoutBox)
+{
+    return layoutBox.isBodyBox() || layoutBox.isDocumentBox() || layoutBox.isTableCell();
+}
+
+static bool hasMarginTopQuirkValue(const Box& layoutBox)
+{
+    return layoutBox.style().hasMarginBeforeQuirk();
+}
+
+bool BlockFormattingContext::Quirks::isStretchedToInitialContainingBlock(const LayoutState& layoutState, const Box& layoutBox)
+{
+    ASSERT(layoutBox.isInFlow());
+    // In quirks mode, body and html stretch to the viewport.
+    if (!layoutState.inQuirksMode())
+        return false;
+
+    if (!layoutBox.isDocumentBox() && !layoutBox.isBodyBox())
+        return false;
+
+    return layoutBox.style().logicalHeight().isAuto();
+}
+
+HeightAndMargin BlockFormattingContext::Quirks::stretchedHeight(const LayoutState& layoutState, const Box& layoutBox, HeightAndMargin heightAndMargin)
+{
+    auto initialContainingBlockHeight = layoutState.displayBoxForLayoutBox(initialContainingBlock(layoutBox)).contentBoxHeight();
+    // This quirk happens when the body height is 0 which means its vertical margins collapse through (top and bottom margins are adjoining).
+    // However now that we stretch the body they don't collapse through anymore, so we need to use the non-collapsed values instead.
+    ASSERT(initialContainingBlockHeight);
+    auto verticalMargins = heightAndMargin.height ? heightAndMargin.usedMarginValues() : heightAndMargin.margin;
+    auto totalVerticalMargins = verticalMargins.top + verticalMargins.bottom;
+    // Stretch but never overstretch with the margins.
+    if (heightAndMargin.height + totalVerticalMargins < initialContainingBlockHeight)
+        heightAndMargin.height = initialContainingBlockHeight - totalVerticalMargins;
+
+    return heightAndMargin;
+}
+
+WidthAndMargin BlockFormattingContext::Quirks::stretchedWidth(const LayoutState& layoutState, const Box& layoutBox, WidthAndMargin widthAndMargin)
+{
+    auto initialContainingBlockWidth = layoutState.displayBoxForLayoutBox(initialContainingBlock(layoutBox)).contentBoxWidth();
+    auto horizontalMargins = widthAndMargin.margin.left + widthAndMargin.margin.right;
+    // Stretch but never overstretch with the margins.
+    if (widthAndMargin.width + horizontalMargins < initialContainingBlockWidth)
+        widthAndMargin.width = initialContainingBlockWidth - horizontalMargins;
+
+    return widthAndMargin;
+}
+
+bool BlockFormattingContext::Quirks::shouldIgnoreMarginTop(const LayoutState& layoutState, const Box& layoutBox)
+{
+    if (!layoutBox.parent())
+        return false;
+
+    return layoutState.inQuirksMode() && isQuirkContainer(*layoutBox.parent()) && hasMarginTopQuirkValue(layoutBox);
+}
+
+}
+}
+
+#endif
index 8c30077..88cf55c 100644 (file)
@@ -28,7 +28,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
-#include "FormattingContext.h"
+#include "BlockFormattingContext.h"
 #include "LayoutBox.h"
 #include <wtf/IsoMallocInlines.h>
 
index 27dd35a..98099b8 100644 (file)
 namespace WebCore {
 namespace Layout {
 
-static bool isQuirkContainer(const Box& layoutBox)
-{
-    return layoutBox.isBodyBox() || layoutBox.isDocumentBox() || layoutBox.isTableCell();
-}
-
-static bool hasMarginTopQuirkValue(const Box& layoutBox)
-{
-    return layoutBox.style().hasMarginBeforeQuirk();
-}
-
-static bool shouldIgnoreMarginTopInQuirkContext(const LayoutState& layoutState, const Box& layoutBox)
-{
-    if (!layoutBox.parent())
-        return false;
-    return layoutState.inQuirksMode() && isQuirkContainer(*layoutBox.parent()) && hasMarginTopQuirkValue(layoutBox);
-}
-
 static LayoutUnit marginValue(LayoutUnit currentMarginValue, LayoutUnit candidateMarginValue)
 {
     if (!candidateMarginValue)
@@ -99,7 +82,7 @@ static bool isMarginBottomCollapsedWithSibling(const Box& layoutBox)
     return layoutBox.style().bottom().isAuto();
 }
 
-static bool isMarginTopCollapsedWithParent(const LayoutState& layoutState, const Box& layoutBox)
+bool BlockFormattingContext::Geometry::MarginCollapse::isMarginTopCollapsedWithParent(const LayoutState& layoutState, const Box& layoutBox)
 {
     // The first inflow child could propagate its top margin to parent.
     // https://www.w3.org/TR/CSS21/box.html#collapsing-margins
@@ -132,7 +115,7 @@ static bool isMarginTopCollapsedWithParent(const LayoutState& layoutState, const
     if (parentDisplayBox.paddingTop().value_or(0))
         return false;
 
-    if (shouldIgnoreMarginTopInQuirkContext(layoutState, layoutBox))
+    if (BlockFormattingContext::Quirks::shouldIgnoreMarginTop(layoutState, layoutBox))
         return false;
 
     return true;
@@ -232,7 +215,7 @@ LayoutUnit BlockFormattingContext::Geometry::MarginCollapse::marginTop(const Lay
         return 0;
 
     // FIXME: Find out the logic behind this.
-    if (shouldIgnoreMarginTopInQuirkContext(layoutState, layoutBox))
+    if (BlockFormattingContext::Quirks::shouldIgnoreMarginTop(layoutState, layoutBox))
         return 0;
 
     if (!isMarginTopCollapsedWithSibling(layoutBox)) {
index bf80bc3..39841ce 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "FloatingContext.h"
 #include "FloatingState.h"
 #include "InlineFormattingState.h"
 #include "InlineLineBreaker.h"
index 08e9576..888d5e3 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "InlineItem.h"
+#include "InlineRunProvider.h"
 
 namespace WebCore {
 namespace Layout {