Title: [164988] trunk
Revision
164988
Author
abu...@adobe.com
Date
2014-03-03 09:16:06 -0800 (Mon, 03 Mar 2014)

Log Message

[CSS Regions] Overset computation is incorrect in some cases
https://bugs.webkit.org/show_bug.cgi?id=129032

Reviewed by Mihnea Ovidenie.

Source/WebCore:

This patch reworks the way overset is computed for regions and named flows.

1. Regions overflow no longer trigger an overset changed event. This is because
the overflow of a box is contained within the region range of the box. The content
edge should be considered the logical bottom position of the content inside the
flow thread.

2. The regions events logic was moved from RenderFlowThread to RenderNamedFlowThread
and from RenderRegion to RenderNamedFlowFragment (including the regionOverset property).

3. The overset value of the named flow is no longer stored in the named flow. It is
extracted from the overset of the last region in the chain.

4. The regions overset is not computed every time the flow thread is laid out which
should improve performance for flows with many regions. With the patch, each region
computes the overset value during its layout when the flow thread is in the overflow
or the final layout phase.

5. The overset changed event is dispatched only at the end of the layout of the named flows,
after all the region overset changes have been considered. This means that the overset
event can't be dispatched in the middle of the auto-height processing algorithm that
requires multiple layout passes for the flow threads.

However, the region layout update event dispatch timing was not changed, it is dispatched
every time the flow thread has a layout. This preserves the current behavior of the event.

Tests: The old tests were modified to take into account the change.

* dom/Element.cpp:
(WebCore::Element::webkitRegionOverset):
* dom/WebKitNamedFlow.cpp:
(WebCore::WebKitNamedFlow::overset):
* inspector/InspectorCSSAgent.cpp:
(WebCore::InspectorCSSAgent::buildArrayForRegions):
* rendering/FlowThreadController.cpp:
(WebCore::FlowThreadController::updateFlowThreadsIntoMeasureContentPhase):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::computeOverflow):
* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::RenderFlowThread):
(WebCore::RenderFlowThread::layout):
* rendering/RenderFlowThread.h:
* rendering/RenderNamedFlowFragment.cpp:
(WebCore::RenderNamedFlowFragment::layoutBlock):
(WebCore::RenderNamedFlowFragment::setRegionOversetState):
(WebCore::RenderNamedFlowFragment::regionOversetState):
(WebCore::RenderNamedFlowFragment::updateOversetState):
* rendering/RenderNamedFlowFragment.h:
* rendering/RenderNamedFlowThread.cpp:
(WebCore::RenderNamedFlowThread::RenderNamedFlowThread):
(WebCore::RenderNamedFlowThread::computeOverflow):
(WebCore::RenderNamedFlowThread::layout):
(WebCore::RenderNamedFlowThread::dispatchNamedFlowEvents):
(WebCore::RenderNamedFlowThread::dispatchRegionLayoutUpdateEventIfNeeded):
(WebCore::RenderNamedFlowThread::dispatchRegionOversetChangeEventIfNeeded):
* rendering/RenderNamedFlowThread.h:
There's a new field called m_flowContentBottom that tracks the content bottom of the flow thread
after layout. This value is used to compute the overset value of the regions because it's not
affected by relative positioning or visual overflow such as shadows.
* rendering/RenderRegion.cpp:
* rendering/RenderRegion.h:

LayoutTests:

Adjust the tests to cope with the overset changes.

* fast/regions/cssom/element-region-overset-state-expected.txt:
* fast/regions/cssom/element-region-overset-state-vertical-rl-expected.txt:
* fast/regions/cssom/element-region-overset-state-vertical-rl.html:
* fast/regions/cssom/element-region-overset-state.html:
This test has a new case that verifies region clamping is correctly taken into account.
* fast/regions/cssom/webkit-named-flow-overset-expected.txt:
* fast/regions/cssom/webkit-named-flow-overset.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (164987 => 164988)


--- trunk/LayoutTests/ChangeLog	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/LayoutTests/ChangeLog	2014-03-03 17:16:06 UTC (rev 164988)
@@ -1,3 +1,20 @@
+2014-03-03  Andrei Bucur  <abu...@adobe.com>
+
+        [CSS Regions] Overset computation is incorrect in some cases
+        https://bugs.webkit.org/show_bug.cgi?id=129032
+
+        Reviewed by Mihnea Ovidenie.
+
+        Adjust the tests to cope with the overset changes. 
+
+        * fast/regions/cssom/element-region-overset-state-expected.txt:
+        * fast/regions/cssom/element-region-overset-state-vertical-rl-expected.txt:
+        * fast/regions/cssom/element-region-overset-state-vertical-rl.html:
+        * fast/regions/cssom/element-region-overset-state.html:
+        This test has a new case that verifies region clamping is correctly taken into account.
+        * fast/regions/cssom/webkit-named-flow-overset-expected.txt:
+        * fast/regions/cssom/webkit-named-flow-overset.html:
+
 2014-03-02  Timothy Hatcher  <timo...@apple.com>
 
         Remove ASSERT in ~IDBRequest since it is firing during legitimate uses in Web Inspector.

Modified: trunk/LayoutTests/fast/regions/cssom/element-region-overset-state-expected.txt (164987 => 164988)


--- trunk/LayoutTests/fast/regions/cssom/element-region-overset-state-expected.txt	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/LayoutTests/fast/regions/cssom/element-region-overset-state-expected.txt	2014-03-03 17:16:06 UTC (rev 164988)
@@ -10,6 +10,10 @@
 PASS regionOverset('region_1') is "fit"
 PASS regionOverset('region_2') is "fit"
 PASS regionOverset('region_3') is "empty"
+Generate layout overflow
+PASS regionOverset('region_1') is "fit"
+PASS regionOverset('region_2') is "fit"
+PASS regionOverset('region_3') is "empty"
 Add more content
 PASS regionOverset('region_1') is "fit"
 PASS regionOverset('region_2') is "fit"
@@ -17,7 +21,7 @@
 Add visual overflow
 PASS regionOverset('region_1') is "fit"
 PASS regionOverset('region_2') is "fit"
-PASS regionOverset('region_3') is "overset"
+PASS regionOverset('region_3') is "fit"
 Empty content
 PASS regionOverset('region_1') is "empty"
 PASS regionOverset('region_2') is "empty"

Modified: trunk/LayoutTests/fast/regions/cssom/element-region-overset-state-vertical-rl-expected.txt (164987 => 164988)


--- trunk/LayoutTests/fast/regions/cssom/element-region-overset-state-vertical-rl-expected.txt	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/LayoutTests/fast/regions/cssom/element-region-overset-state-vertical-rl-expected.txt	2014-03-03 17:16:06 UTC (rev 164988)
@@ -17,7 +17,7 @@
 Add visual overflow
 PASS regionOverset('region_1') is "fit"
 PASS regionOverset('region_2') is "fit"
-PASS regionOverset('region_3') is "overset"
+PASS regionOverset('region_3') is "fit"
 Empty content
 PASS regionOverset('region_1') is "empty"
 PASS regionOverset('region_2') is "empty"

Modified: trunk/LayoutTests/fast/regions/cssom/element-region-overset-state-vertical-rl.html (164987 => 164988)


--- trunk/LayoutTests/fast/regions/cssom/element-region-overset-state-vertical-rl.html	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/LayoutTests/fast/regions/cssom/element-region-overset-state-vertical-rl.html	2014-03-03 17:16:06 UTC (rev 164988)
@@ -92,7 +92,7 @@
 
         shouldBeEqualToString("regionOverset('region_1')", "fit");
         shouldBeEqualToString("regionOverset('region_2')", "fit");
-        shouldBeEqualToString("regionOverset('region_3')", "overset");
+        shouldBeEqualToString("regionOverset('region_3')", "fit");
 
         debug("Empty content");
         flowContent("no_article");

Modified: trunk/LayoutTests/fast/regions/cssom/element-region-overset-state.html (164987 => 164988)


--- trunk/LayoutTests/fast/regions/cssom/element-region-overset-state.html	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/LayoutTests/fast/regions/cssom/element-region-overset-state.html	2014-03-03 17:16:06 UTC (rev 164988)
@@ -58,9 +58,20 @@
     }
     function addMoreContent() {
         var c = document.getElementById("content");
+        c.style.marginTop = 0;
         c.style.height = 326;
+        var a = document.getElementById("article");
+        a.style.height = "auto";
     }
 
+    function generateLayoutOverflow() {
+        var c = document.getElementById("content");
+        c.style.marginTop = 400;
+        c.style.height = 400;
+        var a = document.getElementById("article");
+        a.style.height = 150;
+    }
+
     function test() {
         shouldBeEqualToString("regionOverset('region_1')", "empty");
         shouldBeEqualToString("regionOverset('region_2')", "empty");
@@ -73,6 +84,12 @@
         shouldBeEqualToString("regionOverset('region_2')", "fit");
         shouldBeEqualToString("regionOverset('region_3')", "empty");
 
+        debug("Generate layout overflow");
+        generateLayoutOverflow();
+        shouldBeEqualToString("regionOverset('region_1')", "fit");
+        shouldBeEqualToString("regionOverset('region_2')", "fit");
+        shouldBeEqualToString("regionOverset('region_3')", "empty");
+
         debug("Add more content");
         addMoreContent();
 
@@ -85,7 +102,7 @@
 
         shouldBeEqualToString("regionOverset('region_1')", "fit");
         shouldBeEqualToString("regionOverset('region_2')", "fit");
-        shouldBeEqualToString("regionOverset('region_3')", "overset");
+        shouldBeEqualToString("regionOverset('region_3')", "fit");
 
         debug("Empty content");
         flowContent("no_article");

Modified: trunk/LayoutTests/fast/regions/cssom/webkit-named-flow-overset-expected.txt (164987 => 164988)


--- trunk/LayoutTests/fast/regions/cssom/webkit-named-flow-overset-expected.txt	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/LayoutTests/fast/regions/cssom/webkit-named-flow-overset-expected.txt	2014-03-03 17:16:06 UTC (rev 164988)
@@ -7,10 +7,10 @@
 PASS namedFlow.overset is false
 PASS namedFlow.overset is true
 PASS namedFlow.overset is false
-PASS namedFlow.overset is true
 PASS namedFlow.overset is false
-PASS namedFlow.overset is true
 PASS namedFlow.overset is false
+PASS namedFlow.overset is false
+PASS namedFlow.overset is false
 PASS namedFlow.overset is true
 PASS successfullyParsed is true
 

Modified: trunk/LayoutTests/fast/regions/cssom/webkit-named-flow-overset.html (164987 => 164988)


--- trunk/LayoutTests/fast/regions/cssom/webkit-named-flow-overset.html	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/LayoutTests/fast/regions/cssom/webkit-named-flow-overset.html	2014-03-03 17:16:06 UTC (rev 164988)
@@ -59,8 +59,9 @@
     // Add visual overset, overset should be true.
     document.getElementById("article").style.webkitBoxShadow="0px 50px lime";
 
-    // Overset should be true since the content does not fit in regions
-    shouldBe("namedFlow.overset", "true");
+    // Overset should be false even if the content shadow overflows the last region
+    // since the visual overflow does not influence the overset property.
+    shouldBe("namedFlow.overset", "false");
 
     // Add the third region, overset should be false.
     var region3 = document.createElement("div");
@@ -74,8 +75,9 @@
     // Remove the first region from the flow, overset should be true.
     region.className = "";
 
-    // Overset should be true since the content does not fit the regions
-    shouldBe("namedFlow.overset", "true");
+    // Overset should be false even if the content shadow overflows the last region
+    // since the visual overflow does not influence the overset property.
+    shouldBe("namedFlow.overset", "false");
 
     // Remove the content from the flow, overset should be false.
     document.getElementById("article").className = "";

Modified: trunk/Source/WebCore/ChangeLog (164987 => 164988)


--- trunk/Source/WebCore/ChangeLog	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/ChangeLog	2014-03-03 17:16:06 UTC (rev 164988)
@@ -1,3 +1,72 @@
+2014-03-03  Andrei Bucur  <abu...@adobe.com>
+
+        [CSS Regions] Overset computation is incorrect in some cases
+        https://bugs.webkit.org/show_bug.cgi?id=129032
+
+        Reviewed by Mihnea Ovidenie.
+
+        This patch reworks the way overset is computed for regions and named flows.
+
+        1. Regions overflow no longer trigger an overset changed event. This is because
+        the overflow of a box is contained within the region range of the box. The content
+        edge should be considered the logical bottom position of the content inside the
+        flow thread.
+
+        2. The regions events logic was moved from RenderFlowThread to RenderNamedFlowThread
+        and from RenderRegion to RenderNamedFlowFragment (including the regionOverset property).
+
+        3. The overset value of the named flow is no longer stored in the named flow. It is
+        extracted from the overset of the last region in the chain.
+
+        4. The regions overset is not computed every time the flow thread is laid out which
+        should improve performance for flows with many regions. With the patch, each region
+        computes the overset value during its layout when the flow thread is in the overflow
+        or the final layout phase.
+
+        5. The overset changed event is dispatched only at the end of the layout of the named flows,
+        after all the region overset changes have been considered. This means that the overset
+        event can't be dispatched in the middle of the auto-height processing algorithm that
+        requires multiple layout passes for the flow threads.
+
+        However, the region layout update event dispatch timing was not changed, it is dispatched
+        every time the flow thread has a layout. This preserves the current behavior of the event.
+
+        Tests: The old tests were modified to take into account the change.
+
+        * dom/Element.cpp:
+        (WebCore::Element::webkitRegionOverset):
+        * dom/WebKitNamedFlow.cpp:
+        (WebCore::WebKitNamedFlow::overset):
+        * inspector/InspectorCSSAgent.cpp:
+        (WebCore::InspectorCSSAgent::buildArrayForRegions):
+        * rendering/FlowThreadController.cpp:
+        (WebCore::FlowThreadController::updateFlowThreadsIntoMeasureContentPhase):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::computeOverflow):
+        * rendering/RenderFlowThread.cpp:
+        (WebCore::RenderFlowThread::RenderFlowThread):
+        (WebCore::RenderFlowThread::layout):
+        * rendering/RenderFlowThread.h:
+        * rendering/RenderNamedFlowFragment.cpp:
+        (WebCore::RenderNamedFlowFragment::layoutBlock):
+        (WebCore::RenderNamedFlowFragment::setRegionOversetState):
+        (WebCore::RenderNamedFlowFragment::regionOversetState):
+        (WebCore::RenderNamedFlowFragment::updateOversetState):
+        * rendering/RenderNamedFlowFragment.h:
+        * rendering/RenderNamedFlowThread.cpp:
+        (WebCore::RenderNamedFlowThread::RenderNamedFlowThread):
+        (WebCore::RenderNamedFlowThread::computeOverflow):
+        (WebCore::RenderNamedFlowThread::layout):
+        (WebCore::RenderNamedFlowThread::dispatchNamedFlowEvents):
+        (WebCore::RenderNamedFlowThread::dispatchRegionLayoutUpdateEventIfNeeded):
+        (WebCore::RenderNamedFlowThread::dispatchRegionOversetChangeEventIfNeeded):
+        * rendering/RenderNamedFlowThread.h:
+        There's a new field called m_flowContentBottom that tracks the content bottom of the flow thread
+        after layout. This value is used to compute the overset value of the regions because it's not
+        affected by relative positioning or visual overflow such as shadows.
+        * rendering/RenderRegion.cpp:
+        * rendering/RenderRegion.h:
+
 2014-03-03  Tomas Popela  <tpop...@redhat.com>
 
         [GTK] CodeGeneratorGObject.pm remove usage of undefined variable

Modified: trunk/Source/WebCore/dom/Element.cpp (164987 => 164988)


--- trunk/Source/WebCore/dom/Element.cpp	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/dom/Element.cpp	2014-03-03 17:16:06 UTC (rev 164988)
@@ -2570,7 +2570,7 @@
     if (!document().cssRegionsEnabled() || !renderNamedFlowFragment())
         return undefinedState;
 
-    switch (renderNamedFlowFragment()->regionOversetState()) {
+    switch (regionOversetState()) {
     case RegionFit: {
         DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
         return fitState;

Modified: trunk/Source/WebCore/dom/WebKitNamedFlow.cpp (164987 => 164988)


--- trunk/Source/WebCore/dom/WebKitNamedFlow.cpp	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/dom/WebKitNamedFlow.cpp	2014-03-03 17:16:06 UTC (rev 164988)
@@ -69,7 +69,11 @@
 
     // The renderer may be destroyed or created after the style update.
     // Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
-    return m_parentFlowThread ? m_parentFlowThread->overset() : true;
+    if (!m_parentFlowThread || !m_parentFlowThread->hasRegions())
+        return true;
+
+    const RenderNamedFlowFragment* namedFlowFragment = toRenderNamedFlowFragment(m_parentFlowThread->lastRegion());
+    return namedFlowFragment->regionOversetState() == RegionOverset;
 }
 
 static inline bool inFlowThread(RenderObject* renderer, RenderNamedFlowThread* flowThread)

Modified: trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp (164987 => 164988)


--- trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp	2014-03-03 17:16:06 UTC (rev 164988)
@@ -1196,7 +1196,7 @@
     for (unsigned i = 0; i < regionList->length(); ++i) {
         Inspector::TypeBuilder::CSS::Region::RegionOverset::Enum regionOverset;
 
-        switch (toElement(regionList->item(i))->renderNamedFlowFragment()->regionOversetState()) {
+        switch (toElement(regionList->item(i))->regionOversetState()) {
         case RegionFit:
             regionOverset = Inspector::TypeBuilder::CSS::Region::RegionOverset::Fit;
             break;

Modified: trunk/Source/WebCore/rendering/FlowThreadController.cpp (164987 => 164988)


--- trunk/Source/WebCore/rendering/FlowThreadController.cpp	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/rendering/FlowThreadController.cpp	2014-03-03 17:16:06 UTC (rev 164988)
@@ -246,6 +246,7 @@
         RenderNamedFlowThread* flowRenderer = *iter;
         ASSERT(flowRenderer->inFinalLayoutPhase());
 
+        flowRenderer->dispatchNamedFlowEvents();
         flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseMeasureContent);
     }
 }

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (164987 => 164988)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2014-03-03 17:16:06 UTC (rev 164988)
@@ -1590,9 +1590,6 @@
 
     // Add visual overflow from theme.
     addVisualOverflowFromTheme();
-
-    if (isRenderNamedFlowThread())
-        toRenderNamedFlowThread(this)->computeOversetStateForRegions(oldClientAfterEdge);
 }
 
 void RenderBlock::clearLayoutOverflow()

Modified: trunk/Source/WebCore/rendering/RenderFlowThread.cpp (164987 => 164988)


--- trunk/Source/WebCore/rendering/RenderFlowThread.cpp	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.cpp	2014-03-03 17:16:06 UTC (rev 164988)
@@ -58,8 +58,6 @@
     , m_regionsInvalidated(false)
     , m_regionsHaveUniformLogicalWidth(true)
     , m_regionsHaveUniformLogicalHeight(true)
-    , m_dispatchRegionLayoutUpdateEvent(false)
-    , m_dispatchRegionOversetChangeEvent(false)
     , m_pageLogicalSizeChanged(false)
     , m_layoutPhase(LayoutPhaseMeasureContent)
     , m_needsTwoPhasesLayout(false)
@@ -236,12 +234,6 @@
         if (updateAllLayerToRegionMappings())
             layer()->compositor().setCompositingLayersNeedRebuild();
     }
-
-    if (shouldDispatchRegionLayoutUpdateEvent())
-        dispatchRegionLayoutUpdateEvent();
-    
-    if (shouldDispatchRegionOversetChangeEvent())
-        dispatchRegionOversetChangeEvent();
 }
 
 bool RenderFlowThread::hasCompositingRegionDescendant() const

Modified: trunk/Source/WebCore/rendering/RenderFlowThread.h (164987 => 164988)


--- trunk/Source/WebCore/rendering/RenderFlowThread.h	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.h	2014-03-03 17:16:06 UTC (rev 164988)
@@ -209,7 +209,6 @@
 
 private:
     virtual bool isRenderFlowThread() const override final { return true; }
-    virtual void layout() override final;
 
     // Always create a RenderLayer for the RenderFlowThread so that we
     // can easily avoid drawing the children directly.
@@ -219,6 +218,7 @@
     RenderFlowThread(Document&, PassRef<RenderStyle>);
 
     virtual const char* renderName() const = 0;
+    virtual void layout() override;
 
     // Overridden by columns/pages to set up an initial logical width of the page width even when
     // no regions have been generated yet.
@@ -235,16 +235,6 @@
     void updateLayerToRegionMappings(RenderLayer&, LayerToRegionMap&, RegionToLayerListMap&, bool& needsLayerUpdate);
     void updateRegionForRenderLayer(RenderLayer*, LayerToRegionMap&, RegionToLayerListMap&, bool& needsLayerUpdate);
 
-    void setDispatchRegionLayoutUpdateEvent(bool value) { m_dispatchRegionLayoutUpdateEvent = value; }
-    bool shouldDispatchRegionLayoutUpdateEvent() { return m_dispatchRegionLayoutUpdateEvent; }
-    
-    void setDispatchRegionOversetChangeEvent(bool value) { m_dispatchRegionOversetChangeEvent = value; }
-    bool shouldDispatchRegionOversetChangeEvent() const { return m_dispatchRegionOversetChangeEvent; }
-    
-    // Override if the flow thread implementation supports dispatching events when the flow layout is updated (e.g. for named flows)
-    virtual void dispatchRegionLayoutUpdateEvent() { m_dispatchRegionLayoutUpdateEvent = false; }
-    virtual void dispatchRegionOversetChangeEvent() { m_dispatchRegionOversetChangeEvent = false; }
-
     void initializeRegionsComputedAutoHeight(RenderRegion* = 0);
 
     virtual void autoGenerateRegionsToBlockOffset(LayoutUnit) { };
@@ -339,8 +329,6 @@
     bool m_regionsInvalidated : 1;
     bool m_regionsHaveUniformLogicalWidth : 1;
     bool m_regionsHaveUniformLogicalHeight : 1;
-    bool m_dispatchRegionLayoutUpdateEvent : 1;
-    bool m_dispatchRegionOversetChangeEvent : 1;
     bool m_pageLogicalSizeChanged : 1;
     unsigned m_layoutPhase : 2;
     bool m_needsTwoPhasesLayout : 1;

Modified: trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp (164987 => 164988)


--- trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp	2014-03-03 17:16:06 UTC (rev 164988)
@@ -257,8 +257,10 @@
         if (!isHorizontalWritingMode())
             oldRegionRect = oldRegionRect.transposedRect();
 
-        if (m_flowThread->inOverflowLayoutPhase() || m_flowThread->inFinalLayoutPhase())
+        if (m_flowThread->inOverflowLayoutPhase() || m_flowThread->inFinalLayoutPhase()) {
             computeOverflowFromFlowThread();
+            updateOversetState();
+        }
 
         if (hasAutoLogicalHeight() && m_flowThread->inMeasureContentLayoutPhase()) {
             m_flowThread->invalidateRegions();
@@ -272,6 +274,55 @@
     }
 }
 
+void RenderNamedFlowFragment::setRegionOversetState(RegionOversetState state)
+{
+    ASSERT(generatingElement());
+
+    generatingElement()->setRegionOversetState(state);
+}
+
+RegionOversetState RenderNamedFlowFragment::regionOversetState() const
+{
+    ASSERT(generatingElement());
+
+    if (!isValid())
+        return RegionUndefined;
+
+    return generatingElement()->regionOversetState();
+}
+
+void RenderNamedFlowFragment::updateOversetState()
+{
+    ASSERT(isValid());
+
+    RenderNamedFlowThread* flowThread = namedFlowThread();
+    ASSERT(flowThread && (flowThread->inOverflowLayoutPhase() || flowThread->inFinalLayoutPhase()));
+
+    LayoutUnit flowContentBottom = flowThread->flowContentBottom();
+    bool isHorizontalWritingMode = flowThread->isHorizontalWritingMode();
+
+    LayoutUnit flowMin = flowContentBottom - (isHorizontalWritingMode ? flowThreadPortionRect().y() : flowThreadPortionRect().x());
+    LayoutUnit flowMax = flowContentBottom - (isHorizontalWritingMode ? flowThreadPortionRect().maxY() : flowThreadPortionRect().maxX());
+
+    RegionOversetState previousState = regionOversetState();
+    RegionOversetState state = RegionFit;
+    if (flowMin <= 0)
+        state = RegionEmpty;
+    if (flowMax > 0 && isLastRegion())
+        state = RegionOverset;
+    
+    setRegionOversetState(state);
+
+    // Determine whether the NamedFlow object should dispatch a regionLayoutUpdate event
+    if (previousState != state
+        || state == RegionFit
+        || state == RegionOverset)
+        flowThread->setDispatchRegionLayoutUpdateEvent(true);
+    
+    if (previousState != state)
+        flowThread->setDispatchRegionOversetChangeEvent(true);
+}
+
 void RenderNamedFlowFragment::checkRegionStyle()
 {
     ASSERT(m_flowThread);

Modified: trunk/Source/WebCore/rendering/RenderNamedFlowFragment.h (164987 => 164988)


--- trunk/Source/WebCore/rendering/RenderNamedFlowFragment.h	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/rendering/RenderNamedFlowFragment.h	2014-03-03 17:16:06 UTC (rev 164988)
@@ -104,6 +104,8 @@
 
     bool hasComputedAutoHeight() const { return m_hasComputedAutoHeight; }
 
+    RegionOversetState regionOversetState() const;
+
     virtual void attachRegion() override;
     virtual void detachRegion() override;
 
@@ -127,6 +129,9 @@
 
     bool shouldHaveAutoLogicalHeight() const;
 
+    void updateOversetState();
+    void setRegionOversetState(RegionOversetState);
+
     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) override;
 
     struct ObjectRegionStyleInfo {

Modified: trunk/Source/WebCore/rendering/RenderNamedFlowThread.cpp (164987 => 164988)


--- trunk/Source/WebCore/rendering/RenderNamedFlowThread.cpp	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/rendering/RenderNamedFlowThread.cpp	2014-03-03 17:16:06 UTC (rev 164988)
@@ -47,8 +47,9 @@
 
 RenderNamedFlowThread::RenderNamedFlowThread(Document& document, PassRef<RenderStyle> style, PassRef<WebKitNamedFlow> namedFlow)
     : RenderFlowThread(document, std::move(style))
-    , m_overset(true)
     , m_hasRegionsWithStyling(false)
+    , m_dispatchRegionLayoutUpdateEvent(false)
+    , m_dispatchRegionOversetChangeEvent(false)
     , m_namedFlow(std::move(namedFlow))
     , m_regionLayoutUpdateEventTimer(this, &RenderNamedFlowThread::regionLayoutUpdateEventTimerFired)
     , m_regionOversetChangeEventTimer(this, &RenderNamedFlowThread::regionOversetChangeEventTimerFired)
@@ -354,53 +355,33 @@
     return visualOverflowRect;
 }
 
-void RenderNamedFlowThread::computeOversetStateForRegions(LayoutUnit oldClientAfterEdge)
+void RenderNamedFlowThread::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats)
 {
-    LayoutUnit height = oldClientAfterEdge;
+    RenderFlowThread::computeOverflow(oldClientAfterEdge, recomputeFloats);
 
-    // FIXME: the visual overflow of middle region (if it is the last one to contain any content in a render flow thread)
-    // might not be taken into account because the render flow thread height is greater that that regions height + its visual overflow
-    // because of how computeLogicalHeight is implemented for RenderNamedFlowThread (as a sum of all regions height).
-    // This means that the middle region will be marked as fit (even if it has visual overflow flowing into the next region)
-    if (hasRenderOverflow()
-        && ( (isHorizontalWritingMode() && visualOverflowRect().maxY() > clientBoxRect().maxY())
-            || (!isHorizontalWritingMode() && visualOverflowRect().maxX() > clientBoxRect().maxX())))
-        height = isHorizontalWritingMode() ? visualOverflowRect().maxY() : visualOverflowRect().maxX();
+    m_flowContentBottom = oldClientAfterEdge;
+}
 
-    RenderNamedFlowFragment* lastFragment = toRenderNamedFlowFragment(lastRegion());
-    for (auto& namedFlowFragment : m_regionList) {
-        LayoutUnit flowMin = height - (isHorizontalWritingMode() ? namedFlowFragment->flowThreadPortionRect().y() : namedFlowFragment->flowThreadPortionRect().x());
-        LayoutUnit flowMax = height - (isHorizontalWritingMode() ? namedFlowFragment->flowThreadPortionRect().maxY() : namedFlowFragment->flowThreadPortionRect().maxX());
-        RegionOversetState previousState = namedFlowFragment->regionOversetState();
-        RegionOversetState state = RegionFit;
-        if (flowMin <= 0)
-            state = RegionEmpty;
-        if (flowMax > 0 && namedFlowFragment == lastFragment)
-            state = RegionOverset;
-        namedFlowFragment->setRegionOversetState(state);
-        // determine whether the NamedFlow object should dispatch a regionLayoutUpdate event
-        // FIXME: currently it cannot determine whether a region whose regionOverset state remained either "fit" or "overset" has actually
-        // changed, so it just assumes that the NamedFlow should dispatch the event
-        if (previousState != state
-            || state == RegionFit
-            || state == RegionOverset)
-            setDispatchRegionLayoutUpdateEvent(true);
-        
-        if (previousState != state)
-            setDispatchRegionOversetChangeEvent(true);
-    }
-    
+void RenderNamedFlowThread::layout()
+{
+    RenderFlowThread::layout();
+
     // If the number of regions has changed since we last computed the overset property, schedule the regionOversetChange event.
     if (previousRegionCountChanged()) {
         setDispatchRegionOversetChangeEvent(true);
         updatePreviousRegionCount();
     }
 
-    // With the regions overflow state computed we can also set the overset flag for the named flow.
-    // If there are no valid regions in the chain, overset is true.
-    m_overset = lastFragment ? lastFragment->regionOversetState() == RegionOverset : true;
+    dispatchRegionLayoutUpdateEventIfNeeded();
 }
 
+void RenderNamedFlowThread::dispatchNamedFlowEvents()
+{
+    ASSERT(inFinalLayoutPhase());
+
+    dispatchRegionOversetChangeEventIfNeeded();
+}
+
 void RenderNamedFlowThread::checkInvalidRegions()
 {
     Vector<RenderNamedFlowFragment*> newValidFragments;
@@ -529,18 +510,24 @@
     return toElement(originalParent)->renderer()->isChildAllowed(child, style);
 }
 
-void RenderNamedFlowThread::dispatchRegionLayoutUpdateEvent()
+void RenderNamedFlowThread::dispatchRegionLayoutUpdateEventIfNeeded()
 {
-    RenderFlowThread::dispatchRegionLayoutUpdateEvent();
+    if (!m_dispatchRegionLayoutUpdateEvent)
+        return;
+
+    m_dispatchRegionLayoutUpdateEvent = false;
     InspectorInstrumentation::didUpdateRegionLayout(&document(), &namedFlow());
 
     if (!m_regionLayoutUpdateEventTimer.isActive() && namedFlow().hasEventListeners())
         m_regionLayoutUpdateEventTimer.startOneShot(0);
 }
 
-void RenderNamedFlowThread::dispatchRegionOversetChangeEvent()
+void RenderNamedFlowThread::dispatchRegionOversetChangeEventIfNeeded()
 {
-    RenderFlowThread::dispatchRegionOversetChangeEvent();
+    if (!m_dispatchRegionOversetChangeEvent)
+        return;
+
+    m_dispatchRegionOversetChangeEvent = false;
     InspectorInstrumentation::didChangeRegionOverset(&document(), &namedFlow());
     
     if (!m_regionOversetChangeEventTimer.isActive() && namedFlow().hasEventListeners())

Modified: trunk/Source/WebCore/rendering/RenderNamedFlowThread.h (164987 => 164988)


--- trunk/Source/WebCore/rendering/RenderNamedFlowThread.h	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/rendering/RenderNamedFlowThread.h	2014-03-03 17:16:06 UTC (rev 164988)
@@ -70,9 +70,6 @@
 
     LayoutRect decorationsClipRectForBoxInNamedFlowFragment(const RenderBox&, RenderNamedFlowFragment&) const;
 
-    bool overset() const { return m_overset; }
-    void computeOversetStateForRegions(LayoutUnit oldClientAfterEdge);
-
     void registerNamedFlowContentElement(Element&);
     void unregisterNamedFlowContentElement(Element&);
     const NamedFlowContentElements& contentElements() const { return m_contentElements; }
@@ -91,6 +88,12 @@
 
     virtual void removeFlowChildInfo(RenderObject*) override final;
 
+    LayoutUnit flowContentBottom() const { return m_flowContentBottom; }
+    void dispatchNamedFlowEvents();
+
+    void setDispatchRegionLayoutUpdateEvent(bool value) { m_dispatchRegionLayoutUpdateEvent = value; }
+    void setDispatchRegionOversetChangeEvent(bool value) { m_dispatchRegionOversetChangeEvent = value; }
+
 protected:
     void setMarkForDestruction();
     void resetMarkForDestruction();
@@ -99,9 +102,11 @@
     virtual const char* renderName() const override;
     virtual bool isRenderNamedFlowThread() const override { return true; }
     virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
+    virtual void computeOverflow(LayoutUnit, bool = false) override;
+    virtual void layout() override final;
 
-    virtual void dispatchRegionLayoutUpdateEvent() override;
-    virtual void dispatchRegionOversetChangeEvent() override;
+    void dispatchRegionLayoutUpdateEventIfNeeded();
+    void dispatchRegionOversetChangeEventIfNeeded();
 
     bool dependsOn(RenderNamedFlowThread* otherRenderFlowThread) const;
     void addDependencyOnFlowThread(RenderNamedFlowThread*);
@@ -137,14 +142,17 @@
 
     RenderRegionList m_invalidRegionList;
 
-    bool m_overset : 1;
     bool m_hasRegionsWithStyling : 1;
+    bool m_dispatchRegionLayoutUpdateEvent : 1;
+    bool m_dispatchRegionOversetChangeEvent : 1;
 
     // The DOM Object that represents a named flow.
     Ref<WebKitNamedFlow> m_namedFlow;
 
     Timer<RenderNamedFlowThread> m_regionLayoutUpdateEventTimer;
     Timer<RenderNamedFlowThread> m_regionOversetChangeEventTimer;
+
+    LayoutUnit m_flowContentBottom;
 };
 
 RENDER_OBJECT_TYPE_CASTS(RenderNamedFlowThread, isRenderNamedFlowThread())

Modified: trunk/Source/WebCore/rendering/RenderRegion.cpp (164987 => 164988)


--- trunk/Source/WebCore/rendering/RenderRegion.cpp	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/rendering/RenderRegion.cpp	2014-03-03 17:16:06 UTC (rev 164988)
@@ -181,23 +181,6 @@
     return clipRect;
 }
 
-RegionOversetState RenderRegion::regionOversetState() const
-{
-    ASSERT(generatingElement());
-
-    if (!isValid())
-        return RegionUndefined;
-
-    return generatingElement()->regionOversetState();
-}
-
-void RenderRegion::setRegionOversetState(RegionOversetState state)
-{
-    ASSERT(generatingElement());
-
-    generatingElement()->setRegionOversetState(state);
-}
-
 LayoutUnit RenderRegion::pageLogicalTopForOffset(LayoutUnit /* offset */) const
 {
     return flowThread()->isHorizontalWritingMode() ? flowThreadPortionRect().y() : flowThreadPortionRect().x();

Modified: trunk/Source/WebCore/rendering/RenderRegion.h (164987 => 164988)


--- trunk/Source/WebCore/rendering/RenderRegion.h	2014-03-03 17:06:45 UTC (rev 164987)
+++ trunk/Source/WebCore/rendering/RenderRegion.h	2014-03-03 17:16:06 UTC (rev 164988)
@@ -79,9 +79,6 @@
     bool isLastRegion() const;
     bool shouldClipFlowThreadContent() const;
 
-    RegionOversetState regionOversetState() const;
-    void setRegionOversetState(RegionOversetState);
-
     // These methods represent the width and height of a "page" and for a RenderRegion they are just the
     // content width and content height of a region. For RenderRegionSets, however, they will be the width and
     // height of a single column or page in the set.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to