Title: [110731] trunk
Revision
110731
Author
commit-qu...@webkit.org
Date
2012-03-14 12:48:06 -0700 (Wed, 14 Mar 2012)

Log Message

[CSSRegions][CSSOM] Implement regionLayoutEvent
https://bugs.webkit.org/show_bug.cgi?id=78882

Patch by Raul Hudea <rhu...@adobe.com> on 2012-03-14
Reviewed by David Hyatt.

Source/WebCore:

Adding the regionLayoutEvent that is dispatch for all regions after each flow-thread layout.

Tests: fast/regions/region-event-add-to-flow.html
       fast/regions/region-event-remove-from-dom.html
       fast/regions/region-event-remove-from-flow.html
       fast/regions/region-event.html

* dom/Document.cpp:
(WebCore::Document::addListenerTypeIfNeeded): Added check for regionLayoutUpdate listeners
* dom/Document.h:
* dom/EventNames.h:
(WebCore):
* dom/Node.cpp:
(WebCore::Node::dispatchRegionLayoutUpdateEvent):
(WebCore):
* dom/Node.h:
(Node):
* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::RenderFlowThread):
(WebCore::RenderFlowThread::layout): Start the event dispatch timer but only if there are regionLayoutUpdate listeners and there is at least one region that had its layout updated.
(WebCore::RenderFlowThread::computeOverflowStateForRegions): Mark regions that might had a layout update
(WebCore::RenderFlowThread::regionLayoutUpdateEventTimerFired):
(WebCore):
* rendering/RenderFlowThread.h:
* rendering/RenderRegion.cpp:
(WebCore::RenderRegion::RenderRegion):
* rendering/RenderRegion.h:
(WebCore::RenderRegion::setDispatchRegionLayoutUpdateEvent):
(WebCore::RenderRegion::shouldDispatchRegionLayoutUpdateEvent):
(RenderRegion):

LayoutTests:

* fast/regions/region-event-add-to-flow-expected.txt: Added.
* fast/regions/region-event-add-to-flow.html: Added.
* fast/regions/region-event-expected.txt: Added.
* fast/regions/region-event-remove-from-dom-expected.txt: Added.
* fast/regions/region-event-remove-from-dom.html: Added.
* fast/regions/region-event-remove-from-flow-expected.txt: Added.
* fast/regions/region-event-remove-from-flow.html: Added.
* fast/regions/region-event.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (110730 => 110731)


--- trunk/LayoutTests/ChangeLog	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/LayoutTests/ChangeLog	2012-03-14 19:48:06 UTC (rev 110731)
@@ -1,3 +1,19 @@
+2012-03-14  Raul Hudea  <rhu...@adobe.com>
+
+        [CSSRegions][CSSOM] Implement regionLayoutEvent
+        https://bugs.webkit.org/show_bug.cgi?id=78882
+
+        Reviewed by David Hyatt.
+
+        * fast/regions/region-event-add-to-flow-expected.txt: Added.
+        * fast/regions/region-event-add-to-flow.html: Added.
+        * fast/regions/region-event-expected.txt: Added.
+        * fast/regions/region-event-remove-from-dom-expected.txt: Added.
+        * fast/regions/region-event-remove-from-dom.html: Added.
+        * fast/regions/region-event-remove-from-flow-expected.txt: Added.
+        * fast/regions/region-event-remove-from-flow.html: Added.
+        * fast/regions/region-event.html: Added.
+
 2012-03-14  Ojan Vafai  <o...@chromium.org>
 
         Rebaseline chromium-lion tests that have "MISSING" results.

Added: trunk/LayoutTests/fast/regions/region-event-add-to-flow-expected.txt (0 => 110731)


--- trunk/LayoutTests/fast/regions/region-event-add-to-flow-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/region-event-add-to-flow-expected.txt	2012-03-14 19:48:06 UTC (rev 110731)
@@ -0,0 +1,12 @@
+Tests regionLayoutEvent
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+ Flow content
+PASS event.target.id is "region_1"
+PASS event.target.id is "region_1"
+PASS event.target.id is "region_2"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/regions/region-event-add-to-flow.html (0 => 110731)


--- trunk/LayoutTests/fast/regions/region-event-add-to-flow.html	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/region-event-add-to-flow.html	2012-03-14 19:48:06 UTC (rev 110731)
@@ -0,0 +1,75 @@
+<html>
+<head>
+<script src=""
+<style>
+#article {
+    -webkit-flow-into: article;
+    border: 2px solid black;
+}
+#region_1 {
+    -webkit-flow-from: no_article;
+    overflow:hidden;
+    display:inline-block;
+    vertical-align:top;
+    margin:10px;
+}
+.block {
+   display:block;
+}
+#region_1, #region_2 { height:110px; width:200px; margin: 5px;}
+</style>
+</head>
+<body>
+<div id="description" class="block"></div>
+<div id="article">
+    <div>
+        <div id="content" style="height: 200px; background-color: green;"></div>
+    </div>
+</div>
+
+<div id="region_1"></div>
+<div id="region_2"></div>
+
+<div id="console" class="block"></div>
+
+<script>
+    description("Tests regionLayoutEvent")
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+    window.jsTestIsAsync = true;
+    function flowContent(region, flowName) {
+        var r = document.getElementById(region);
+        r.style.webkitFlowFrom = flowName;
+    }
+    var count = 0;
+    function region1Updated(event) {
+        shouldBeEqualToString("event.target.id", "region_1");
+        if (++count > 1) {
+           var r1 = document.getElementById("region_1");
+           r1.removeEventListener("webkitRegionLayoutUpdate", region1Updated);
+           return;
+        }
+        flowContent("region_2", "article"); // this will trigger a new round of events due to layout
+    }
+    function region2Updated(event) {
+        shouldBeEqualToString("event.target.id", "region_2");
+        var r2 = document.getElementById("region_2");
+        r2.removeEventListener("webkitRegionLayoutUpdate", region2Updated);
+        // this should be reached after region_2 is removed from flow
+        finishJSTest();
+    }
+    function startTest() {
+        var r1 = document.getElementById("region_1");
+        var r2 = document.getElementById("region_2");
+        r1.addEventListener("webkitRegionLayoutUpdate", region1Updated);
+        r2.addEventListener("webkitRegionLayoutUpdate", region2Updated);
+        debug("Flow content");
+        flowContent("region_1", "article");
+    }
+    window.addEventListener("load", startTest);
+</script>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/regions/region-event-expected.txt (0 => 110731)


--- trunk/LayoutTests/fast/regions/region-event-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/region-event-expected.txt	2012-03-14 19:48:06 UTC (rev 110731)
@@ -0,0 +1,12 @@
+Tests regionLayoutEvent
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+ 
+Flow content
+PASS event.target.id is "region_1"
+PASS event.target.id is "region_2"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/regions/region-event-remove-from-dom-expected.txt (0 => 110731)


--- trunk/LayoutTests/fast/regions/region-event-remove-from-dom-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/region-event-remove-from-dom-expected.txt	2012-03-14 19:48:06 UTC (rev 110731)
@@ -0,0 +1,13 @@
+Tests regionLayoutEvent
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+ Flow content
+PASS event.target.id is "region_1"
+PASS event.target.id is "region_2"
+Removing region_2 from DOM
+PASS event.target.id is "region_1"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/regions/region-event-remove-from-dom.html (0 => 110731)


--- trunk/LayoutTests/fast/regions/region-event-remove-from-dom.html	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/region-event-remove-from-dom.html	2012-03-14 19:48:06 UTC (rev 110731)
@@ -0,0 +1,84 @@
+<html>
+<head>
+<script src=""
+<style>
+#article {
+    -webkit-flow-into: article;
+    border: 2px solid black;
+}
+#region_1, #region_2{
+    -webkit-flow-from: no_article;
+    overflow:hidden;
+    display:inline-block;
+    vertical-align:top;
+    margin:10px;
+}
+.block {
+   display:block;
+}
+#region_1, #region_2 { height:110px; width:200px; margin: 5px;}
+</style>
+</head>
+<body>
+<div id="description" class="block"></div>
+<div id="article">
+    <div>
+        <div id="content" style="height: 200px; background-color: green;"></div>
+    </div>
+</div>
+
+<div id="region_1"></div>
+<div id="container2">
+    <div id="region_2"></div>
+</div>
+
+<div id="console" class="block"></div>
+
+<script>
+    description("Tests regionLayoutEvent")
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+    window.jsTestIsAsync = true;
+    function flowContent(flowName) {
+        var r = document.getElementById("region_1");
+        r.style.webkitFlowFrom = flowName;
+        r = document.getElementById("region_2");
+        r.style.webkitFlowFrom = flowName;
+    }
+    var count = 0;
+    function region1Updated(event) {
+        shouldBeEqualToString("event.target.id", "region_1");
+        if (++count > 1) {
+           var r1 = document.getElementById("region_1");
+           r1.removeEventListener("webkitRegionLayoutUpdate", region1Updated);
+           // this should be reached after region_2 is removed from DOM
+           finishJSTest();
+        }
+    }
+    function region2Updated(event) {
+        shouldBeEqualToString("event.target.id", "region_2");
+        var r2 = document.getElementById("region_2");
+        r2.removeEventListener("webkitRegionLayoutUpdate", region2Updated);
+        r2.addEventListener("webkitRegionLayoutUpdate", regionUpdated);
+        var c2 = document.getElementById("container2");
+        debug("Removing region_2 from DOM");
+        c2.innerHTML = ""; // this will trigger a new round of events due to layout
+    }
+    function regionUpdated(event) {
+        testFailed(event.target.id + " event shouldn't have been dispatched" );
+    }
+    function startTest() {
+        var r1 = document.getElementById("region_1");
+        var r2 = document.getElementById("region_2");
+        r1.addEventListener("webkitRegionLayoutUpdate", region1Updated);
+        r2.addEventListener("webkitRegionLayoutUpdate", region2Updated);
+        debug("Flow content");
+        flowContent("article");
+    }
+    window.addEventListener("load", startTest);
+</script>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/regions/region-event-remove-from-flow-expected.txt (0 => 110731)


--- trunk/LayoutTests/fast/regions/region-event-remove-from-flow-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/region-event-remove-from-flow-expected.txt	2012-03-14 19:48:06 UTC (rev 110731)
@@ -0,0 +1,14 @@
+Tests regionLayoutEvent
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+ 
+Flow content
+PASS event.target.id is "region_1"
+PASS event.target.id is "region_2"
+Removing region_2 from flow
+PASS event.target.id is "region_1"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/regions/region-event-remove-from-flow.html (0 => 110731)


--- trunk/LayoutTests/fast/regions/region-event-remove-from-flow.html	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/region-event-remove-from-flow.html	2012-03-14 19:48:06 UTC (rev 110731)
@@ -0,0 +1,81 @@
+<html>
+<head>
+<script src=""
+<style>
+#article {
+    -webkit-flow-into: article;
+    border: 2px solid black;
+}
+#region_1, #region_2{
+    -webkit-flow-from: no_article;
+    overflow:hidden;
+    display:inline-block;
+    vertical-align:top;
+    margin:10px;
+}
+.block {
+   display:block;
+}
+#region_1, #region_2 { height:110px; width:200px; margin: 5px;}
+</style>
+</head>
+<body>
+<div id="description" class="block"></div>
+<div id="article">
+    <div>
+        <div id="content" style="height: 200px; background-color: green;"></div>
+    </div>
+</div>
+
+<div id="region_1"></div>
+<div id="region_2"></div>
+
+<div id="console" class="block"></div>
+
+<script>
+    description("Tests regionLayoutEvent")
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+    window.jsTestIsAsync = true;
+    function flowContent(flowName) {
+        var r = document.getElementById("region_1");
+        r.style.webkitFlowFrom = flowName;
+        r = document.getElementById("region_2");
+        r.style.webkitFlowFrom = flowName;
+    }
+    var count = 0;
+    function region1Updated(event) {
+        shouldBeEqualToString("event.target.id", "region_1");
+        if (++count > 1) {
+           var r1 = document.getElementById("region_1");
+           r1.removeEventListener("webkitRegionLayoutUpdate", region1Updated);
+           // this should be reached after region_2 is removed from flow
+           finishJSTest();
+        }
+    }
+    function region2Updated(event) {
+        shouldBeEqualToString("event.target.id", "region_2");
+        var r2 = document.getElementById("region_2");
+        r2.removeEventListener("webkitRegionLayoutUpdate", region2Updated);
+        r2.addEventListener("webkitRegionLayoutUpdate", regionUpdated);
+        debug("Removing region_2 from flow");
+        r2.style.webkitFlowFrom = "none"; // this will trigger a new round of events due to layout
+    }
+    function regionUpdated(event) {
+        testFailed(event.target.id + " event shouldn't have been dispatched" );
+    }
+    function startTest() {
+        var r1 = document.getElementById("region_1");
+        var r2 = document.getElementById("region_2");
+        r1.addEventListener("webkitRegionLayoutUpdate", region1Updated);
+        r2.addEventListener("webkitRegionLayoutUpdate", region2Updated);
+        debug("Flow content");
+        flowContent("article");
+    }
+    window.addEventListener("load", startTest);
+</script>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/regions/region-event.html (0 => 110731)


--- trunk/LayoutTests/fast/regions/region-event.html	                        (rev 0)
+++ trunk/LayoutTests/fast/regions/region-event.html	2012-03-14 19:48:06 UTC (rev 110731)
@@ -0,0 +1,68 @@
+<html>
+<head>
+<script src=""
+<style>
+#article {
+    -webkit-flow-into: article;
+    border: 2px solid black;
+}
+#region_1, #region_2{
+    -webkit-flow-from: no_article;
+    overflow:hidden;
+    display:inline-block;
+    vertical-align:top;
+    margin:10px;
+}
+.block {
+   display:block;
+}
+#region_1, #region_2 { height:110px; width:200px}
+</style>
+</head>
+<body>
+<div id="description" class="block"></div>
+<div id="article">
+    <div>
+        <div id="content" style="height: 200px; background-color: green;"></div>
+    </div>
+</div>
+
+<div id="region_1"></div>
+<div id="region_2"></div>
+
+<div id="console" class="block"></div>
+
+<script>
+    description("Tests regionLayoutEvent")
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+    window.jsTestIsAsync = true;
+    function flowContent(flowName) {
+        var r = document.getElementById("region_1");
+        r.style.webkitFlowFrom = flowName;
+        r = document.getElementById("region_2");
+        r.style.webkitFlowFrom = flowName;
+    }
+    function region1Updated(event) {
+        shouldBeEqualToString("event.target.id", "region_1");
+    }
+    function region2Updated(event) {
+        shouldBeEqualToString("event.target.id", "region_2");
+        finishJSTest();
+    }
+    function startTest() {
+        var r1 = document.getElementById("region_1");
+        var r2 = document.getElementById("region_2");
+        r1.addEventListener("webkitRegionLayoutUpdate", region1Updated);
+        r2.addEventListener("webkitRegionLayoutUpdate", region2Updated);
+        debug("Flow content");
+        flowContent("article");
+    }
+    //startTest();
+    window.addEventListener("load", startTest);
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (110730 => 110731)


--- trunk/Source/WebCore/ChangeLog	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/Source/WebCore/ChangeLog	2012-03-14 19:48:06 UTC (rev 110731)
@@ -1,3 +1,41 @@
+2012-03-14  Raul Hudea  <rhu...@adobe.com>
+
+        [CSSRegions][CSSOM] Implement regionLayoutEvent
+        https://bugs.webkit.org/show_bug.cgi?id=78882
+
+        Reviewed by David Hyatt.
+
+        Adding the regionLayoutEvent that is dispatch for all regions after each flow-thread layout.
+
+        Tests: fast/regions/region-event-add-to-flow.html
+               fast/regions/region-event-remove-from-dom.html
+               fast/regions/region-event-remove-from-flow.html
+               fast/regions/region-event.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::addListenerTypeIfNeeded): Added check for regionLayoutUpdate listeners
+        * dom/Document.h:
+        * dom/EventNames.h:
+        (WebCore):
+        * dom/Node.cpp:
+        (WebCore::Node::dispatchRegionLayoutUpdateEvent):
+        (WebCore):
+        * dom/Node.h:
+        (Node):
+        * rendering/RenderFlowThread.cpp:
+        (WebCore::RenderFlowThread::RenderFlowThread):
+        (WebCore::RenderFlowThread::layout): Start the event dispatch timer but only if there are regionLayoutUpdate listeners and there is at least one region that had its layout updated.
+        (WebCore::RenderFlowThread::computeOverflowStateForRegions): Mark regions that might had a layout update
+        (WebCore::RenderFlowThread::regionLayoutUpdateEventTimerFired):
+        (WebCore):
+        * rendering/RenderFlowThread.h:
+        * rendering/RenderRegion.cpp:
+        (WebCore::RenderRegion::RenderRegion):
+        * rendering/RenderRegion.h:
+        (WebCore::RenderRegion::setDispatchRegionLayoutUpdateEvent):
+        (WebCore::RenderRegion::shouldDispatchRegionLayoutUpdateEvent):
+        (RenderRegion):
+
 2012-03-14  Pierre Rossi  <pierre.ro...@gmail.com>
 
         [Qt] Add support for vertical sliders in mobile theme

Modified: trunk/Source/WebCore/dom/Document.cpp (110730 => 110731)


--- trunk/Source/WebCore/dom/Document.cpp	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/Source/WebCore/dom/Document.cpp	2012-03-14 19:48:06 UTC (rev 110731)
@@ -3799,6 +3799,8 @@
 #endif
     else if (eventType == eventNames().scrollEvent)
         addListenerType(SCROLL_LISTENER);
+    else if (eventType == eventNames().webkitRegionLayoutUpdateEvent)
+        addListenerType(REGIONLAYOUTUPDATE_LISTENER);
 }
 
 CSSStyleDeclaration* Document::getOverrideStyle(Element*, const String&)

Modified: trunk/Source/WebCore/dom/Document.h (110730 => 110731)


--- trunk/Source/WebCore/dom/Document.h	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/Source/WebCore/dom/Document.h	2012-03-14 19:48:06 UTC (rev 110731)
@@ -773,7 +773,8 @@
         TRANSITIONEND_LISTENER               = 0x800,
         BEFORELOAD_LISTENER                  = 0x1000,
         TOUCH_LISTENER                       = 0x2000,
-        SCROLL_LISTENER                      = 0x4000
+        SCROLL_LISTENER                      = 0x4000,
+        REGIONLAYOUTUPDATE_LISTENER          = 0x8000
     };
 
     bool hasListenerType(ListenerType listenerType) const { return (m_listenerTypes & listenerType); }

Modified: trunk/Source/WebCore/dom/EventNames.h (110730 => 110731)


--- trunk/Source/WebCore/dom/EventNames.h	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/Source/WebCore/dom/EventNames.h	2012-03-14 19:48:06 UTC (rev 110731)
@@ -212,6 +212,8 @@
     \
     macro(webkitpointerlocklost) \
     \
+    macro(webkitRegionLayoutUpdate) \
+    \
 
 // end of DOM_EVENT_NAMES_FOR_EACH
 

Modified: trunk/Source/WebCore/dom/Node.cpp (110730 => 110731)


--- trunk/Source/WebCore/dom/Node.cpp	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/Source/WebCore/dom/Node.cpp	2012-03-14 19:48:06 UTC (rev 110731)
@@ -2742,6 +2742,16 @@
     return EventDispatcher::dispatchEvent(this, EventDispatchMediator::create(event));
 }
 
+void Node::dispatchRegionLayoutUpdateEvent()
+{
+    ASSERT(!eventDispatchForbidden());
+
+    if (!document()->hasListenerType(Document::REGIONLAYOUTUPDATE_LISTENER))
+        return;
+
+    dispatchScopedEvent(UIEvent::create(eventNames().webkitRegionLayoutUpdateEvent, true, true, document()->defaultView(), 0));
+}
+
 void Node::dispatchSubtreeModifiedEvent()
 {
     if (isInShadowTree())

Modified: trunk/Source/WebCore/dom/Node.h (110730 => 110731)


--- trunk/Source/WebCore/dom/Node.h	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/Source/WebCore/dom/Node.h	2012-03-14 19:48:06 UTC (rev 110731)
@@ -569,6 +569,8 @@
 
     virtual void handleLocalEvents(Event*);
 
+    void dispatchRegionLayoutUpdateEvent();
+
     void dispatchSubtreeModifiedEvent();
     void dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent);
     void dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Node> oldFocusedNode);

Modified: trunk/Source/WebCore/rendering/RenderFlowThread.cpp (110730 => 110731)


--- trunk/Source/WebCore/rendering/RenderFlowThread.cpp	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.cpp	2012-03-14 19:48:06 UTC (rev 110731)
@@ -52,6 +52,7 @@
     , m_regionsHaveUniformLogicalWidth(true)
     , m_regionsHaveUniformLogicalHeight(true)
     , m_overflow(false)
+    , m_regionLayoutUpdateEventTimer(this, &RenderFlowThread::regionLayoutUpdateEventTimerFired)
 {
     ASSERT(node->document()->cssRegionsEnabled());
     setIsAnonymous(false);
@@ -399,6 +400,15 @@
     LayoutStateMaintainer statePusher(view(), this, regionsChanged);
     RenderBlock::layout();
     statePusher.pop();
+    if (document()->hasListenerType(Document::REGIONLAYOUTUPDATE_LISTENER) && !m_regionLayoutUpdateEventTimer.isActive())
+        for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
+            RenderRegion* region = *iter;
+            if (region->shouldDispatchRegionLayoutUpdateEvent()) {
+                // at least one region needs to dispatch the event
+                m_regionLayoutUpdateEventTimer.startOneShot(0);
+                break;
+            }
+        }
 }
 
 void RenderFlowThread::computeLogicalWidth()
@@ -892,12 +902,20 @@
         }
         LayoutUnit flowMin = height - (isHorizontalWritingMode() ? region->regionRect().y() : region->regionRect().x());
         LayoutUnit flowMax = height - (isHorizontalWritingMode() ? region->regionRect().maxY() : region->regionRect().maxX());
+        RenderRegion::RegionState previousState = region->regionState();
         RenderRegion::RegionState state = RenderRegion::RegionFit;
         if (flowMin <= 0)
             state = RenderRegion::RegionEmpty;
         if (flowMax > 0)
             state = RenderRegion::RegionOverflow;
         region->setRegionState(state);
+        // determine whether this region should dispatch a regionLayoutUpdate event
+        // FIXME: currently it cannot determine whether a region whose regionOverflow state remained either "fit" or "overflow" has actually
+        // changed, so it just assumes that those region should dispatch the event
+        if (previousState != state
+            || state == RenderRegion::RegionFit
+            || state == RenderRegion::RegionOverflow)
+            region->setDispatchRegionLayoutUpdateEvent(true);
     }
 
     // With the regions overflow state computed we can also set the overflow for the named flow.
@@ -905,5 +923,34 @@
     m_overflow = lastReg && (lastReg->regionState() == RenderRegion::RegionOverflow);
 }
 
+void RenderFlowThread::regionLayoutUpdateEventTimerFired(Timer<RenderFlowThread>*)
+{
+    // Create a copy of region nodes, to protect them for being destroyed in the event listener
+    Vector<RefPtr<Node> > regionNodes;
+    regionNodes.reserveCapacity(m_regionList.size());
+    for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
+        RenderRegion* region = *iter;
+        ASSERT(region->node() && region->node()->isElementNode());
+        // dispatch the event only for marked regions and only for those who have a listener
+        if (region->shouldDispatchRegionLayoutUpdateEvent()) {
+            regionNodes.append(region->node());
+            // clear the dispatch flag here, as it is possible to be set again due to event listeners
+            region->setDispatchRegionLayoutUpdateEvent(false);
+        }
+    }
+    for (Vector<RefPtr<Node> >::const_iterator it = regionNodes.begin(); it != regionNodes.end(); ++it) {
+        RefPtr<Node> node = *it;
+        RefPtr<Document> document = node->document();
+        if (!document)
+            continue;
+        RenderObject* renderer = node->renderer();
+        if (renderer && renderer->isRenderRegion()) {
+            node->dispatchRegionLayoutUpdateEvent();
+            // Layout needs to be uptodate after each event listener
+            document->updateLayoutIgnorePendingStylesheets();
+        }
+    }
+}
+
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/rendering/RenderFlowThread.h (110730 => 110731)


--- trunk/Source/WebCore/rendering/RenderFlowThread.h	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/Source/WebCore/rendering/RenderFlowThread.h	2012-03-14 19:48:06 UTC (rev 110731)
@@ -146,6 +146,7 @@
     void checkInvalidRegions();
 
     bool shouldRepaint(const LayoutRect&) const;
+    void regionLayoutUpdateEventTimerFired(Timer<RenderFlowThread>*);
 
     typedef ListHashSet<RenderObject*> FlowThreadChildList;
     FlowThreadChildList m_flowThreadChildList;
@@ -199,6 +200,7 @@
     bool m_regionsHaveUniformLogicalHeight;
     bool m_overflow;
     RefPtr<WebKitNamedFlow> m_namedFlow;
+    Timer<RenderFlowThread> m_regionLayoutUpdateEventTimer;
 };
 
 inline RenderFlowThread* toRenderFlowThread(RenderObject* object)

Modified: trunk/Source/WebCore/rendering/RenderRegion.cpp (110730 => 110731)


--- trunk/Source/WebCore/rendering/RenderRegion.cpp	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/Source/WebCore/rendering/RenderRegion.cpp	2012-03-14 19:48:06 UTC (rev 110731)
@@ -48,6 +48,7 @@
     , m_isValid(false)
     , m_hasCustomRegionStyle(false)
     , m_regionState(RegionUndefined)
+    , m_dispatchRegionLayoutUpdateEvent(false)
 {
     ASSERT(node->document()->cssRegionsEnabled());
 }

Modified: trunk/Source/WebCore/rendering/RenderRegion.h (110730 => 110731)


--- trunk/Source/WebCore/rendering/RenderRegion.h	2012-03-14 19:45:31 UTC (rev 110730)
+++ trunk/Source/WebCore/rendering/RenderRegion.h	2012-03-14 19:48:06 UTC (rev 110731)
@@ -91,6 +91,8 @@
 
     RegionState regionState() const { return isValid() ? m_regionState : RegionUndefined; }
     void setRegionState(RegionState regionState) { m_regionState = regionState; }
+    void setDispatchRegionLayoutUpdateEvent(bool value) { m_dispatchRegionLayoutUpdateEvent = value; }
+    bool shouldDispatchRegionLayoutUpdateEvent() { return m_dispatchRegionLayoutUpdateEvent; }
 private:
     virtual const char* renderName() const { return "RenderRegion"; }
 
@@ -120,6 +122,7 @@
     bool m_isValid;
     bool m_hasCustomRegionStyle;
     RegionState m_regionState;
+    bool m_dispatchRegionLayoutUpdateEvent;
 };
 
 inline RenderRegion* toRenderRegion(RenderObject* object)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to