15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2007 David Smith (catfish.man@gmail.com)
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2010. All rights reserved.
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderBlock.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/accessibility/AXObjectCache.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Element.h"
31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/StyleEngine.h"
32e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/ShadowRoot.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/Editor.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/FrameSelection.h"
35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/events/OverflowEvent.h"
36a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "core/fetch/ResourceLoadPriorityOptimizer.h"
371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/FrameView.h"
38d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
3909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/frame/Settings.h"
407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/page/Page.h"
417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/BlockPainter.h"
427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/paint/BoxPainter.h"
4319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "core/rendering/GraphicsContextAnnotator.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/HitTestLocation.h"
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/HitTestResult.h"
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/InlineIterator.h"
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/InlineTextBox.h"
4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/PaintInfo.h"
4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderCombineText.h"
5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderDeprecatedFlexibleBox.h"
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderFlexibleBox.h"
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/rendering/RenderFlowThread.h"
535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/rendering/RenderGrid.h"
5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderInline.h"
5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderLayer.h"
5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderMarquee.h"
57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/rendering/RenderObjectInlines.h"
5853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderRegion.h"
5953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTableCell.h"
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/rendering/RenderTextControl.h"
6153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTextFragment.h"
6253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTheme.h"
6353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h"
64c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/rendering/TextAutosizer.h"
65591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/rendering/shapes/ShapeOutsideInfo.h"
66a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "core/rendering/style/ContentData.h"
67a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "core/rendering/style/RenderStyle.h"
681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/FloatQuad.h"
69bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/geometry/TransformState.h"
7007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "platform/graphics/GraphicsContextCullSaver.h"
71a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContextStateSaver.h"
7202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/StdLibExtras.h"
7302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/TemporaryChange.h"
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace WTF;
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace Unicode;
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
78c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct SameSizeAsRenderBlock : public RenderBox {
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObjectChildList children;
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderLineBoxList lineBoxes;
8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    int pageLogicalOffset;
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    uint32_t bitfields;
8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock_should_stay_small);
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)typedef WTF::HashMap<const RenderBox*, OwnPtr<ColumnInfo> > ColumnInfoMap;
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static ColumnInfoMap* gColumnInfoMap = 0;
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static TrackedDescendantsMap* gPositionedDescendantsMap = 0;
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0;
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static TrackedContainerMap* gPositionedContainerMap = 0;
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static TrackedContainerMap* gPercentHeightContainerMap = 0;
9902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int gDelayUpdateScrollInfo = 0;
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static bool gColumnFlowSplitEnabled = true;
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code
1071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)// only works on RenderBlocks. If this changes, this class should be shared with other RenderBoxes.
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class OverflowEventDispatcher {
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher);
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    OverflowEventDispatcher(const RenderBlock* block)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_block(block)
113a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        , m_hadHorizontalLayoutOverflow(false)
114a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        , m_hadVerticalLayoutOverflow(false)
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1168abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowClip() && m_block->document().hasListenerType(Document::OVERFLOWCHANGED_LISTENER);
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_shouldDispatchEvent) {
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_hadHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_hadVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ~OverflowEventDispatcher()
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!m_shouldDispatchEvent)
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool hasHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool hasVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool horizontalLayoutOverflowChanged = hasHorizontalLayoutOverflow != m_hadHorizontalLayoutOverflow;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool verticalLayoutOverflowChanged = hasVerticalLayoutOverflow != m_hadVerticalLayoutOverflow;
1331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (!horizontalLayoutOverflowChanged && !verticalLayoutOverflowChanged)
1351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return;
1361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
137a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        RefPtrWillBeRawPtr<OverflowEvent> event = OverflowEvent::create(horizontalLayoutOverflowChanged, hasHorizontalLayoutOverflow, verticalLayoutOverflowChanged, hasVerticalLayoutOverflow);
13851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        event->setTarget(m_block->node());
13951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_block->document().enqueueAnimationFrameEvent(event.release());
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const RenderBlock* m_block;
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_shouldDispatchEvent;
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_hadHorizontalLayoutOverflow;
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_hadVerticalLayoutOverflow;
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)RenderBlock::RenderBlock(ContainerNode* node)
150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    : RenderBox(node)
151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_hasMarginBeforeQuirk(false)
152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_hasMarginAfterQuirk(false)
153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_beingDestroyed(false)
154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_hasMarkupTruncation(false)
155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_hasBorderOrPaddingLogicalWidthChanged(false)
15609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    , m_hasOnlySelfCollapsingChildren(false)
157197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    , m_descendantsWithFloatsMarkedForLayout(false)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
159197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // RenderBlockFlow calls setChildrenInline(true).
160197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // By default, subclasses do not have inline children.
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
163e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RenderBlock::trace(Visitor* visitor)
164e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
165e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    visitor->trace(m_children);
166e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RenderBox::trace(visitor);
167e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
168e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (OwnPtr<TrackedRendererListHashSet> descendantSet = descendantMap->take(block)) {
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TrackedRendererListHashSet::iterator end = descendantSet->end();
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (TrackedRendererListHashSet::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
174926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            TrackedContainerMap::iterator it = containerMap->find(*descendant);
175926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ASSERT(it != containerMap->end());
176926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (it == containerMap->end())
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            HashSet<RenderBlock*>* containerSet = it->value.get();
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(containerSet->contains(block));
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            containerSet->remove(block);
181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (containerSet->isEmpty())
182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                containerMap->remove(it);
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
187a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)static void appendImageIfNotNull(Vector<ImageResource*>& imageResources, const StyleImage* styleImage)
188a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
18909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (styleImage && styleImage->cachedImage()) {
19009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        ImageResource* imageResource = styleImage->cachedImage();
19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (imageResource && !imageResource->isLoaded())
19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            imageResources.append(styleImage->cachedImage());
19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
194a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
195a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
196197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic void appendLayers(Vector<ImageResource*>& images, const FillLayer& styleLayer)
197a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
198197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    for (const FillLayer* layer = &styleLayer; layer; layer = layer->next())
199a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        appendImageIfNotNull(images, layer->image());
200a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
201a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static void appendImagesFromStyle(Vector<ImageResource*>& images, RenderStyle& blockStyle)
20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
20409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    appendLayers(images, blockStyle.backgroundLayers());
20509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    appendLayers(images, blockStyle.maskLayers());
20609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
20709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const ContentData* contentData = blockStyle.contentData();
208c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (contentData && contentData->isImage())
209c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        appendImageIfNotNull(images, toImageContentData(contentData)->image());
21009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (blockStyle.boxReflect())
21109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        appendImageIfNotNull(images, blockStyle.boxReflect()->mask().image());
21209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    appendImageIfNotNull(images, blockStyle.listStyleImage());
21309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    appendImageIfNotNull(images, blockStyle.borderImageSource());
21409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    appendImageIfNotNull(images, blockStyle.maskBoxImageSource());
2156f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (blockStyle.shapeOutside())
2166f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        appendImageIfNotNull(images, blockStyle.shapeOutside()->image());
21709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
21809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
219e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RenderBlock::removeFromGlobalMaps()
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasColumns())
222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        gColumnInfoMap->take(this);
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (gPercentHeightDescendantsMap)
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (gPositionedDescendantsMap)
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap);
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
229e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)RenderBlock::~RenderBlock()
230e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
231e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if !ENABLE(OILPAN)
232e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    removeFromGlobalMaps();
233e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#endif
234e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
235e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
236e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RenderBlock::destroy()
237e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
238e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RenderBox::destroy();
239e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#if ENABLE(OILPAN)
240e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    // RenderObject::removeChild called in destory() depends on gColumnInfoMap.
241e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    removeFromGlobalMaps();
242e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#endif
243e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
244e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::willBeDestroyed()
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Mark as being destroyed to avoid trouble with merges in removeChild().
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_beingDestroyed = true;
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    children()->destroyLeftoverChildren();
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Destroy our continuation before anything other than anonymous children.
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The reason we don't destroy it before anonymous children is that they may
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // have continuations of their own that are anonymous children of our continuation.
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* continuation = this->continuation();
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (continuation) {
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        continuation->destroy();
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setContinuation(0);
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
26202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!documentBeingDestroyed()) {
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (firstLineBox()) {
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We can't wait for RenderBox::destroy to clear the selection,
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // because by then we will have nuked the line boxes.
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // FIXME: The FrameSelection should be responsible for this when it
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // is notified of DOM mutations.
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isSelectionBorder())
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                view()->clearSelection();
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If we are an anonymous block, then our line boxes might have children
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // that will outlast this block. In the non-anonymous block case those
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // children will be destroyed by the time we return from this function.
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isAnonymousBlock()) {
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    while (InlineBox* childBox = box->firstChild())
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        childBox->remove();
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (parent())
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            parent()->dirtyLinesFromChangedChild(this);
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    m_lineBoxes.deleteLineBoxes();
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0))
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        gDelayedUpdateScrollInfoSet->remove(this);
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
290c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (TextAutosizer* textAutosizer = document().textAutosizer())
291a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        textAutosizer->destroy(this);
292a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBox::willBeDestroyed();
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
296aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochvoid RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderStyle* oldStyle = style();
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
300aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    setReplaced(newStyle.isDisplayInlineType());
30102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
302d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (oldStyle && parent()) {
303d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        bool oldStyleIsContainer = oldStyle->position() != StaticPosition || oldStyle->hasTransformRelatedProperty();
304d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        bool newStyleIsContainer = newStyle.position() != StaticPosition || newStyle.hasTransformRelatedProperty();
305d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
306d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        if (oldStyleIsContainer && !newStyleIsContainer) {
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Clear our positioned objects list. Our absolutely positioned descendants will be
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // inserted into our containing block's positioned objects list during layout.
309926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            removePositionedObjects(0, NewContainingBlock);
310d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        } else if (!oldStyleIsContainer && newStyleIsContainer) {
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Remove our absolutely positioned descendants from their current containing block.
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // They will be inserted into our positioned objects list during layout.
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderObject* cb = parent();
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    cb = cb->containingBlock();
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    break;
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                cb = cb->parent();
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
32102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (cb->isRenderBlock())
323926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                toRenderBlock(cb)->removePositionedObjects(this, NewContainingBlock);
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBox::styleWillChange(diff, newStyle);
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
330926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static bool borderOrPaddingLogicalWidthChanged(const RenderStyle* oldStyle, const RenderStyle* newStyle)
331926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
332926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (newStyle->isHorizontalWritingMode())
333926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return oldStyle->borderLeftWidth() != newStyle->borderLeftWidth()
334926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            || oldStyle->borderRightWidth() != newStyle->borderRightWidth()
335926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            || oldStyle->paddingLeft() != newStyle->paddingLeft()
336926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            || oldStyle->paddingRight() != newStyle->paddingRight();
337926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
338926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return oldStyle->borderTopWidth() != newStyle->borderTopWidth()
339926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        || oldStyle->borderBottomWidth() != newStyle->borderBottomWidth()
340926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        || oldStyle->paddingTop() != newStyle->paddingTop()
341926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        || oldStyle->paddingBottom() != newStyle->paddingBottom();
342926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
343926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBox::styleDidChange(diff, oldStyle);
34702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
348926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RenderStyle* newStyle = style();
34953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isAnonymousBlock()) {
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Ensure that all of our continuation blocks pick up the new style.
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBoxModelObject* nextCont = currCont->continuation();
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            currCont->setContinuation(0);
355926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            currCont->setStyle(newStyle);
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            currCont->setContinuation(nextCont);
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
360c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (TextAutosizer* textAutosizer = document().textAutosizer())
361a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        textAutosizer->record(this);
362a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
36302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    propagateStyleToAnonymousChildren(true);
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
365926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // It's possible for our border/padding to change, but for the overall logical width of the block to
366926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
36710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff.needsFullLayout() && needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, newStyle);
36809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
36909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // If the style has unloaded images, want to notify the ResourceLoadPriorityOptimizer so that
37009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // network priorities can be set.
37109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    Vector<ImageResource*> images;
37209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    appendImagesFromStyle(images, *newStyle);
37309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (images.isEmpty())
37409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->removeRenderObject(this);
37509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    else
37609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->addRenderObject(this);
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
379fdbb120d0a4a87db74bcb608de226c85a7d1c920Ben Murdochvoid RenderBlock::invalidatePaintOfSubtreesIfNeeded(const PaintInvalidationState& childPaintInvalidationState)
380f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{
381fdbb120d0a4a87db74bcb608de226c85a7d1c920Ben Murdoch    RenderBox::invalidatePaintOfSubtreesIfNeeded(childPaintInvalidationState);
382f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
383197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Take care of positioned objects. This is required as PaintInvalidationState keeps a single clip rect.
384f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    if (TrackedRendererListHashSet* positionedObjects = this->positionedObjects()) {
385f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        TrackedRendererListHashSet::iterator end = positionedObjects->end();
386d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        for (TrackedRendererListHashSet::iterator it = positionedObjects->begin(); it != end; ++it) {
387d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            RenderBox* box = *it;
388d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
3899e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            // One of the renderers we're skipping over here may be the child's paint invalidation container,
3909e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            // so we can't pass our own paint invalidation container along.
3919e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            const RenderLayerModelObject& paintInvalidationContainerForChild = *box->containerForPaintInvalidation();
392d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
393197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            // If it's a new paint invalidation container, we won't have properly accumulated the offset into the
394197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            // PaintInvalidationState.
395197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            // FIXME: Teach PaintInvalidationState to handle this case. crbug.com/371485
396fdbb120d0a4a87db74bcb608de226c85a7d1c920Ben Murdoch            if (paintInvalidationContainerForChild != childPaintInvalidationState.paintInvalidationContainer()) {
397197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                ForceHorriblySlowRectMapping slowRectMapping(&childPaintInvalidationState);
3989e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                PaintInvalidationState disabledPaintInvalidationState(childPaintInvalidationState, *this, paintInvalidationContainerForChild);
399197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                box->invalidateTreeIfNeeded(disabledPaintInvalidationState);
400197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                continue;
401197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            }
402197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
403d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            // If the positioned renderer is absolutely positioned and it is inside
404197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            // a relatively positioned inline element, we need to account for
405197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            // the inline elements position in PaintInvalidationState.
406d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (box->style()->position() == AbsolutePosition) {
4079e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                RenderObject* container = box->container(&paintInvalidationContainerForChild, 0);
408197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                if (container->isRelPositioned() && container->isRenderInline()) {
409197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                    // FIXME: We should be able to use PaintInvalidationState for this.
410197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                    // Currently, we will place absolutely positioned elements inside
411d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                    // relatively positioned inline blocks in the wrong location. crbug.com/371485
412197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                    ForceHorriblySlowRectMapping slowRectMapping(&childPaintInvalidationState);
4139e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                    PaintInvalidationState disabledPaintInvalidationState(childPaintInvalidationState, *this, paintInvalidationContainerForChild);
414197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                    box->invalidateTreeIfNeeded(disabledPaintInvalidationState);
415d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                    continue;
416d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                }
417d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            }
418d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
419197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            box->invalidateTreeIfNeeded(childPaintInvalidationState);
420d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        }
421f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    }
422f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu}
423f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeChild && beforeChild->parent() == this)
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return this;
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* curr = toRenderBlock(continuation());
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* nextToLast = this;
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* last = this;
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (curr) {
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (beforeChild && beforeChild->parent() == curr) {
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (curr->firstChild() == beforeChild)
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return last;
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return curr;
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nextToLast = last;
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        last = curr;
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = toRenderBlock(curr->continuation());
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!beforeChild && !last->firstChild())
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return nextToLast;
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return last;
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* flow = continuationBefore(beforeChild);
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* beforeChildParent = 0;
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeChild)
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBoxModelObject* cont = flow->continuation();
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (cont)
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            beforeChildParent = cont;
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            beforeChildParent = flow;
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newChild->isFloatingOrOutOfFlowPositioned()) {
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // A continuation always consists of two potential candidates: a block or an anonymous
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // column span box holding column span children.
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (flow == beforeChildParent) {
4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        flow->addChildIgnoringContinuation(newChild, beforeChild);
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
47902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The goal here is to match up if we can, so that we can coalesce and create the
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // minimal # of continuations needed for the inline.
4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (childIsNormal == bcpIsNormal) {
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (flowIsNormal == childIsNormal) {
4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
49702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The goal is to locate a suitable box in which to place our child.
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* beforeChildParent = 0;
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeChild) {
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* curr = beforeChild;
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (curr && curr->parent() != this)
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            curr = curr->parent();
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChildParent = toRenderBlock(curr);
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(beforeChildParent);
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(beforeChildParent->isAnonymousColumnsBlock() || beforeChildParent->isAnonymousColumnSpanBlock());
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChildParent = toRenderBlock(lastChild());
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the new child is floating or positioned it can just go in that block.
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newChild->isFloatingOrOutOfFlowPositioned()) {
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // See if the child can be placed in the box.
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline();
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) {
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!beforeChild) {
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Create a new block of the correct type.
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        children()->appendChildNode(this, newBox);
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* immediateChild = beforeChild;
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isPreviousBlockViable = true;
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (immediateChild->parent() != this) {
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isPreviousBlockViable)
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            isPreviousBlockViable = !immediateChild->previousSibling();
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        immediateChild = immediateChild->parent();
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isPreviousBlockViable && immediateChild->previousSibling()) {
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
54402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Split our anonymous blocks.
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* newBeforeChild = splitAnonymousBoxesAroundChild(beforeChild);
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
54802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Create a new anonymous box of the appropriate type.
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    children()->insertChildNode(this, newBox, newBeforeChild);
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return;
5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
556a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)RenderBlockFlow* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RenderObject* curr = this; curr; curr = curr->parent()) {
5606f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        if (!curr->isRenderBlock() || curr->isFloatingOrOutOfFlowPositioned() || curr->isTableCell() || curr->isDocumentElement() || curr->isRenderView() || curr->hasOverflowClip()
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            || curr->isInlineBlockOrInlineTable())
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 0;
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
564a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        // FIXME: Renderers that do special management of their children (tables, buttons,
565a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        // lists, flexboxes, etc.) breaks when the flow is split through them. Disabling
566a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        // multi-column for them to avoid this problem.)
567a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        if (!curr->isRenderBlockFlow() || curr->isListItem())
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 0;
56902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
570a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        RenderBlockFlow* currBlock = toRenderBlockFlow(curr);
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!currBlock->createsAnonymousWrapper())
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            firstChildIgnoringAnonymousWrappers = currBlock;
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
575a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            return toRenderBlockFlow(firstChildIgnoringAnonymousWrappers);
57602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (currBlock->isAnonymousColumnSpanBlock())
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 0;
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderBlock* RenderBlock::clone() const
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* cloneBlock;
5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isAnonymousBlock()) {
5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cloneBlock = createAnonymousBlock();
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cloneBlock->setChildrenInline(childrenInline());
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
591591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        RenderObject* cloneRenderer = toElement(node())->createRenderer(style());
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cloneBlock = toRenderBlock(cloneRenderer);
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cloneBlock->setStyle(style());
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This takes care of setting the right value of childrenInline in case
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // generated content is added to cloneBlock and 'this' does not have
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // generated content added yet.
5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->firstChild()->isInline() : childrenInline());
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
600926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    cloneBlock->setFlowThreadState(flowThreadState());
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return cloneBlock;
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                              RenderBlock* middleBlock,
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                              RenderObject* beforeChild, RenderBoxModelObject* oldCont)
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Create a clone of this inline.
6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* cloneBlock = clone();
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isAnonymousBlock())
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cloneBlock->setContinuation(oldCont);
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!beforeChild && isAfterContent(lastChild()))
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChild = lastChild();
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If we are moving inline children from |this| to cloneBlock, then we need
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // to clear our line box tree.
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeChild && childrenInline())
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        deleteLineBoxTree();
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now take all of the children from beforeChild to the end and remove
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // them from |this| and place them in the clone.
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    moveChildrenTo(cloneBlock, beforeChild, 0, true);
62402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Hook |clone| up as the continuation of the middle block.
6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!cloneBlock->isAnonymousBlock())
6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        middleBlock->setContinuation(cloneBlock);
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We have been reparented and are now under the fromBlock.  We need
6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // to walk up our block parent chain until we hit the containing anonymous columns block.
6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Once we hit the anonymous columns block we're done.
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
6335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* currChild = this;
6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* currChildNextSibling = currChild->nextSibling();
6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
63653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    while (curr && curr->isDescendantOf(fromBlock) && curr != fromBlock) {
637926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT_WITH_SECURITY_IMPLICATION(curr->isRenderBlock());
63802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBlock* blockCurr = toRenderBlock(curr);
64002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Create a new clone.
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBlock* cloneChild = cloneBlock;
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cloneBlock = blockCurr->clone();
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Insert our child clone as the first child.
6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cloneBlock->addChildIgnoringContinuation(cloneChild, 0);
6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Hook the clone up as a continuation of |curr|.  Note we do encounter
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // anonymous blocks possibly as we walk up the block chain.  When we split an
6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // anonymous block, there's no need to do any continuation hookup, since we haven't
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // actually split a real element.
6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!blockCurr->isAnonymousBlock()) {
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            oldCont = blockCurr->continuation();
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            blockCurr->setContinuation(cloneBlock);
6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            cloneBlock->setContinuation(oldCont);
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Now we need to take all of the children starting from the first child
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // *after* currChild and append them all to the clone.
6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true);
6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Keep walking up the chain.
6635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        currChild = curr;
6645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        currChildNextSibling = currChild->nextSibling();
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = toRenderBoxModelObject(curr->parent());
6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now we are at the columns block level. We need to put the clone into the toBlock.
6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    toBlock->children()->appendChildNode(toBlock, cloneBlock);
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now take all the children after currChild and remove them from the fromBlock
6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // and put them in the toBlock.
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true);
6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            RenderObject* newChild, RenderBoxModelObject* oldCont)
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* pre = 0;
6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* block = containingColumnsBlock();
68102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Delete our line boxes before we do the inline split into continuations.
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->deleteLineBoxTree();
68402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool madeNewBeforeBlock = false;
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (block->isAnonymousColumnsBlock()) {
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We can reuse this block and make it the preBlock of the next continuation.
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pre = block;
6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pre->removePositionedObjects(0);
690f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        if (block->isRenderBlockFlow())
691f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            toRenderBlockFlow(pre)->removeFloatingObjects();
6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        block = toRenderBlock(block->parent());
6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // No anonymous block available for use.  Make one.
6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pre = block->createAnonymousColumnsBlock();
6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pre->setChildrenInline(false);
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        madeNewBeforeBlock = true;
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* post = block->createAnonymousColumnsBlock();
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    post->setChildrenInline(false);
7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (madeNewBeforeBlock)
7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        block->children()->insertChildNode(block, pre, boxFirst);
7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->children()->insertChildNode(block, newBlockBox, boxFirst);
7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->children()->insertChildNode(block, post, boxFirst);
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->setChildrenInline(false);
70902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (madeNewBeforeBlock)
7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        block->moveChildrenTo(pre, boxFirst, 0, true);
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // time in makeChildrenNonInline by just setting this explicitly up front.
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newBlockBox->setChildrenInline(false);
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newBlockBox->addChild(newChild);
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // get deleted properly.  Because objects moves from the pre block into the post block, we want to
7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // make new line boxes instead of leaving the old line boxes around.
7245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
7255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
7265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
729a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlockFlow* newBlockBox, RenderObject* newChild)
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
731a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    RenderBlockFlow* pre = 0;
732a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    RenderBlockFlow* post = 0;
7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                               // so that we don't have to patch all of the rest of the code later on.
73502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Delete the block's line boxes before we do the split.
7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->deleteLineBoxTree();
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeChild && beforeChild->parent() != this)
7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeChild != firstChild()) {
7435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pre = block->createAnonymousColumnsBlock();
7445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pre->setChildrenInline(block->childrenInline());
7455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeChild) {
7485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        post = block->createAnonymousColumnsBlock();
7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        post->setChildrenInline(block->childrenInline());
7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* boxFirst = block->firstChild();
7535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (pre)
7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        block->children()->insertChildNode(block, pre, boxFirst);
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->children()->insertChildNode(block, newBlockBox, boxFirst);
7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (post)
7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        block->children()->insertChildNode(block, post, boxFirst);
7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->setChildrenInline(false);
75902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The pre/post blocks always have layers, so we know to always do a full insert/remove (so we pass true as the last argument).
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->moveChildrenTo(pre, boxFirst, beforeChild, true);
7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    block->moveChildrenTo(post, beforeChild, 0, true);
7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // time in makeChildrenNonInline by just setting this explicitly up front.
7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newBlockBox->setChildrenInline(false);
7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newBlockBox->addChild(newChild);
7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // get deleted properly.  Because objects moved from the pre block into the post block, we want to
7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // make new line boxes instead of leaving the old line boxes around.
7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (pre)
7745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
7755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (post)
7775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
780a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)RenderBlockFlow* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
7815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: This function is the gateway for the addition of column-span support.  It will
7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // be added to in three stages:
7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (1) Immediate children of a multi-column block can span.
7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // cross the streams and have to cope with both types of continuations mixed together).
7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This function currently supports (1) and (2).
789a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    RenderBlockFlow* columnsBlockAncestor = 0;
7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        && !newChild->isFloatingOrOutOfFlowPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        columnsBlockAncestor = containingColumnsBlock(false);
7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (columnsBlockAncestor) {
7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Make sure that none of the parent ancestors have a continuation.
7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If yes, we do not want split the block into continuations.
7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderObject* curr = this;
7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (curr && curr != columnsBlockAncestor) {
7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    columnsBlockAncestor = 0;
8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    break;
8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                curr = curr->parent();
8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return columnsBlockAncestor;
8075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeChild && beforeChild->parent() != this) {
8125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* beforeChildContainer = beforeChild->parent();
8135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (beforeChildContainer->parent() != this)
8145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            beforeChildContainer = beforeChildContainer->parent();
8155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(beforeChildContainer);
8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (beforeChildContainer->isAnonymous()) {
8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If the requested beforeChild is not one of our children, then this is because
8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // there is an anonymous container within this object that contains the beforeChild.
8205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderObject* beforeChildAnonymousContainer = beforeChildContainer;
8215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (beforeChildAnonymousContainer->isAnonymousBlock()
8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Full screen renderers and full screen placeholders act as anonymous blocks, not tables:
8235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                || beforeChildAnonymousContainer->isRenderFullScreen()
8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                || beforeChildAnonymousContainer->isRenderFullScreenPlaceholder()
8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ) {
8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Insert the child into the anonymous block box instead of here.
827d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                if (newChild->isInline() || newChild->isFloatingOrOutOfFlowPositioned() || beforeChild->parent()->slowFirstChild() != beforeChild)
8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    beforeChild->parent()->addChild(newChild, beforeChild);
8295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else
8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    addChild(newChild, beforeChild->parent());
8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return;
8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(beforeChildAnonymousContainer->isTable());
8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (newChild->isTablePart()) {
8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Insert into the anonymous table.
8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                beforeChildAnonymousContainer->addChild(newChild, beforeChild);
8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return;
8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(beforeChild->parent() == this);
8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (beforeChild->parent() != this) {
8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // We should never reach here. If we do, we need to use the
8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // safe fallback to use the topmost beforeChild container.
8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                beforeChild = beforeChildContainer;
8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Check for a spanning element in columns.
85310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (gColumnFlowSplitEnabled && !document().regionBasedColumnsEnabled()) {
854a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        RenderBlockFlow* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
855926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (columnsBlockAncestor) {
856926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
857926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // We are placing a column-span element inside a block.
858a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            RenderBlockFlow* newBox = createAnonymousColumnSpanBlock();
85902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
860e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch            if (columnsBlockAncestor != this && !isRenderFlowThread()) {
861926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                // We are nested inside a multi-column element and are being split by the span. We have to break up
862926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                // our block into continuations.
863926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                RenderBoxModelObject* oldContinuation = continuation();
864926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
865926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                // When we split an anonymous block, there's no need to do any continuation hookup,
866926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                // since we haven't actually split a real element.
867926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (!isAnonymousBlock())
868926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    setContinuation(newBox);
869926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
870926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                splitFlow(beforeChild, newBox, newChild, oldContinuation);
871926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                return;
8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
874926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // We have to perform a split of this block's children. This involves creating an anonymous block box to hold
875926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
876926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
877926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool madeBoxesNonInline = false;
8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // A block has to either have all of its children inline, or all of its children as blocks.
8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // So, if our children are currently inline and a block child has to be inserted, we move all our
8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // inline children into anonymous block boxes.
8875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned()) {
8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This is a block with inline content. Wrap the inline content in anonymous blocks.
8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        makeChildrenNonInline(beforeChild);
8905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        madeBoxesNonInline = true;
8915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (beforeChild && beforeChild->parent() != this) {
8935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            beforeChild = beforeChild->parent();
8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(beforeChild->isAnonymousBlock());
8955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(beforeChild->parent() == this);
8965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
8975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else if (!childrenInline() && (newChild->isFloatingOrOutOfFlowPositioned() || newChild->isInline())) {
8985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we're inserting an inline child but all of our children are blocks, then we have to make sure
8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // a new one is created and inserted into our list of children in the appropriate position.
9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (afterChild && afterChild->isAnonymousBlock()) {
9045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            afterChild->addChild(newChild);
9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
9065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (newChild->isInline()) {
9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // No suitable existing anonymous box - create a new one.
9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBlock* newBox = createAnonymousBlock();
9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBox::addChild(newBox, beforeChild);
9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            newBox->addChild(newChild);
9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
9145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBox::addChild(newChild, beforeChild);
91802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
9205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // this object may be dead here
9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (continuation() && !isAnonymousBlock())
9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        addChildToContinuation(newChild, beforeChild);
9285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        addChildIgnoringContinuation(newChild, beforeChild);
9305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        addChildToAnonymousColumnBlocks(newChild, beforeChild);
9365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
9375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
9385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void getInlineRun(RenderObject* start, RenderObject* boundary,
9415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                         RenderObject*& inlineRunStart,
9425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                         RenderObject*& inlineRunEnd)
9435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Beginning at |start| we find the largest contiguous run of inlines that
9455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // we can.  We denote the run with start and end points, |inlineRunStart|
9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // and |inlineRunEnd|.  Note that these two values may be the same if
9475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // we encounter only one inline.
9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We skip any non-inlines we encounter as long as we haven't found any
9505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // inlines yet.
9515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //
9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
9535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
9545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // a non-inline.
95502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Start by skipping as many non-inlines as we can.
9575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject * curr = start;
9585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool sawInline;
9595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    do {
9605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (curr && !(curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()))
9615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            curr = curr->nextSibling();
96202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        inlineRunStart = inlineRunEnd = curr;
96402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!curr)
9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return; // No more inline children to be found.
96702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        sawInline = curr->isInline();
96902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = curr->nextSibling();
9715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (curr && (curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()) && (curr != boundary)) {
9725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            inlineRunEnd = curr;
9735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (curr->isInline())
9745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                sawInline = true;
9755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            curr = curr->nextSibling();
9765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } while (!sawInline);
9785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::deleteLineBoxTree()
9815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
982c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(!m_lineBoxes.firstLineBox());
9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
98602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{
9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // makeChildrenNonInline takes a block whose children are *all* inline and it
9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // makes sure that inline children are coalesced under anonymous
9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // the new block child that is causing us to have to wrap all the inlines.  This
9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // means that we cannot coalesce inlines before |insertionPoint| with inlines following
9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // |insertionPoint|, because the new child is going to be inserted in between the inlines,
9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // splitting them.
9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(isInlineBlockOrInlineTable() || !isInline());
9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!insertionPoint || insertionPoint->parent() == this);
9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setChildrenInline(false);
9985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject *child = firstChild();
10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!child)
10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    deleteLineBoxTree();
10045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (child) {
10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject *inlineRunStart, *inlineRunEnd;
10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!inlineRunStart)
10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        child = inlineRunEnd->nextSibling();
10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBlock* block = createAnonymousBlock();
10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        children()->insertChildNode(this, block, inlineRunStart);
10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        moveChildrenTo(block, inlineRunStart, child);
10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1019197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RenderObject *c = firstChild(); c; c = c->nextSibling())
10215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!c->isInline());
10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
10235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10249e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    setShouldDoFullPaintInvalidation(true);
10255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(child->isAnonymousBlock());
10305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!child->childrenInline());
103102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
10325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
10335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
103402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
10355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* firstAnChild = child->m_children.firstChild();
10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* lastAnChild = child->m_children.lastChild();
10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (firstAnChild) {
10385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* o = firstAnChild;
10395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (o) {
10405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            o->setParent(this);
10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            o = o->nextSibling();
10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        firstAnChild->setPreviousSibling(child->previousSibling());
10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lastAnChild->setNextSibling(child->nextSibling());
10455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (child->previousSibling())
10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            child->previousSibling()->setNextSibling(firstAnChild);
10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (child->nextSibling())
10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            child->nextSibling()->setPreviousSibling(lastAnChild);
104902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (child == m_children.firstChild())
10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_children.setFirstChild(firstAnChild);
10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (child == m_children.lastChild())
10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_children.setLastChild(lastAnChild);
10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (child == m_children.firstChild())
10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_children.setFirstChild(child->nextSibling());
10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (child == m_children.lastChild())
10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_children.setLastChild(child->previousSibling());
10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (child->previousSibling())
10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            child->previousSibling()->setNextSibling(child->nextSibling());
10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (child->nextSibling())
10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            child->nextSibling()->setPreviousSibling(child->previousSibling());
10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1065926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1066926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    child->children()->setFirstChild(0);
1067e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    child->m_next = nullptr;
1068926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1069926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Remove all the information in the flow thread associated with the leftover anonymous block.
1070926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    child->removeFromRenderFlowThread();
1071926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
10725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // RenderGrid keeps track of its children, we must notify it about changes in the tree.
10735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (child->parent()->isRenderGrid())
10745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        toRenderGrid(child->parent())->dirtyGrid();
10755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
107651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    child->setParent(0);
10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    child->setPreviousSibling(0);
10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    child->setNextSibling(0);
10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    child->destroy();
10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
10865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
10895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || (next && (next->isRubyRun() || next->isRubyBase())))
10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
10955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!prev || !next)
10975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Make sure the types of the anonymous blocks match up.
11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)           && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
11025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11048abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)void RenderBlock::collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock* child)
11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11068abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // It's possible that this block's destruction may have been triggered by the
11078abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // child's removal. Just bail if the anonymous child block is already being
11088abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // destroyed. See crbug.com/282088
11098abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (child->beingDestroyed())
11108abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        return;
11115d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    parent->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
11125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parent->setChildrenInline(child->childrenInline());
11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* nextSibling = child->nextSibling();
11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RenderFlowThread* childFlowThread = child->flowThreadContainingBlock();
11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    CurrentRenderFlowThreadMaintainer flowThreadMaintainer(childFlowThread);
111702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
11188abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    parent->children()->removeChildNode(parent, child, child->hasLayer());
1119f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch    // FIXME: Get rid of the temporary disabling of continuations. This is needed by the old
1120f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch    // multicol implementation, because of buggy block continuation handling (which is hard and
1121f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch    // rather pointless to fix at this point). Support for block continuations can be removed
1122f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch    // together with the old multicol implementation. crbug.com/408123
1123f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch    RenderBoxModelObject* temporarilyInactiveContinuation = parent->continuation();
1124f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch    if (temporarilyInactiveContinuation)
1125f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch        parent->setContinuation(0);
11268abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    child->moveAllChildrenTo(parent, nextSibling, child->hasLayer());
1127f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch    if (temporarilyInactiveContinuation)
1128f542a0e9557608d421c9d165487573efa35a5f91Ben Murdoch        parent->setContinuation(temporarilyInactiveContinuation);
11298abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // Explicitly delete the child's line box tree, or the special anonymous
11308abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // block handling in willBeDestroyed will cause problems.
11318abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    child->deleteLineBoxTree();
11328abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    child->destroy();
11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::removeChild(RenderObject* oldChild)
11365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // No need to waste time in merging or removing empty anonymous blocks.
11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We can just bail out if our document is getting destroyed.
11395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (documentBeingDestroyed()) {
11405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBox::removeChild(oldChild);
11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // This protects against column split flows when anonymous blocks are getting merged.
1145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
1146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If this child is a block, and if our previous and next siblings are
11485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // both anonymous blocks with inline content, then we can go ahead and
11495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // fold the inline content back together.
11505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* prev = oldChild->previousSibling();
11515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* next = oldChild->nextSibling();
11525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
11535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (canMergeAnonymousBlocks && prev && next) {
11545d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        prev->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
115509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        RenderBlockFlow* nextBlock = toRenderBlockFlow(next);
115609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        RenderBlockFlow* prevBlock = toRenderBlockFlow(prev);
115702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
11585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (prev->childrenInline() != next->childrenInline()) {
11595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
116102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
11625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Place the inline children block inside of the block children block instead of deleting it.
11635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // to clear out inherited column properties by just making a new style, and to also clear the
11655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // column span flag if it is set.
11665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(!inlineChildrenBlock->continuation());
11675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK);
11685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Cache this value as it might get changed in setStyle() call.
11695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool inlineChildrenBlockHasLayer = inlineChildrenBlock->hasLayer();
11705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            inlineChildrenBlock->setStyle(newStyle);
11715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlockHasLayer);
117202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
11735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
11745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
11755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                            inlineChildrenBlockHasLayer || blockChildrenBlock->hasLayer());
11765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            next->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
117702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
11785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
11795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // of "this". we null out prev or next so that is not used later in the function.
11805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (inlineChildrenBlock == prevBlock)
11815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                prev = 0;
11825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
11835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                next = 0;
11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
11855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Take all the children out of the |next| block and put them in
11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // the |prev| block.
1187e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            nextBlock->moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
118802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Delete the now-empty block's lines and nuke it.
11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            nextBlock->deleteLineBoxTree();
11915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            nextBlock->destroy();
11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            next = 0;
11935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
11945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBox::removeChild(oldChild);
11975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* child = prev ? prev : next;
11995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && canCollapseAnonymousBlockChild()) {
12005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The removal has knocked us down to containing only a single anonymous
12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // box.  We can go ahead and pull the content right back up into our
12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // box.
12038abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        collapseAnonymousBlockChild(this, toRenderBlock(child));
12045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && canCollapseAnonymousBlockChild()) {
12055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // It's possible that the removal has knocked us down to a single anonymous
12065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // block with pseudo-style element siblings (e.g. first-letter). If these
12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // are floating, then we need to pull the content up also.
12088abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        RenderBlock* anonymousBlock = toRenderBlock((prev && prev->isAnonymousBlock()) ? prev : next);
12098abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if ((anonymousBlock->previousSibling() || anonymousBlock->nextSibling())
12108abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            && (!anonymousBlock->previousSibling() || (anonymousBlock->previousSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->previousSibling()->isFloating() && !anonymousBlock->previousSibling()->previousSibling()))
12118abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            && (!anonymousBlock->nextSibling() || (anonymousBlock->nextSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->nextSibling()->isFloating() && !anonymousBlock->nextSibling()->nextSibling()))) {
12128abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            collapseAnonymousBlockChild(this, anonymousBlock);
12135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
12145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!firstChild()) {
12175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If this was our last child be sure to clear out our line boxes.
12185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (childrenInline())
12195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            deleteLineBoxTree();
12205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we are an empty anonymous block in the continuation chain,
12225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // we need to remove ourself and fix the continuation chain.
12235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild->isListMarker()) {
12245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderObject* containingBlockIgnoringAnonymous = containingBlock();
1225197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymous())
12265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
12275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (RenderObject* curr = this; curr; curr = curr->previousInPreOrder(containingBlockIgnoringAnonymous)) {
12285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (curr->virtualContinuation() != this)
12295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    continue;
12305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Found our previous continuation. We just need to point it to
12325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // |this|'s next continuation.
12335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                RenderBoxModelObject* nextContinuation = continuation();
12345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (curr->isRenderInline())
12355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    toRenderInline(curr)->setContinuation(nextContinuation);
12365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else if (curr->isRenderBlock())
12375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    toRenderBlock(curr)->setContinuation(nextContinuation);
12385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                else
12395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    ASSERT_NOT_REACHED();
12405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
12425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
12435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            setContinuation(0);
12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            destroy();
12455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
12465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderBlock::isSelfCollapsingBlock() const
12505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We are not self-collapsing if we
12525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
12535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (b) are a table,
12545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (c) have border/padding,
12555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (d) have a min-height
12565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (e) have specified that one of our margins can't collapse using a CSS extension
125709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // (f) establish a new block formatting context.
125809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
1259f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // The early exit must be done before we check for clean layout.
1260f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // We should be able to give a quick answer if the box is a relayout boundary.
1261f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // Being a relayout boundary implies a block formatting context, and also
1262f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // our internal layout shouldn't affect our container in any way.
126309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (createsBlockFormattingContext())
126409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return false;
126509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
1266f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // Placeholder elements are not laid out until the dimensions of their parent text control are known, so they
1267f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // don't get layout until their parent has had layout - this is unique in the layout tree and means
1268f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    // when we call isSelfCollapsingBlock on them we find that they still need layout.
1269f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    ASSERT(!needsLayout() || (node() && node()->isElementNode() && toElement(node())->shadowPseudoId() == "-webkit-input-placeholder"));
1270f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (logicalHeight() > 0
12725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || isTable() || borderAndPaddingLogicalHeight()
12735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || style()->logicalMinHeight().isPositive()
12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
12755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
12765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Length logicalHeightLength = style()->logicalHeight();
12785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasAutoHeight = logicalHeightLength.isAuto();
12798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (logicalHeightLength.isPercent() && !document().inQuirksMode()) {
12805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        hasAutoHeight = true;
12815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
12825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
12835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                hasAutoHeight = false;
12845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
12855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
12885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // on whether we have content that is all self-collapsing or not.
12895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
12905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If the block has inline children, see if we generated any line boxes.  If we have any
12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // line boxes, then we can't be self-collapsing, since we have content.
12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (childrenInline())
12935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return !firstLineBox();
129402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
12955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Whether or not we collapse is dependent on whether all our normal flow children
12965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // are also self-collapsing.
129709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (m_hasOnlySelfCollapsingChildren)
129809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return true;
12995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (child->isFloatingOrOutOfFlowPositioned())
13015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
13025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!child->isSelfCollapsingBlock())
13035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return false;
13045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
13085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::startDelayUpdateScrollInfo()
13115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (gDelayUpdateScrollInfo == 0) {
13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!gDelayedUpdateScrollInfoSet);
13145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
13155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(gDelayedUpdateScrollInfoSet);
13175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ++gDelayUpdateScrollInfo;
13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::finishDelayUpdateScrollInfo()
13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    --gDelayUpdateScrollInfo;
13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(gDelayUpdateScrollInfo >= 0);
13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (gDelayUpdateScrollInfo == 0) {
13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(gDelayedUpdateScrollInfoSet);
13265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        OwnPtr<DelayedUpdateScrollInfoSet> infoSet(adoptPtr(gDelayedUpdateScrollInfoSet));
13285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        gDelayedUpdateScrollInfoSet = 0;
13295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
13315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderBlock* block = *it;
13325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (block->hasOverflowClip()) {
1333f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)                block->layer()->scrollableArea()->updateAfterLayout();
13345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
13355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
13365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::updateScrollInfoAfterLayout()
13405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasOverflowClip()) {
13425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (style()->isFlippedBlocksWritingMode()) {
13435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=97937
13445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Workaround for now. We cannot delay the scroll info for overflow
13455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // for items with opposite writing directions, as the contents needs
13465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // to overflow in that direction
1347f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            layer()->scrollableArea()->updateAfterLayout();
13485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
13495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
13505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (gDelayUpdateScrollInfo)
13525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            gDelayedUpdateScrollInfoSet->add(this);
13535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
1354f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            layer()->scrollableArea()->updateAfterLayout();
13555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::layout()
13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    OverflowEventDispatcher dispatcher(this);
13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Update our first letter info now.
13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    updateFirstLetter();
13645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
13665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // layoutBlock().
13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    layoutBlock(false);
136802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // It's safe to check for control clip here, since controls can never be table cells.
13705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If we have a lightweight clip, there can never be any overflow from children.
13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasControlClip() && m_overflow)
13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        clearLayoutOverflow();
1373926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1374926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    invalidateBackgroundObscurationStatus();
13755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
137709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool RenderBlock::updateImageLoadingPriorities()
1378a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
1379a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    Vector<ImageResource*> images;
138009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    appendImagesFromStyle(images, *style());
1381a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
1382a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (images.isEmpty())
138309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return false;
1384a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
1385a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    LayoutRect viewBounds = viewRect();
1386a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    LayoutRect objectBounds = absoluteContentBox();
1387a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // The object bounds might be empty right now, so intersects will fail since it doesn't deal
1388a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // with empty rects. Use LayoutRect::contains in that case.
1389a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    bool isVisible;
1390a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!objectBounds.isEmpty())
1391a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        isVisible =  viewBounds.intersects(objectBounds);
1392a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    else
1393a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        isVisible = viewBounds.contains(objectBounds);
1394a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
1395a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ResourceLoadPriorityOptimizer::VisibilityStatus status = isVisible ?
1396a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        ResourceLoadPriorityOptimizer::Visible : ResourceLoadPriorityOptimizer::NotVisible;
1397a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
139807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    LayoutRect screenArea;
139907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    if (!objectBounds.isEmpty()) {
140007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        screenArea = viewBounds;
140107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        screenArea.intersect(objectBounds);
140207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    }
140307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
1404a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    for (Vector<ImageResource*>::iterator it = images.begin(), end = images.end(); it != end; ++it)
140507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->notifyImageResourceVisibility(*it, status, screenArea);
140609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
140709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return true;
1408a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
1409a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
1410c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool RenderBlock::widthAvailableToChildrenHasChanged()
1411c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
1412c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool widthAvailableToChildrenHasChanged = m_hasBorderOrPaddingLogicalWidthChanged;
1413c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    m_hasBorderOrPaddingLogicalWidthChanged = false;
1414c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1415c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // If we use border-box sizing, have percentage padding, and our parent has changed width then the width available to our children has changed even
1416c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // though our own width has remained the same.
1417c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    widthAvailableToChildrenHasChanged |= style()->boxSizing() == BORDER_BOX && needsPreferredWidthsRecalculation() && view()->layoutState()->containingBlockLogicalWidthChanged();
1418c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1419c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return widthAvailableToChildrenHasChanged;
1420c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
1421c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderBlock::updateLogicalWidthAndColumnWidth()
14235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit oldWidth = logicalWidth();
14255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit oldColumnWidth = desiredColumnWidth();
14265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    updateLogicalWidth();
14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    calcColumnWidth();
14295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1430c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth() || widthAvailableToChildrenHasChanged();
14315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
143309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void RenderBlock::layoutBlock(bool)
14345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14358abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ASSERT_NOT_REACHED();
14363c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    clearNeedsLayout();
14375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::addOverflowFromChildren()
14405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!hasColumns()) {
14425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (childrenInline())
1443a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            toRenderBlockFlow(this)->addOverflowFromInlineChildren();
14445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
14455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            addOverflowFromBlockChildren();
14465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
14475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ColumnInfo* colInfo = columnInfo();
14485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (columnCount(colInfo)) {
14495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            LayoutRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
14505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            addLayoutOverflow(lastRect);
14513c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            addContentsVisualOverflow(lastRect);
14525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
14535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1456f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool)
14575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1458926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_overflow.clear();
1459926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
14605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Add overflow from children.
14615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addOverflowFromChildren();
14625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Add in the overflow from positioned objects.
14645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addOverflowFromPositionedObjects();
14655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasOverflowClip()) {
14675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
14685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
14695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // be considered reachable.
147002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        LayoutRect clientRect(noOverflowRect());
14715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LayoutRect rectToApply;
14725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isHorizontalWritingMode())
1473197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            rectToApply = LayoutRect(clientRect.x(), clientRect.y(), 1, std::max<LayoutUnit>(0, oldClientAfterEdge - clientRect.y()));
14745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else
1475197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            rectToApply = LayoutRect(clientRect.x(), clientRect.y(), std::max<LayoutUnit>(0, oldClientAfterEdge - clientRect.x()), 1);
14765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        addLayoutOverflow(rectToApply);
1477926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (hasRenderOverflow())
1478926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge);
14795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
148002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
14815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addVisualEffectOverflow();
14825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addVisualOverflowFromTheme();
14845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::addOverflowFromBlockChildren()
14875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
14895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!child->isFloatingOrOutOfFlowPositioned())
14905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            addOverflowFromChild(child);
14915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::addOverflowFromPositionedObjects()
14955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TrackedRendererListHashSet* positionedDescendants = positionedObjects();
14975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!positionedDescendants)
14985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBox* positionedObject;
15015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TrackedRendererListHashSet::iterator end = positionedDescendants->end();
15025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
15035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        positionedObject = *it;
150402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
15055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
150651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (positionedObject->style()->position() != FixedPosition)
150751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            addOverflowFromChild(positionedObject, LayoutSize(positionedObject->x(), positionedObject->y()));
15085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::addVisualOverflowFromTheme()
15125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!style()->hasAppearance())
15145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
15155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IntRect inflatedRect = pixelSnappedBorderBoxRect();
15179e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    RenderTheme::theme().adjustPaintInvalidationRect(this, inflatedRect);
15185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addVisualOverflow(inflatedRect);
15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1521197021e6b966cfb06891637935ef33fff06433d1Ben Murdochbool RenderBlock::createsBlockFormattingContext() const
1522197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
1523197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || isFlexItemIncludingDeprecated()
1524197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        || style()->specifiesColumns() || isRenderFlowThread() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isDocumentElement() || style()->columnSpan();
1525197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
1526197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1527926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox* child)
1528926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1529926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
1530926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // an auto value. Add a method to determine this, so that we can avoid the relayout.
15315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (relayoutChildren || (child->hasRelativeLogicalHeight() && !isRenderView()))
15323c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        child->setChildNeedsLayout(MarkOnlyThis);
1533926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1534926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
1535926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (relayoutChildren && child->needsPreferredWidthsRecalculation())
1536c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        child->setPreferredLogicalWidthsDirty(MarkOnlyThis);
1537926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
1538926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::simplifiedNormalFlowLayout()
15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (childrenInline()) {
15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ListHashSet<RootInlineBox*> lineBoxes;
15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RenderObject* o = walker.current();
15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!o->isOutOfFlowPositioned() && (o->isReplaced() || o->isFloating())) {
15465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                o->layoutIfNeeded();
15475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (toRenderBox(o)->inlineBoxWrapper()) {
1548d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    RootInlineBox& box = toRenderBox(o)->inlineBoxWrapper()->root();
1549d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    lineBoxes.add(&box);
15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
15513c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            } else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline())) {
15523c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                o->clearNeedsLayout();
15533c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            }
15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
155702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        GlyphOverflowAndFallbackFontsMap textBoxDataMap;
15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RootInlineBox* box = *it;
15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
15615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
15625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!box->isOutOfFlowPositioned())
15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                box->layoutIfNeeded();
15665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderBlock::simplifiedLayout()
15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
157210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    // Check if we need to do a full layout.
157310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (normalChildNeedsLayout() || selfNeedsLayout())
157410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        return false;
157510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch
157610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    // Check that we actually need to do a simplified layout.
157710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (!posChildNeedsLayout() && !(needsSimplifiedNormalFlowLayout() || needsPositionedMovementLayout()))
15785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
158002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
158107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    {
15829e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        // LayoutState needs this deliberate scope to pop before paint invalidation.
15835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        LayoutState state(*this, locationOffset());
158407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
158507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
158607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            return false;
15875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1588c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        TextAutosizer::LayoutScope textAutosizerLayoutScope(this);
158907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
159007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // Lay out positioned descendants or objects that just need to recompute overflow.
159107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (needsSimplifiedNormalFlowLayout())
159207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            simplifiedNormalFlowLayout();
159307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
159407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // Lay out our positioned objects if our positioned child bit is set.
159507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
159607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // child, neither the fixed element nor its container learn of the movement since posChildNeedsLayout() is only marked as far as the
159707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // relative positioned container. So if we can have fixed pos objects in our positioned objects list check if any of them
159807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // are statically positioned and thus need to move with their absolute ancestors.
159907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        bool canContainFixedPosObjects = canContainFixedPositionObjects();
160010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        if (posChildNeedsLayout() || needsPositionedMovementLayout() || canContainFixedPosObjects)
160110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            layoutPositionedObjects(false, needsPositionedMovementLayout() ? ForcedLayoutAfterContainingBlockMoved : (!posChildNeedsLayout() && canContainFixedPosObjects ? LayoutOnlyFixedPositionedObjects : DefaultLayout));
160207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
160307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // Recompute our overflow information.
160407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
160507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
160607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // For now just always recompute overflow. This is no worse performance-wise than the old code that called rightmostPosition and
160707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // lowestPosition on every relayout so it's not a regression.
160807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // computeOverflow expects the bottom edge before we clamp our height. Since this information isn't available during
160907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // simplifiedLayout, we cache the value in m_overflow.
161007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
161107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        computeOverflow(oldClientAfterEdge, true);
161207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    }
161302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
161476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    updateLayerTransformAfterLayout();
16155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    updateScrollInfoAfterLayout();
16175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16183c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    clearNeedsLayout();
16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
16205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1622e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void RenderBlock::markFixedPositionObjectForLayoutIfNeeded(RenderObject* child, SubtreeLayoutScope& layoutScope)
1623926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1624926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (child->style()->position() != FixedPosition)
1625926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
1626926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1627926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontalWritingMode());
1628926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    bool hasStaticInlinePosition = child->style()->hasStaticInlinePosition(isHorizontalWritingMode());
1629926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!hasStaticBlockPosition && !hasStaticInlinePosition)
1630926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
1631926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1632926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RenderObject* o = child->parent();
1633926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    while (o && !o->isRenderView() && o->style()->position() != AbsolutePosition)
1634926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        o = o->parent();
1635926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (o->style()->position() != AbsolutePosition)
1636926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
1637926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1638926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RenderBox* box = toRenderBox(child);
1639926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (hasStaticInlinePosition) {
1640d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LogicalExtentComputedValues computedValues;
1641d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        box->computeLogicalWidth(computedValues);
1642d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        LayoutUnit newLeft = computedValues.m_position;
1643d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (newLeft != box->logicalLeft())
1644e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            layoutScope.setChildNeedsLayout(child);
1645926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    } else if (hasStaticBlockPosition) {
1646926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        LayoutUnit oldTop = box->logicalTop();
1647926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        box->updateLogicalHeight();
1648926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (box->logicalTop() != oldTop)
1649e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            layoutScope.setChildNeedsLayout(child);
1650926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1651926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
1652926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
165306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)LayoutUnit RenderBlock::marginIntrinsicLogicalWidthForChild(RenderBox* child) const
165406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles){
165506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // A margin has three types: fixed, percentage, and auto (variable).
165606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Auto and percentage margins become 0 when computing min/max width.
165706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Fixed margins can be added in as is.
165806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    Length marginLeft = child->style()->marginStartUsing(style());
165906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    Length marginRight = child->style()->marginEndUsing(style());
166006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    LayoutUnit margin = 0;
166106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (marginLeft.isFixed())
166206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        margin += marginLeft.value();
166306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (marginRight.isFixed())
166406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        margin += marginRight.value();
166506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    return margin;
166606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)}
166706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)
1668d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RenderBlock::layoutPositionedObjects(bool relayoutChildren, PositionedLayoutBehavior info)
16695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TrackedRendererListHashSet* positionedDescendants = positionedObjects();
16715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!positionedDescendants)
16725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
167302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
16745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasColumns())
16755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
16765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBox* r;
16785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TrackedRendererListHashSet::iterator end = positionedDescendants->end();
16795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
16805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        r = *it;
1681926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1682a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        // FIXME: this should only be set from clearNeedsLayout crbug.com/361250
1683a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        r->setLayoutDidGetCalled(true);
168407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
168510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        SubtreeLayoutScope layoutScope(*r);
1686926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
168702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        // if this is a fixed position element, mark it for layout if it has an abspos ancestor and needs to move with that ancestor, i.e.
1688926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // it has static position.
1689e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        markFixedPositionObjectForLayoutIfNeeded(r, layoutScope);
1690d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (info == LayoutOnlyFixedPositionedObjects) {
1691926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            r->layoutIfNeeded();
1692926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            continue;
1693926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1694926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
16955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
16965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
16975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
16985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // positioned explicitly) this should not incur a performance penalty.
16995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this))
1700e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            layoutScope.setChildNeedsLayout(r);
170102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
17025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
17035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (relayoutChildren && r->needsPreferredWidthsRecalculation())
1704c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)            r->setPreferredLogicalWidthsDirty(MarkOnlyThis);
170502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
17065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!r->needsLayout())
1707e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            r->markForPaginationRelayoutIfNeeded(layoutScope);
170802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
17095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If we are paginated or in a line grid, go ahead and compute a vertical position for our object now.
17105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If it's wrong we'll lay out again.
17115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LayoutUnit oldLogicalTop = 0;
171202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        bool needsBlockDirectionLocationSetBeforeLayout = r->needsLayout() && view()->layoutState()->needsBlockDirectionLocationSetBeforeLayout();
17135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (needsBlockDirectionLocationSetBeforeLayout) {
17145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isHorizontalWritingMode() == r->isHorizontalWritingMode())
17155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                r->updateLogicalHeight();
17165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
17175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                r->updateLogicalWidth();
17185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            oldLogicalTop = logicalTopForChild(r);
17195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
172002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
17217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout() here instead of a full layout. Need
17227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // to investigate why it does not trigger the correct invalidations in that case. crbug.com/350756
1723d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (info == ForcedLayoutAfterContainingBlockMoved)
17247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            r->setNeedsLayout();
1725d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
17265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        r->layoutIfNeeded();
17275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Lay out again if our estimate was wrong.
1729f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop)
1730f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            r->forceChildLayout();
17315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
173202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
17335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasColumns())
173407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        view()->layoutState()->setColumnInfo(columnInfo()); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
17355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::markPositionedObjectsForLayout()
17385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1739c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (TrackedRendererListHashSet* positionedDescendants = positionedObjects()) {
17405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TrackedRendererListHashSet::iterator end = positionedDescendants->end();
1741c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it)
1742c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            (*it)->setChildNeedsLayout();
17435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
17445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1746e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void RenderBlock::markForPaginationRelayoutIfNeeded(SubtreeLayoutScope& layoutScope)
17475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!needsLayout());
17495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (needsLayout())
17505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
17515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1752d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(*this, logicalTop()) != pageLogicalOffset()))
1753e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        layoutScope.setChildNeedsLayout(this);
17545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
17575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    BlockPainter(*this).paint(paintInfo, paintOffset);
17595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
176193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
17625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    BlockPainter(*this).paintChildren(paintInfo, paintOffset);
17645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
17675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    BlockPainter(*this).paintObject(paintInfo, paintOffset);
17695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderInline* RenderBlock::inlineElementContinuation() const
177202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch{
17735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* continuation = this->continuation();
17745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
17755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderBlock* RenderBlock::blockElementContinuation() const
17785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBoxModelObject* currentContinuation = continuation();
17805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!currentContinuation || currentContinuation->isInline())
17815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
17825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
17835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (nextContinuation->isAnonymousBlock())
17845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return nextContinuation->blockElementContinuation();
17855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return nextContinuation;
17865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
178702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
17887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciContinuationOutlineTableMap* continuationOutlineTable()
17895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
17915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return &table;
17925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderBlock::addContinuationWithOutline(RenderInline* flow)
17955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We can't make this work if the inline is in a layer.  We'll just rely on the broken
17975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // way of painting.
17985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
179902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ContinuationOutlineTableMap* table = continuationOutlineTable();
18015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ListHashSet<RenderInline*>* continuations = table->get(this);
18025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!continuations) {
18035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        continuations = new ListHashSet<RenderInline*>;
1804926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        table->set(this, adoptPtr(continuations));
18055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
180602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    continuations->add(flow);
18085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderBlock::shouldPaintSelectionGaps() const
18115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
18135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderBlock::isSelectionRoot() const
18165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1817926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (isPseudoElement())
18185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1819926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(node() || isAnonymous());
182002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
18225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isTable())
18235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
182402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18256f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (isBody() || isDocumentElement() || hasOverflowClip()
18265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || isPositioned() || isFloating()
18275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || isTableCell() || isInlineBlockOrInlineTable()
18285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || hasTransform() || hasReflection() || hasMask() || isWritingModeRoot()
182910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        || isRenderFlowThread() || isFlexItemIncludingDeprecated())
18305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
183102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (view() && view()->selectionStart()) {
18335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node* startElement = view()->selectionStart()->node();
18345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (startElement && startElement->rootEditableElement() == node())
18355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
18365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
183702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
18395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciGapRects RenderBlock::selectionGapRectsForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
18425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!needsLayout());
18445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!shouldPaintSelectionGaps())
18465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return GapRects();
18475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
18499e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    mapLocalToContainer(paintInvalidationContainer, transformState, ApplyContainerFlip | UseTransforms);
18509e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    LayoutPoint offsetFromPaintInvalidationContainer = roundedLayoutPoint(transformState.mappedPoint());
18515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasOverflowClip())
18539e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        offsetFromPaintInvalidationContainer -= scrolledContentOffset();
18545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit lastTop = 0;
18565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
18575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
185802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18599e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return selectionGaps(this, offsetFromPaintInvalidationContainer, IntSize(), lastTop, lastLeft, lastRight);
18605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, TrackedRendererListHashSet* positionedObjects)
18635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!positionedObjects)
18655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
186602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
18675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TrackedRendererListHashSet::const_iterator end = positionedObjects->end();
18685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
18695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderBox* r = *it;
18705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
18715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
18725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
187451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)LayoutUnit RenderBlock::blockDirectionOffset(const LayoutSize& offsetFromBlock) const
18755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
187651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return isHorizontalWritingMode() ? offsetFromBlock.height() : offsetFromBlock.width();
18775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
187951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)LayoutUnit RenderBlock::inlineDirectionOffset(const LayoutSize& offsetFromBlock) const
18805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
188151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return isHorizontalWritingMode() ? offsetFromBlock.width() : offsetFromBlock.height();
18825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciLayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPhysicalPosition, const LayoutRect& logicalRect) const
18855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect result;
18875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isHorizontalWritingMode())
18885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result = logicalRect;
18895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
18905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result = LayoutRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
18915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    flipForWritingMode(result);
18925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result.moveBy(rootBlockPhysicalPosition);
18935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
18945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciGapRects RenderBlock::selectionGaps(const RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
18977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                                    LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo) const
18985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
19005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Clip out floating and positioned objects when painting selection gaps.
19015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (paintInfo) {
19025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
19035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
19045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        rootBlock->flipForWritingMode(flippedBlockRect);
19055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        flippedBlockRect.moveBy(rootBlockPhysicalPosition);
19065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positionedObjects());
19076f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        if (isBody() || isDocumentElement()) // The <body> must make sure to examine its containingBlock's positioned objects.
19085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
19095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->positionedObjects()); // FIXME: Not right for flipped writing modes.
1910f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        clipOutFloatingObjects(rootBlock, paintInfo, rootBlockPhysicalPosition, offsetFromRootBlock);
19115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
19125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled, the other is
19145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // fixed).
19155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GapRects result;
1916197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!isRenderBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
19175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return result;
19185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasColumns() || hasTransform() || style()->columnSpan()) {
19205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
192151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalHeight();
19225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
19235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
19245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return result;
19255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
19265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (childrenInline())
192851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        result = toRenderBlockFlow(this)->inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
19295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
19305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
19315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
19335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
193402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
19355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                             logicalHeight(), paintInfo));
19365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
19375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciGapRects RenderBlock::blockSelectionGaps(const RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
19407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                                         LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo) const
19415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
19425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    GapRects result;
19435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Go ahead and jump right to the first block child that contains some selected objects.
19455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderBox* curr;
19465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
19475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
19495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        SelectionState childState = curr->selectionState();
19505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (childState == SelectionBoth || childState == SelectionEnd)
19515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            sawSelectionEnd = true;
19525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curr->isFloatingOrOutOfFlowPositioned())
19545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue; // We must be a normal flow object in order to even be considered.
19555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1956197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (curr->isRelPositioned() && curr->hasLayer()) {
19575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
19585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Just disregard it completely.
1959e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch            LayoutSize relOffset = curr->layer()->offsetForInFlowPosition();
19605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (relOffset.width() || relOffset.height())
19615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
19625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
19635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
19655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
19665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (fillBlockGaps) {
19675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We need to fill the vertical gap above this object.
19685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (childState == SelectionEnd || childState == SelectionInside)
19695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Fill the gap above the object.
197002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch                result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
19715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                     curr->logicalTop(), paintInfo));
19725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Only fill side gaps for objects that paint their own selection if we know for sure the selection is going to extend all the way *past*
19745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // our object.  We know this if the selection did not end inside our object.
19755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
19765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                childState = SelectionNone;
19775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Fill side gaps on this object based off its state.
19795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool leftGap, rightGap;
19805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            getSelectionGapInfo(childState, leftGap, rightGap);
19815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (leftGap)
19835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
19845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (rightGap)
19855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
19865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
19885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // they can without bumping into floating or positioned objects.  Ideally they will go right up
19895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // to the border of the root selection block.
199051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + curr->logicalBottom();
19915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
19925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
19935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (childState != SelectionNone)
19945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We must be a block that has some selected object inside it.  Go ahead and recur.
199502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch            result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
19965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                            lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
19975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
19985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
19995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2001197021e6b966cfb06891637935ef33fff06433d1Ben MurdochIntRect alignSelectionRectToDevicePixels(LayoutRect& rect)
2002197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
2003197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit roundedX = rect.x().round();
2004197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return IntRect(roundedX, rect.y().round(),
2005197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        (rect.maxX() - roundedX).round(),
2006197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        snapSizeToPixel(rect.height(), rect.y()));
2007197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
2008197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
20097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciLayoutRect RenderBlock::blockSelectionGap(const RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
20107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                                          LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo* paintInfo) const
20115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
20125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit logicalTop = lastLogicalTop;
201351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    LayoutUnit logicalHeight = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalBottom - logicalTop;
20145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (logicalHeight <= 0)
20155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return LayoutRect();
20165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Get the selection offsets for the bottom of the gap
2018197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit logicalLeft = std::max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
2019197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit logicalRight = std::min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
20205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit logicalWidth = logicalRight - logicalLeft;
20215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (logicalWidth <= 0)
20225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return LayoutRect();
20235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
20255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (paintInfo)
2026197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        paintInfo->context->fillRect(alignSelectionRectToDevicePixels(gapRect), selectionBackgroundColor());
20275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return gapRect;
20285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciLayoutRect RenderBlock::logicalLeftSelectionGap(const RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
20317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                                                const RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo) const
20325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
203351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    LayoutUnit rootBlockLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalTop;
2034197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit rootBlockLogicalLeft = std::max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
2035197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit rootBlockLogicalRight = std::min(rootBlock->inlineDirectionOffset(offsetFromRootBlock) + logicalLeft, std::min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
20365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
20375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (rootBlockLogicalWidth <= 0)
20385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return LayoutRect();
20395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
20415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (paintInfo)
2042197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        paintInfo->context->fillRect(alignSelectionRectToDevicePixels(gapRect), selObj->selectionBackgroundColor());
20435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return gapRect;
20445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciLayoutRect RenderBlock::logicalRightSelectionGap(const RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
20477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                                                 const RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo) const
20485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
204951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    LayoutUnit rootBlockLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalTop;
2050197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit rootBlockLogicalLeft = std::max(rootBlock->inlineDirectionOffset(offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
2051197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    LayoutUnit rootBlockLogicalRight = std::min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
20525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
20535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (rootBlockLogicalWidth <= 0)
20545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return LayoutRect();
20555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
20575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (paintInfo)
2058197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        paintInfo->context->fillRect(alignSelectionRectToDevicePixels(gapRect), selObj->selectionBackgroundColor());
20595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return gapRect;
20605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap) const
20635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
20645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool ltr = style()->isLeftToRightDirection();
20655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    leftGap = (state == RenderObject::SelectionInside) ||
20665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)              (state == RenderObject::SelectionEnd && ltr) ||
20675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)              (state == RenderObject::SelectionStart && !ltr);
20685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    rightGap = (state == RenderObject::SelectionInside) ||
20695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)               (state == RenderObject::SelectionStart && ltr) ||
20705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)               (state == RenderObject::SelectionEnd && !ltr);
20715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciLayoutUnit RenderBlock::logicalLeftSelectionOffset(const RenderBlock* rootBlock, LayoutUnit position) const
20745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
207509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // The border can potentially be further extended by our containingBlock().
207609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (rootBlock != this)
207709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
207809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return logicalLeftOffsetForContent();
20795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciLayoutUnit RenderBlock::logicalRightSelectionOffset(const RenderBlock* rootBlock, LayoutUnit position) const
20825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
208309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // The border can potentially be further extended by our containingBlock().
208409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (rootBlock != this)
208509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
208609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return logicalRightOffsetForContent();
20875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
20905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
20915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isSelectionRoot())
20925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
20935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const RenderObject* object = this;
20955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* sibling;
20965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    do {
20975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        sibling = object->previousSibling();
20985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (sibling && (!sibling->isRenderBlock() || toRenderBlock(sibling)->isSelectionRoot()))
20995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            sibling = sibling->previousSibling();
21005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
21015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        offset -= LayoutSize(toRenderBlock(object)->logicalLeft(), toRenderBlock(object)->logicalTop());
21025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        object = object->parent();
2103