summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/FlowThreadController.cpp
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2016-08-25 19:20:41 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-02-02 12:30:55 +0000
commit6882a04fb36642862b11efe514251d32070c3d65 (patch)
treeb7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/rendering/FlowThreadController.cpp
parentab6df191029eeeb0b0f16f127d553265659f739e (diff)
downloadqtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebCore/rendering/FlowThreadController.cpp')
-rw-r--r--Source/WebCore/rendering/FlowThreadController.cpp181
1 files changed, 122 insertions, 59 deletions
diff --git a/Source/WebCore/rendering/FlowThreadController.cpp b/Source/WebCore/rendering/FlowThreadController.cpp
index e0f1c6713..44b22bbe1 100644
--- a/Source/WebCore/rendering/FlowThreadController.cpp
+++ b/Source/WebCore/rendering/FlowThreadController.cpp
@@ -28,11 +28,11 @@
*/
#include "config.h"
-
#include "FlowThreadController.h"
#include "NamedFlowCollection.h"
#include "RenderFlowThread.h"
+#include "RenderLayer.h"
#include "RenderNamedFlowThread.h"
#include "StyleInheritedData.h"
#include "WebKitNamedFlow.h"
@@ -40,14 +40,8 @@
namespace WebCore {
-PassOwnPtr<FlowThreadController> FlowThreadController::create(RenderView* view)
-{
- return adoptPtr(new FlowThreadController(view));
-}
-
FlowThreadController::FlowThreadController(RenderView* view)
: m_view(view)
- , m_currentRenderFlowThread(0)
, m_isRenderNamedFlowThreadOrderDirty(false)
, m_flowThreadsWithAutoLogicalHeightRegions(0)
{
@@ -57,25 +51,24 @@ FlowThreadController::~FlowThreadController()
{
}
-RenderNamedFlowThread* FlowThreadController::ensureRenderFlowThreadWithName(const AtomicString& name)
+RenderNamedFlowThread& FlowThreadController::ensureRenderFlowThreadWithName(const AtomicString& name)
{
if (!m_renderNamedFlowThreadList)
- m_renderNamedFlowThreadList = adoptPtr(new RenderNamedFlowThreadList());
+ m_renderNamedFlowThreadList = std::make_unique<RenderNamedFlowThreadList>();
else {
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList) {
if (flowRenderer->flowThreadName() == name)
- return flowRenderer;
+ return *flowRenderer;
}
}
- NamedFlowCollection* namedFlows = m_view->document()->namedFlows();
+ NamedFlowCollection& namedFlows = m_view->document().namedFlows();
// Sanity check for the absence of a named flow in the "CREATED" state with the same name.
- ASSERT(!namedFlows->flowByName(name));
+ ASSERT(!namedFlows.flowByName(name));
- RenderNamedFlowThread* flowRenderer = RenderNamedFlowThread::createAnonymous(m_view->document(), namedFlows->ensureFlowWithName(name));
- flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(m_view->style()));
+ auto flowRenderer = new RenderNamedFlowThread(m_view->document(), RenderFlowThread::createFlowThreadStyle(&m_view->style()), namedFlows.ensureFlowWithName(name));
+ flowRenderer->initializeStyle();
m_renderNamedFlowThreadList->add(flowRenderer);
// Keep the flow renderer as a child of RenderView.
@@ -83,47 +76,39 @@ RenderNamedFlowThread* FlowThreadController::ensureRenderFlowThreadWithName(cons
setIsRenderNamedFlowThreadOrderDirty(true);
- return flowRenderer;
+ return *flowRenderer;
}
void FlowThreadController::styleDidChange()
{
- RenderStyle* viewStyle = m_view->style();
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(viewStyle));
- }
+ RenderStyle& viewStyle = m_view->style();
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList)
+ flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(&viewStyle));
}
void FlowThreadController::layoutRenderNamedFlowThreads()
{
updateFlowThreadsChainIfNecessary();
-
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList)
flowRenderer->layoutIfNeeded();
- }
}
-void FlowThreadController::registerNamedFlowContentNode(Node* contentNode, RenderNamedFlowThread* namedFlow)
+void FlowThreadController::registerNamedFlowContentElement(Element& contentElement, RenderNamedFlowThread& namedFlow)
{
- ASSERT(contentNode && contentNode->isElementNode());
- ASSERT(namedFlow);
- ASSERT(!m_mapNamedFlowContentNodes.contains(contentNode));
- ASSERT(!namedFlow->hasContentNode(contentNode));
- m_mapNamedFlowContentNodes.add(contentNode, namedFlow);
- namedFlow->registerNamedFlowContentNode(contentNode);
+ ASSERT(!m_mapNamedFlowContentElement.contains(&contentElement));
+ ASSERT(!namedFlow.hasContentElement(contentElement));
+ m_mapNamedFlowContentElement.add(&contentElement, &namedFlow);
+ namedFlow.registerNamedFlowContentElement(contentElement);
}
-void FlowThreadController::unregisterNamedFlowContentNode(Node* contentNode)
+void FlowThreadController::unregisterNamedFlowContentElement(Element& contentElement)
{
- ASSERT(contentNode && contentNode->isElementNode());
- HashMap<const Node*, RenderNamedFlowThread*>::iterator it = m_mapNamedFlowContentNodes.find(contentNode);
- ASSERT(it != m_mapNamedFlowContentNodes.end());
+ auto it = m_mapNamedFlowContentElement.find(&contentElement);
+ ASSERT(it != m_mapNamedFlowContentElement.end());
ASSERT(it->value);
- ASSERT(it->value->hasContentNode(contentNode));
- it->value->unregisterNamedFlowContentNode(contentNode);
- m_mapNamedFlowContentNodes.remove(contentNode);
+ ASSERT(it->value->hasContentElement(contentElement));
+ it->value->unregisterNamedFlowContentElement(contentElement);
+ m_mapNamedFlowContentElement.remove(&contentElement);
}
void FlowThreadController::updateFlowThreadsChainIfNecessary()
@@ -133,8 +118,7 @@ void FlowThreadController::updateFlowThreadsChainIfNecessary()
// Remove the left-over flow threads.
RenderNamedFlowThreadList toRemoveList;
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList) {
if (flowRenderer->isMarkedForDestruction())
toRemoveList.add(flowRenderer);
}
@@ -142,8 +126,7 @@ void FlowThreadController::updateFlowThreadsChainIfNecessary()
if (toRemoveList.size() > 0)
setIsRenderNamedFlowThreadOrderDirty(true);
- for (RenderNamedFlowThreadList::iterator iter = toRemoveList.begin(); iter != toRemoveList.end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
+ for (auto& flowRenderer : toRemoveList) {
m_renderNamedFlowThreadList->remove(flowRenderer);
flowRenderer->destroy();
}
@@ -151,8 +134,7 @@ void FlowThreadController::updateFlowThreadsChainIfNecessary()
if (isRenderNamedFlowThreadOrderDirty()) {
// Arrange the thread list according to dependencies.
RenderNamedFlowThreadList sortedList;
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList) {
if (sortedList.contains(flowRenderer))
continue;
flowRenderer->pushDependencies(sortedList);
@@ -167,10 +149,9 @@ bool FlowThreadController::updateFlowThreadsNeedingLayout()
{
bool needsTwoPassLayout = false;
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList) {
ASSERT(!flowRenderer->needsTwoPhasesLayout());
- flowRenderer->setInConstrainedLayoutPhase(false);
+ ASSERT(flowRenderer->inMeasureContentLayoutPhase());
if (flowRenderer->needsLayout() && flowRenderer->hasAutoLogicalHeightRegions())
needsTwoPassLayout = true;
}
@@ -185,8 +166,7 @@ bool FlowThreadController::updateFlowThreadsNeedingTwoStepLayout()
{
bool needsTwoPassLayout = false;
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList) {
if (flowRenderer->needsTwoPhasesLayout()) {
needsTwoPassLayout = true;
break;
@@ -201,8 +181,7 @@ bool FlowThreadController::updateFlowThreadsNeedingTwoStepLayout()
void FlowThreadController::resetFlowThreadsWithAutoHeightRegions()
{
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList) {
if (flowRenderer->hasAutoLogicalHeightRegions()) {
flowRenderer->markAutoLogicalHeightRegionsForLayout();
flowRenderer->invalidateRegions();
@@ -214,7 +193,7 @@ void FlowThreadController::updateFlowThreadsIntoConstrainedPhase()
{
// Walk the flow chain in reverse order to update the auto-height regions and compute correct sizes for the containing regions. Only after this we can
// set the flow in the constrained layout phase.
- for (RenderNamedFlowThreadList::reverse_iterator iter = m_renderNamedFlowThreadList->rbegin(); iter != m_renderNamedFlowThreadList->rend(); ++iter) {
+ for (auto iter = m_renderNamedFlowThreadList->rbegin(), end = m_renderNamedFlowThreadList->rend(); iter != end; ++iter) {
RenderNamedFlowThread* flowRenderer = *iter;
ASSERT(!flowRenderer->hasRegions() || flowRenderer->hasValidRegionInfo());
flowRenderer->layoutIfNeeded();
@@ -222,14 +201,98 @@ void FlowThreadController::updateFlowThreadsIntoConstrainedPhase()
ASSERT(flowRenderer->needsTwoPhasesLayout());
flowRenderer->markAutoLogicalHeightRegionsForLayout();
}
- flowRenderer->setInConstrainedLayoutPhase(true);
+ flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseConstrained);
flowRenderer->clearNeedsTwoPhasesLayout();
}
}
-bool FlowThreadController::isContentNodeRegisteredWithAnyNamedFlow(const Node* contentNode) const
+void FlowThreadController::updateFlowThreadsIntoOverflowPhase()
{
- return m_mapNamedFlowContentNodes.contains(contentNode);
+ for (auto iter = m_renderNamedFlowThreadList->rbegin(), end = m_renderNamedFlowThreadList->rend(); iter != end; ++iter) {
+ RenderNamedFlowThread* flowRenderer = *iter;
+ ASSERT(!flowRenderer->hasRegions() || flowRenderer->hasValidRegionInfo());
+ ASSERT(!flowRenderer->needsTwoPhasesLayout());
+
+ // In the overflow computation phase the flow threads start in the constrained phase even though optimizations didn't set the state before.
+ flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseConstrained);
+
+ flowRenderer->layoutIfNeeded();
+ flowRenderer->markRegionsForOverflowLayoutIfNeeded();
+ flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseOverflow);
+ }
+}
+
+void FlowThreadController::updateFlowThreadsIntoMeasureContentPhase()
+{
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList) {
+ ASSERT(flowRenderer->inFinalLayoutPhase());
+
+ flowRenderer->dispatchNamedFlowEvents();
+ flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseMeasureContent);
+ }
+}
+
+void FlowThreadController::updateFlowThreadsIntoFinalPhase()
+{
+ for (auto iter = m_renderNamedFlowThreadList->rbegin(), end = m_renderNamedFlowThreadList->rend(); iter != end; ++iter) {
+ RenderNamedFlowThread* flowRenderer = *iter;
+ flowRenderer->layoutIfNeeded();
+ if (flowRenderer->needsTwoPhasesLayout()) {
+ flowRenderer->markRegionsForOverflowLayoutIfNeeded();
+ flowRenderer->clearNeedsTwoPhasesLayout();
+ }
+ flowRenderer->setLayoutPhase(RenderFlowThread::LayoutPhaseFinal);
+ }
+}
+
+void FlowThreadController::updateFlowThreadsLayerToRegionMappingsIfNeeded()
+{
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList)
+ flowRenderer->updateAllLayerToRegionMappingsIfNeeded();
+}
+
+void FlowThreadController::updateNamedFlowsLayerListsIfNeeded()
+{
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList)
+ flowRenderer->layer()->updateLayerListsIfNeeded();
+}
+
+static inline bool compareZIndexFlowThreadController(RenderLayer* first, RenderLayer* second)
+{
+ return first->zIndex() < second->zIndex();
+}
+
+// Collect the fixed positioned layers that have the named flows as containing block
+// These layers are painted and hit-tested starting from RenderView not from regions.
+void FlowThreadController::collectFixedPositionedLayers(Vector<RenderLayer*>& fixedPosLayers) const
+{
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList) {
+ // If the named flow does not have any regions attached, a fixed element should not be
+ // displayed even if the fixed element is positioned/sized by the viewport.
+ if (!flowRenderer->hasRegions())
+ continue;
+
+ RenderLayer* flowThreadLayer = flowRenderer->layer();
+ if (Vector<RenderLayer*>* negZOrderList = flowThreadLayer->negZOrderList()) {
+ for (size_t i = 0, size = negZOrderList->size(); i < size; ++i) {
+ RenderLayer* currLayer = negZOrderList->at(i);
+ if (currLayer->renderer().style().position() != FixedPosition)
+ continue;
+ fixedPosLayers.append(currLayer);
+ }
+ }
+
+ if (Vector<RenderLayer*>* posZOrderList = flowThreadLayer->posZOrderList()) {
+ for (size_t i = 0, size = posZOrderList->size(); i < size; ++i) {
+ RenderLayer* currLayer = posZOrderList->at(i);
+ if (currLayer->renderer().style().position() != FixedPosition)
+ continue;
+ fixedPosLayers.append(currLayer);
+ }
+ }
+ }
+
+ std::stable_sort(fixedPosLayers.begin(), fixedPosLayers.end(), compareZIndexFlowThreadController);
}
#ifndef NDEBUG
@@ -238,8 +301,8 @@ bool FlowThreadController::isAutoLogicalHeightRegionsCountConsistent() const
if (!hasRenderNamedFlowThreads())
return !hasFlowThreadsWithAutoLogicalHeightRegions();
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- if (!(*iter)->isAutoLogicalHeightRegionsCountConsistent())
+ for (auto& flowRenderer : *m_renderNamedFlowThreadList) {
+ if (!flowRenderer->isAutoLogicalHeightRegionsCountConsistent())
return false;
}