2
* Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
8
* 1. Redistributions of source code must retain the above
9
* copyright notice, this list of conditions and the following
11
* 2. Redistributions in binary form must reproduce the above
12
* copyright notice, this list of conditions and the following
13
* disclaimer in the documentation and/or other materials
14
* provided with the distribution.
16
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
17
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
20
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
#include "FlowThreadController.h"
34
#include "NamedFlowCollection.h"
35
#include "RenderFlowThread.h"
36
#include "RenderNamedFlowThread.h"
37
#include "StyleInheritedData.h"
38
#include "WebKitNamedFlow.h"
39
#include <wtf/text/AtomicString.h>
43
PassOwnPtr<FlowThreadController> FlowThreadController::create(RenderView* view)
45
return adoptPtr(new FlowThreadController(view));
48
FlowThreadController::FlowThreadController(RenderView* view)
50
, m_currentRenderFlowThread(0)
51
, m_isRenderNamedFlowThreadOrderDirty(false)
52
, m_autoLogicalHeightRegionsCount(0)
56
FlowThreadController::~FlowThreadController()
60
RenderNamedFlowThread* FlowThreadController::ensureRenderFlowThreadWithName(const AtomicString& name)
62
if (!m_renderNamedFlowThreadList)
63
m_renderNamedFlowThreadList = adoptPtr(new RenderNamedFlowThreadList());
65
for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
66
RenderNamedFlowThread* flowRenderer = *iter;
67
if (flowRenderer->flowThreadName() == name)
72
NamedFlowCollection* namedFlows = m_view->document()->namedFlows();
74
// Sanity check for the absence of a named flow in the "CREATED" state with the same name.
75
ASSERT(!namedFlows->flowByName(name));
77
RenderNamedFlowThread* flowRenderer = new (m_view->renderArena()) RenderNamedFlowThread(m_view->document(), namedFlows->ensureFlowWithName(name));
78
flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(m_view->style()));
79
m_renderNamedFlowThreadList->add(flowRenderer);
81
// Keep the flow renderer as a child of RenderView.
82
m_view->addChild(flowRenderer);
84
setIsRenderNamedFlowThreadOrderDirty(true);
89
void FlowThreadController::styleDidChange()
91
RenderStyle* viewStyle = m_view->style();
92
for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
93
RenderNamedFlowThread* flowRenderer = *iter;
94
flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(viewStyle));
98
void FlowThreadController::layoutRenderNamedFlowThreads()
100
ASSERT(m_renderNamedFlowThreadList);
102
ASSERT(isAutoLogicalHeightRegionsFlagConsistent());
104
// Remove the left-over flow threads.
105
RenderNamedFlowThreadList toRemoveList;
106
for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
107
RenderNamedFlowThread* flowRenderer = *iter;
108
if (flowRenderer->isMarkedForDestruction())
109
toRemoveList.add(flowRenderer);
112
if (toRemoveList.size() > 0)
113
setIsRenderNamedFlowThreadOrderDirty(true);
115
for (RenderNamedFlowThreadList::iterator iter = toRemoveList.begin(); iter != toRemoveList.end(); ++iter) {
116
RenderNamedFlowThread* flowRenderer = *iter;
117
m_renderNamedFlowThreadList->remove(flowRenderer);
118
flowRenderer->destroy();
121
if (isRenderNamedFlowThreadOrderDirty()) {
122
// Arrange the thread list according to dependencies.
123
RenderNamedFlowThreadList sortedList;
124
for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
125
RenderNamedFlowThread* flowRenderer = *iter;
126
if (sortedList.contains(flowRenderer))
128
flowRenderer->pushDependencies(sortedList);
129
sortedList.add(flowRenderer);
131
m_renderNamedFlowThreadList->swap(sortedList);
132
setIsRenderNamedFlowThreadOrderDirty(false);
135
for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
136
RenderNamedFlowThread* flowRenderer = *iter;
137
flowRenderer->layoutIfNeeded();
141
void FlowThreadController::registerNamedFlowContentNode(Node* contentNode, RenderNamedFlowThread* namedFlow)
143
ASSERT(contentNode && contentNode->isElementNode());
145
ASSERT(!m_mapNamedFlowContentNodes.contains(contentNode));
146
ASSERT(!namedFlow->hasContentNode(contentNode));
147
m_mapNamedFlowContentNodes.add(contentNode, namedFlow);
148
namedFlow->registerNamedFlowContentNode(contentNode);
151
void FlowThreadController::unregisterNamedFlowContentNode(Node* contentNode)
153
ASSERT(contentNode && contentNode->isElementNode());
154
HashMap<Node*, RenderNamedFlowThread*>::iterator it = m_mapNamedFlowContentNodes.find(contentNode);
155
ASSERT(it != m_mapNamedFlowContentNodes.end());
157
ASSERT(it->value->hasContentNode(contentNode));
158
it->value->unregisterNamedFlowContentNode(contentNode);
159
m_mapNamedFlowContentNodes.remove(contentNode);
163
bool FlowThreadController::isAutoLogicalHeightRegionsFlagConsistent() const
165
if (!hasRenderNamedFlowThreads())
166
return !hasAutoLogicalHeightRegions();
168
// Count the number of auto height regions
169
unsigned autoLogicalHeightRegions = 0;
170
for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
171
RenderNamedFlowThread* flowRenderer = *iter;
172
autoLogicalHeightRegions += flowRenderer->autoLogicalHeightRegionsCount();
175
return autoLogicalHeightRegions == m_autoLogicalHeightRegionsCount;
179
void FlowThreadController::resetRegionsOverrideLogicalContentHeight()
181
ASSERT(m_view->normalLayoutPhase());
182
for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter)
183
(*iter)->resetRegionsOverrideLogicalContentHeight();
186
void FlowThreadController::markAutoLogicalHeightRegionsForLayout()
188
ASSERT(m_view->constrainedFlowThreadsLayoutPhase());
189
for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter)
190
(*iter)->markAutoLogicalHeightRegionsForLayout();
193
} // namespace WebCore