~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/rendering/FlowThreadController.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions
 
6
 * are met:
 
7
 *
 
8
 * 1. Redistributions of source code must retain the above
 
9
 *    copyright notice, this list of conditions and the following
 
10
 *    disclaimer.
 
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.
 
15
 *
 
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
 
27
 * SUCH DAMAGE.
 
28
 */
 
29
 
 
30
#include "config.h"
 
31
 
 
32
#include "FlowThreadController.h"
 
33
 
 
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>
 
40
 
 
41
namespace WebCore {
 
42
 
 
43
PassOwnPtr<FlowThreadController> FlowThreadController::create(RenderView* view)
 
44
{
 
45
    return adoptPtr(new FlowThreadController(view));
 
46
}
 
47
 
 
48
FlowThreadController::FlowThreadController(RenderView* view)
 
49
    : m_view(view)
 
50
    , m_currentRenderFlowThread(0)
 
51
    , m_isRenderNamedFlowThreadOrderDirty(false)
 
52
    , m_autoLogicalHeightRegionsCount(0)
 
53
{
 
54
}
 
55
 
 
56
FlowThreadController::~FlowThreadController()
 
57
{
 
58
}
 
59
 
 
60
RenderNamedFlowThread* FlowThreadController::ensureRenderFlowThreadWithName(const AtomicString& name)
 
61
{
 
62
    if (!m_renderNamedFlowThreadList)
 
63
        m_renderNamedFlowThreadList = adoptPtr(new RenderNamedFlowThreadList());
 
64
    else {
 
65
        for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
 
66
            RenderNamedFlowThread* flowRenderer = *iter;
 
67
            if (flowRenderer->flowThreadName() == name)
 
68
                return flowRenderer;
 
69
        }
 
70
    }
 
71
 
 
72
    NamedFlowCollection* namedFlows = m_view->document()->namedFlows();
 
73
 
 
74
    // Sanity check for the absence of a named flow in the "CREATED" state with the same name.
 
75
    ASSERT(!namedFlows->flowByName(name));
 
76
 
 
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);
 
80
 
 
81
    // Keep the flow renderer as a child of RenderView.
 
82
    m_view->addChild(flowRenderer);
 
83
 
 
84
    setIsRenderNamedFlowThreadOrderDirty(true);
 
85
 
 
86
    return flowRenderer;
 
87
}
 
88
 
 
89
void FlowThreadController::styleDidChange()
 
90
{
 
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));
 
95
    }
 
96
}
 
97
 
 
98
void FlowThreadController::layoutRenderNamedFlowThreads()
 
99
{
 
100
    ASSERT(m_renderNamedFlowThreadList);
 
101
 
 
102
    ASSERT(isAutoLogicalHeightRegionsFlagConsistent());
 
103
 
 
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);
 
110
    }
 
111
 
 
112
    if (toRemoveList.size() > 0)
 
113
        setIsRenderNamedFlowThreadOrderDirty(true);
 
114
 
 
115
    for (RenderNamedFlowThreadList::iterator iter = toRemoveList.begin(); iter != toRemoveList.end(); ++iter) {
 
116
        RenderNamedFlowThread* flowRenderer = *iter;
 
117
        m_renderNamedFlowThreadList->remove(flowRenderer);
 
118
        flowRenderer->destroy();
 
119
    }
 
120
 
 
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))
 
127
                continue;
 
128
            flowRenderer->pushDependencies(sortedList);
 
129
            sortedList.add(flowRenderer);
 
130
        }
 
131
        m_renderNamedFlowThreadList->swap(sortedList);
 
132
        setIsRenderNamedFlowThreadOrderDirty(false);
 
133
    }
 
134
 
 
135
    for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
 
136
        RenderNamedFlowThread* flowRenderer = *iter;
 
137
        flowRenderer->layoutIfNeeded();
 
138
    }
 
139
}
 
140
 
 
141
void FlowThreadController::registerNamedFlowContentNode(Node* contentNode, RenderNamedFlowThread* namedFlow)
 
142
{
 
143
    ASSERT(contentNode && contentNode->isElementNode());
 
144
    ASSERT(namedFlow);
 
145
    ASSERT(!m_mapNamedFlowContentNodes.contains(contentNode));
 
146
    ASSERT(!namedFlow->hasContentNode(contentNode));
 
147
    m_mapNamedFlowContentNodes.add(contentNode, namedFlow);
 
148
    namedFlow->registerNamedFlowContentNode(contentNode);
 
149
}
 
150
 
 
151
void FlowThreadController::unregisterNamedFlowContentNode(Node* contentNode)
 
152
{
 
153
    ASSERT(contentNode && contentNode->isElementNode());
 
154
    HashMap<Node*, RenderNamedFlowThread*>::iterator it = m_mapNamedFlowContentNodes.find(contentNode);
 
155
    ASSERT(it != m_mapNamedFlowContentNodes.end());
 
156
    ASSERT(it->value);
 
157
    ASSERT(it->value->hasContentNode(contentNode));
 
158
    it->value->unregisterNamedFlowContentNode(contentNode);
 
159
    m_mapNamedFlowContentNodes.remove(contentNode);
 
160
}
 
161
 
 
162
#ifndef NDEBUG
 
163
bool FlowThreadController::isAutoLogicalHeightRegionsFlagConsistent() const
 
164
{
 
165
    if (!hasRenderNamedFlowThreads())
 
166
        return !hasAutoLogicalHeightRegions();
 
167
 
 
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();
 
173
    }
 
174
 
 
175
    return autoLogicalHeightRegions == m_autoLogicalHeightRegionsCount;
 
176
}
 
177
#endif
 
178
 
 
179
void FlowThreadController::resetRegionsOverrideLogicalContentHeight()
 
180
{
 
181
    ASSERT(m_view->normalLayoutPhase());
 
182
    for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter)
 
183
        (*iter)->resetRegionsOverrideLogicalContentHeight();
 
184
}
 
185
 
 
186
void FlowThreadController::markAutoLogicalHeightRegionsForLayout()
 
187
{
 
188
    ASSERT(m_view->constrainedFlowThreadsLayoutPhase());
 
189
    for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter)
 
190
        (*iter)->markAutoLogicalHeightRegionsForLayout();
 
191
}
 
192
 
 
193
} // namespace WebCore