REGRESSION (r155854 - r155967) block with margin-left adjacent to floated block cause...
[WebKit-https.git] / Source / WebCore / rendering / RenderBlock.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2007 David Smith (catfish.man@gmail.com)
5  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include "config.h"
25 #include "RenderBlock.h"
26
27 #include "AXObjectCache.h"
28 #include "ColumnInfo.h"
29 #include "Document.h"
30 #include "Editor.h"
31 #include "Element.h"
32 #include "FloatQuad.h"
33 #include "Frame.h"
34 #include "FrameSelection.h"
35 #include "FrameView.h"
36 #include "GraphicsContext.h"
37 #include "HTMLInputElement.h"
38 #include "HTMLNames.h"
39 #include "HitTestLocation.h"
40 #include "HitTestResult.h"
41 #include "InlineIterator.h"
42 #include "InlineTextBox.h"
43 #include "LayoutRepainter.h"
44 #include "LogicalSelectionOffsetCaches.h"
45 #include "OverflowEvent.h"
46 #include "Page.h"
47 #include "PaintInfo.h"
48 #include "RenderBoxRegionInfo.h"
49 #include "RenderCombineText.h"
50 #include "RenderDeprecatedFlexibleBox.h"
51 #include "RenderFlexibleBox.h"
52 #include "RenderInline.h"
53 #include "RenderLayer.h"
54 #include "RenderMarquee.h"
55 #include "RenderNamedFlowThread.h"
56 #include "RenderRegion.h"
57 #include "RenderTableCell.h"
58 #include "RenderTextFragment.h"
59 #include "RenderTheme.h"
60 #include "RenderView.h"
61 #include "SVGTextRunRenderingContext.h"
62 #include "Settings.h"
63 #include "ShadowRoot.h"
64 #include "TransformState.h"
65 #include <wtf/StackStats.h>
66 #include <wtf/TemporaryChange.h>
67
68 #if ENABLE(CSS_SHAPES)
69 #include "ShapeInsideInfo.h"
70 #include "ShapeOutsideInfo.h"
71 #endif
72
73 #if ENABLE(IOS_TEXT_AUTOSIZING)
74 #include "HTMLElement.h"
75 #endif
76
77 using namespace std;
78 using namespace WTF;
79 using namespace Unicode;
80
81 namespace WebCore {
82
83 using namespace HTMLNames;
84
85 struct SameSizeAsRenderBlock : public RenderBox {
86     void* pointers[2];
87     RenderObjectChildList children;
88     RenderLineBoxList lineBoxes;
89     uint32_t bitfields;
90 };
91
92 COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock_should_stay_small);
93
94 typedef WTF::HashMap<const RenderBox*, OwnPtr<ColumnInfo> > ColumnInfoMap;
95 static ColumnInfoMap* gColumnInfoMap = 0;
96
97 static TrackedDescendantsMap* gPositionedDescendantsMap = 0;
98 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0;
99
100 static TrackedContainerMap* gPositionedContainerMap = 0;
101 static TrackedContainerMap* gPercentHeightContainerMap = 0;
102     
103 typedef WTF::HashMap<RenderBlock*, OwnPtr<ListHashSet<RenderInline*> > > ContinuationOutlineTableMap;
104
105 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
106 static int gDelayUpdateScrollInfo = 0;
107 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
108
109 static bool gColumnFlowSplitEnabled = true;
110
111 bool RenderBlock::s_canPropagateFloatIntoSibling = false;
112
113 // This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code
114 // only works on RenderBlocks. If this change, this class should be shared with other RenderBoxes.
115 class OverflowEventDispatcher {
116     WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher);
117 public:
118     OverflowEventDispatcher(const RenderBlock* block)
119         : m_block(block)
120         , m_hadHorizontalLayoutOverflow(false)
121         , m_hadVerticalLayoutOverflow(false)
122     {
123         m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowClip() && m_block->document().hasListenerType(Document::OVERFLOWCHANGED_LISTENER);
124         if (m_shouldDispatchEvent) {
125             m_hadHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
126             m_hadVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
127         }
128     }
129
130     ~OverflowEventDispatcher()
131     {
132         if (!m_shouldDispatchEvent)
133             return;
134
135         bool hasHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
136         bool hasVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
137
138         bool horizontalLayoutOverflowChanged = hasHorizontalLayoutOverflow != m_hadHorizontalLayoutOverflow;
139         bool verticalLayoutOverflowChanged = hasVerticalLayoutOverflow != m_hadVerticalLayoutOverflow;
140         if (horizontalLayoutOverflowChanged || verticalLayoutOverflowChanged)
141             m_block->view().frameView().scheduleEvent(OverflowEvent::create(horizontalLayoutOverflowChanged, hasHorizontalLayoutOverflow, verticalLayoutOverflowChanged, hasVerticalLayoutOverflow), m_block->element());
142     }
143
144 private:
145     const RenderBlock* m_block;
146     bool m_shouldDispatchEvent;
147     bool m_hadHorizontalLayoutOverflow;
148     bool m_hadVerticalLayoutOverflow;
149 };
150
151 // -------------------------------------------------------------------------------------------------------
152
153 RenderBlock::RenderBlock(Element* element)
154     : RenderBox(element)
155     , m_lineHeight(-1)
156     , m_hasMarginBeforeQuirk(false)
157     , m_hasMarginAfterQuirk(false)
158     , m_beingDestroyed(false)
159     , m_hasMarkupTruncation(false)
160     , m_hasBorderOrPaddingLogicalWidthChanged(false)
161 #if ENABLE(IOS_TEXT_AUTOSIZING)
162     , m_widthForTextAutosizing(-1)
163     , m_lineCountForTextAutosizing(NOT_SET)
164 #endif
165 {
166     setChildrenInline(true);
167 }
168
169 static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
170 {
171     if (OwnPtr<TrackedRendererListHashSet> descendantSet = descendantMap->take(block)) {
172         TrackedRendererListHashSet::iterator end = descendantSet->end();
173         for (TrackedRendererListHashSet::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
174             TrackedContainerMap::iterator it = containerMap->find(*descendant);
175             ASSERT(it != containerMap->end());
176             if (it == containerMap->end())
177                 continue;
178             HashSet<RenderBlock*>* containerSet = it->value.get();
179             ASSERT(containerSet->contains(block));
180             containerSet->remove(block);
181             if (containerSet->isEmpty())
182                 containerMap->remove(it);
183         }
184     }
185 }
186
187 RenderBlock::~RenderBlock()
188 {
189     if (hasColumns())
190         gColumnInfoMap->take(this);
191     if (gPercentHeightDescendantsMap)
192         removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
193     if (gPositionedDescendantsMap)
194         removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap);
195 }
196
197 RenderBlock* RenderBlock::createAnonymous(Document& document)
198 {
199     RenderBlock* renderer = new (*document.renderArena()) RenderBlockFlow(0);
200     renderer->setDocumentForAnonymous(document);
201     return renderer;
202 }
203
204 void RenderBlock::willBeDestroyed()
205 {
206     // Mark as being destroyed to avoid trouble with merges in removeChild().
207     m_beingDestroyed = true;
208
209     if (!documentBeingDestroyed()) {
210         if (firstChild() && firstChild()->isRunIn())
211             moveRunInToOriginalPosition(firstChild());
212     }
213
214     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
215     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
216     children()->destroyLeftoverChildren();
217
218     // Destroy our continuation before anything other than anonymous children.
219     // The reason we don't destroy it before anonymous children is that they may
220     // have continuations of their own that are anonymous children of our continuation.
221     RenderBoxModelObject* continuation = this->continuation();
222     if (continuation) {
223         continuation->destroy();
224         setContinuation(0);
225     }
226     
227     if (!documentBeingDestroyed()) {
228         if (firstLineBox()) {
229             // We can't wait for RenderBox::destroy to clear the selection,
230             // because by then we will have nuked the line boxes.
231             // FIXME: The FrameSelection should be responsible for this when it
232             // is notified of DOM mutations.
233             if (isSelectionBorder())
234                 view().clearSelection();
235
236             // If we are an anonymous block, then our line boxes might have children
237             // that will outlast this block. In the non-anonymous block case those
238             // children will be destroyed by the time we return from this function.
239             if (isAnonymousBlock()) {
240                 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
241                     while (InlineBox* childBox = box->firstChild())
242                         childBox->remove();
243                 }
244             }
245         } else if (parent())
246             parent()->dirtyLinesFromChangedChild(this);
247     }
248
249     m_lineBoxes.deleteLineBoxes(renderArena());
250
251     if (lineGridBox())
252         lineGridBox()->destroy(renderArena());
253
254     if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0))
255         gDelayedUpdateScrollInfoSet->remove(this);
256
257     RenderBox::willBeDestroyed();
258 }
259
260 void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
261 {
262     RenderStyle* oldStyle = style();
263     s_canPropagateFloatIntoSibling = oldStyle ? !isFloatingOrOutOfFlowPositioned() && !avoidsFloats() : false;
264
265     setReplaced(newStyle->isDisplayInlineType());
266     
267     if (oldStyle && parent() && diff == StyleDifferenceLayout && oldStyle->position() != newStyle->position()) {
268         if (newStyle->position() == StaticPosition)
269             // Clear our positioned objects list. Our absolutely positioned descendants will be
270             // inserted into our containing block's positioned objects list during layout.
271             removePositionedObjects(0, NewContainingBlock);
272         else if (oldStyle->position() == StaticPosition) {
273             // Remove our absolutely positioned descendants from their current containing block.
274             // They will be inserted into our positioned objects list during layout.
275             RenderObject* cb = parent();
276             while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
277                 if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
278                     cb = cb->containingBlock();
279                     break;
280                 }
281                 cb = cb->parent();
282             }
283             
284             if (cb->isRenderBlock())
285                 toRenderBlock(cb)->removePositionedObjects(this, NewContainingBlock);
286         }
287
288         if (containsFloats() && !isFloating() && !isOutOfFlowPositioned() && newStyle->hasOutOfFlowPosition())
289             markAllDescendantsWithFloatsForLayout();
290     }
291
292     RenderBox::styleWillChange(diff, newStyle);
293 }
294
295 static bool borderOrPaddingLogicalWidthChanged(const RenderStyle* oldStyle, const RenderStyle* newStyle)
296 {
297     if (newStyle->isHorizontalWritingMode())
298         return oldStyle->borderLeftWidth() != newStyle->borderLeftWidth()
299             || oldStyle->borderRightWidth() != newStyle->borderRightWidth()
300             || oldStyle->paddingLeft() != newStyle->paddingLeft()
301             || oldStyle->paddingRight() != newStyle->paddingRight();
302
303     return oldStyle->borderTopWidth() != newStyle->borderTopWidth()
304         || oldStyle->borderBottomWidth() != newStyle->borderBottomWidth()
305         || oldStyle->paddingTop() != newStyle->paddingTop()
306         || oldStyle->paddingBottom() != newStyle->paddingBottom();
307 }
308
309 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
310 {
311     RenderBox::styleDidChange(diff, oldStyle);
312     
313     RenderStyle* newStyle = style();
314     
315 #if ENABLE(CSS_SHAPES)
316     updateShapeInsideInfoAfterStyleChange(newStyle->resolvedShapeInside(), oldStyle ? oldStyle->resolvedShapeInside() : 0);
317 #endif
318
319     if (!isAnonymousBlock()) {
320         // Ensure that all of our continuation blocks pick up the new style.
321         for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
322             RenderBoxModelObject* nextCont = currCont->continuation();
323             currCont->setContinuation(0);
324             currCont->setStyle(newStyle);
325             currCont->setContinuation(nextCont);
326         }
327     }
328
329     propagateStyleToAnonymousChildren(true);    
330     m_lineHeight = -1;
331
332     // After our style changed, if we lose our ability to propagate floats into next sibling
333     // blocks, then we need to find the top most parent containing that overhanging float and
334     // then mark its descendants with floats for layout and clear all floats from its next
335     // sibling blocks that exist in our floating objects list. See bug 56299 and 62875.
336     bool canPropagateFloatIntoSibling = !isFloatingOrOutOfFlowPositioned() && !avoidsFloats();
337     if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) {
338         RenderBlock* parentBlock = this;
339         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
340         FloatingObjectSetIterator end = floatingObjectSet.end();
341
342         for (RenderObject* curr = parent(); curr && !curr->isRenderView(); curr = curr->parent()) {
343             if (curr->isRenderBlock()) {
344                 RenderBlock* currBlock = toRenderBlock(curr);
345
346                 if (currBlock->hasOverhangingFloats()) {
347                     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
348                         RenderBox* renderer = (*it)->renderer();
349                         if (currBlock->hasOverhangingFloat(renderer)) {
350                             parentBlock = currBlock;
351                             break;
352                         }
353                     }
354                 }
355             }
356         }
357               
358         parentBlock->markAllDescendantsWithFloatsForLayout();
359         parentBlock->markSiblingsWithFloatsForLayout();
360     }
361     
362     // It's possible for our border/padding to change, but for the overall logical width of the block to
363     // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
364     m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff == StyleDifferenceLayout && needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, newStyle);
365 }
366
367 RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
368 {
369     if (beforeChild && beforeChild->parent() == this)
370         return this;
371
372     RenderBlock* curr = toRenderBlock(continuation());
373     RenderBlock* nextToLast = this;
374     RenderBlock* last = this;
375     while (curr) {
376         if (beforeChild && beforeChild->parent() == curr) {
377             if (curr->firstChild() == beforeChild)
378                 return last;
379             return curr;
380         }
381
382         nextToLast = last;
383         last = curr;
384         curr = toRenderBlock(curr->continuation());
385     }
386
387     if (!beforeChild && !last->firstChild())
388         return nextToLast;
389     return last;
390 }
391
392 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
393 {
394     RenderBlock* flow = continuationBefore(beforeChild);
395     ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
396     RenderBoxModelObject* beforeChildParent = 0;
397     if (beforeChild)
398         beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
399     else {
400         RenderBoxModelObject* cont = flow->continuation();
401         if (cont)
402             beforeChildParent = cont;
403         else
404             beforeChildParent = flow;
405     }
406
407     if (newChild->isFloatingOrOutOfFlowPositioned()) {
408         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
409         return;
410     }
411
412     // A continuation always consists of two potential candidates: a block or an anonymous
413     // column span box holding column span children.
414     bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
415     bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
416     bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
417
418     if (flow == beforeChildParent) {
419         flow->addChildIgnoringContinuation(newChild, beforeChild);
420         return;
421     }
422     
423     // The goal here is to match up if we can, so that we can coalesce and create the
424     // minimal # of continuations needed for the inline.
425     if (childIsNormal == bcpIsNormal) {
426         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
427         return;
428     }
429     if (flowIsNormal == childIsNormal) {
430         flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
431         return;
432     }
433     beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
434 }
435
436
437 void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
438 {
439     ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
440         
441     // The goal is to locate a suitable box in which to place our child.
442     RenderBlock* beforeChildParent = 0;
443     if (beforeChild) {
444         RenderObject* curr = beforeChild;
445         while (curr && curr->parent() != this)
446             curr = curr->parent();
447         beforeChildParent = toRenderBlock(curr);
448         ASSERT(beforeChildParent);
449         ASSERT(beforeChildParent->isAnonymousColumnsBlock() || beforeChildParent->isAnonymousColumnSpanBlock());
450     } else
451         beforeChildParent = toRenderBlock(lastChild());
452
453     // If the new child is floating or positioned it can just go in that block.
454     if (newChild->isFloatingOrOutOfFlowPositioned()) {
455         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
456         return;
457     }
458
459     // See if the child can be placed in the box.
460     bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline();
461     bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
462
463     if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) {
464         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
465         return;
466     }
467
468     if (!beforeChild) {
469         // Create a new block of the correct type.
470         RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
471         children()->appendChildNode(this, newBox);
472         newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
473         return;
474     }
475
476     RenderObject* immediateChild = beforeChild;
477     bool isPreviousBlockViable = true;
478     while (immediateChild->parent() != this) {
479         if (isPreviousBlockViable)
480             isPreviousBlockViable = !immediateChild->previousSibling();
481         immediateChild = immediateChild->parent();
482     }
483     if (isPreviousBlockViable && immediateChild->previousSibling()) {
484         toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
485         return;
486     }
487         
488     // Split our anonymous blocks.
489     RenderObject* newBeforeChild = splitAnonymousBoxesAroundChild(beforeChild);
490
491     
492     // Create a new anonymous box of the appropriate type.
493     RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
494     children()->insertChildNode(this, newBox, newBeforeChild);
495     newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
496     return;
497 }
498
499 RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
500 {
501     RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
502     for (RenderObject* curr = this; curr; curr = curr->parent()) {
503         if (!curr->isRenderBlock() || curr->isFloatingOrOutOfFlowPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
504             || curr->isInlineBlockOrInlineTable())
505             return 0;
506
507         // FIXME: Tables, RenderButtons, and RenderListItems all do special management
508         // of their children that breaks when the flow is split through them. Disabling
509         // multi-column for them to avoid this problem.
510         if (curr->isTable() || curr->isRenderButton() || curr->isListItem())
511             return 0;
512         
513         RenderBlock* currBlock = toRenderBlock(curr);
514         if (!currBlock->createsAnonymousWrapper())
515             firstChildIgnoringAnonymousWrappers = currBlock;
516
517         if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
518             return firstChildIgnoringAnonymousWrappers;
519             
520         if (currBlock->isAnonymousColumnSpanBlock())
521             return 0;
522     }
523     return 0;
524 }
525
526 RenderBlock* RenderBlock::clone() const
527 {
528     RenderBlock* cloneBlock;
529     if (isAnonymousBlock()) {
530         cloneBlock = createAnonymousBlock();
531         cloneBlock->setChildrenInline(childrenInline());
532     } else {
533         RenderObject* cloneRenderer = element()->createRenderer(renderArena(), *style());
534         cloneBlock = toRenderBlock(cloneRenderer);
535         cloneBlock->setStyle(style());
536
537         // This takes care of setting the right value of childrenInline in case
538         // generated content is added to cloneBlock and 'this' does not have
539         // generated content added yet.
540         cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->firstChild()->isInline() : childrenInline());
541     }
542     cloneBlock->setFlowThreadState(flowThreadState());
543     return cloneBlock;
544 }
545
546 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
547                               RenderBlock* middleBlock,
548                               RenderObject* beforeChild, RenderBoxModelObject* oldCont)
549 {
550     // Create a clone of this inline.
551     RenderBlock* cloneBlock = clone();
552     if (!isAnonymousBlock())
553         cloneBlock->setContinuation(oldCont);
554
555     if (!beforeChild && isAfterContent(lastChild()))
556         beforeChild = lastChild();
557
558     // If we are moving inline children from |this| to cloneBlock, then we need
559     // to clear our line box tree.
560     if (beforeChild && childrenInline())
561         deleteLineBoxTree();
562
563     // Now take all of the children from beforeChild to the end and remove
564     // them from |this| and place them in the clone.
565     moveChildrenTo(cloneBlock, beforeChild, 0, true);
566     
567     // Hook |clone| up as the continuation of the middle block.
568     if (!cloneBlock->isAnonymousBlock())
569         middleBlock->setContinuation(cloneBlock);
570
571     // We have been reparented and are now under the fromBlock.  We need
572     // to walk up our block parent chain until we hit the containing anonymous columns block.
573     // Once we hit the anonymous columns block we're done.
574     RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
575     RenderBoxModelObject* currChild = this;
576     RenderObject* currChildNextSibling = currChild->nextSibling();
577
578     while (curr && curr != fromBlock) {
579         ASSERT_WITH_SECURITY_IMPLICATION(curr->isRenderBlock());
580         
581         RenderBlock* blockCurr = toRenderBlock(curr);
582         
583         // Create a new clone.
584         RenderBlock* cloneChild = cloneBlock;
585         cloneBlock = blockCurr->clone();
586
587         // Insert our child clone as the first child.
588         cloneBlock->addChildIgnoringContinuation(cloneChild, 0);
589
590         // Hook the clone up as a continuation of |curr|.  Note we do encounter
591         // anonymous blocks possibly as we walk up the block chain.  When we split an
592         // anonymous block, there's no need to do any continuation hookup, since we haven't
593         // actually split a real element.
594         if (!blockCurr->isAnonymousBlock()) {
595             oldCont = blockCurr->continuation();
596             blockCurr->setContinuation(cloneBlock);
597             cloneBlock->setContinuation(oldCont);
598         }
599
600         // Now we need to take all of the children starting from the first child
601         // *after* currChild and append them all to the clone.
602         blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true);
603
604         // Keep walking up the chain.
605         currChild = curr;
606         currChildNextSibling = currChild->nextSibling();
607         curr = toRenderBoxModelObject(curr->parent());
608     }
609
610     // Now we are at the columns block level. We need to put the clone into the toBlock.
611     toBlock->children()->appendChildNode(toBlock, cloneBlock);
612
613     // Now take all the children after currChild and remove them from the fromBlock
614     // and put them in the toBlock.
615     fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true);
616 }
617
618 void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
619                             RenderObject* newChild, RenderBoxModelObject* oldCont)
620 {
621     RenderBlock* pre = 0;
622     RenderBlock* block = containingColumnsBlock();
623     
624     // Delete our line boxes before we do the inline split into continuations.
625     block->deleteLineBoxTree();
626     
627     bool madeNewBeforeBlock = false;
628     if (block->isAnonymousColumnsBlock()) {
629         // We can reuse this block and make it the preBlock of the next continuation.
630         pre = block;
631         pre->removePositionedObjects(0);
632         pre->removeFloatingObjects();
633         block = toRenderBlock(block->parent());
634     } else {
635         // No anonymous block available for use.  Make one.
636         pre = block->createAnonymousColumnsBlock();
637         pre->setChildrenInline(false);
638         madeNewBeforeBlock = true;
639     }
640
641     RenderBlock* post = block->createAnonymousColumnsBlock();
642     post->setChildrenInline(false);
643
644     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
645     if (madeNewBeforeBlock)
646         block->children()->insertChildNode(block, pre, boxFirst);
647     block->children()->insertChildNode(block, newBlockBox, boxFirst);
648     block->children()->insertChildNode(block, post, boxFirst);
649     block->setChildrenInline(false);
650     
651     if (madeNewBeforeBlock)
652         block->moveChildrenTo(pre, boxFirst, 0, true);
653
654     splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
655
656     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
657     // time in makeChildrenNonInline by just setting this explicitly up front.
658     newBlockBox->setChildrenInline(false);
659
660     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
661     // connected, thus allowing newChild access to a renderArena should it need
662     // to wrap itself in additional boxes (e.g., table construction).
663     newBlockBox->addChild(newChild);
664
665     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
666     // get deleted properly.  Because objects moves from the pre block into the post block, we want to
667     // make new line boxes instead of leaving the old line boxes around.
668     pre->setNeedsLayoutAndPrefWidthsRecalc();
669     block->setNeedsLayoutAndPrefWidthsRecalc();
670     post->setNeedsLayoutAndPrefWidthsRecalc();
671 }
672
673 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
674 {
675     RenderBlock* pre = 0;
676     RenderBlock* post = 0;
677     RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
678                                // so that we don't have to patch all of the rest of the code later on.
679     
680     // Delete the block's line boxes before we do the split.
681     block->deleteLineBoxTree();
682
683     if (beforeChild && beforeChild->parent() != this)
684         beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
685
686     if (beforeChild != firstChild()) {
687         pre = block->createAnonymousColumnsBlock();
688         pre->setChildrenInline(block->childrenInline());
689     }
690
691     if (beforeChild) {
692         post = block->createAnonymousColumnsBlock();
693         post->setChildrenInline(block->childrenInline());
694     }
695
696     RenderObject* boxFirst = block->firstChild();
697     if (pre)
698         block->children()->insertChildNode(block, pre, boxFirst);
699     block->children()->insertChildNode(block, newBlockBox, boxFirst);
700     if (post)
701         block->children()->insertChildNode(block, post, boxFirst);
702     block->setChildrenInline(false);
703     
704     // 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).
705     block->moveChildrenTo(pre, boxFirst, beforeChild, true);
706     block->moveChildrenTo(post, beforeChild, 0, true);
707
708     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
709     // time in makeChildrenNonInline by just setting this explicitly up front.
710     newBlockBox->setChildrenInline(false);
711
712     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
713     // connected, thus allowing newChild access to a renderArena should it need
714     // to wrap itself in additional boxes (e.g., table construction).
715     newBlockBox->addChild(newChild);
716
717     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
718     // get deleted properly.  Because objects moved from the pre block into the post block, we want to
719     // make new line boxes instead of leaving the old line boxes around.
720     if (pre)
721         pre->setNeedsLayoutAndPrefWidthsRecalc();
722     block->setNeedsLayoutAndPrefWidthsRecalc();
723     if (post)
724         post->setNeedsLayoutAndPrefWidthsRecalc();
725 }
726
727 RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
728 {
729     // FIXME: This function is the gateway for the addition of column-span support.  It will
730     // be added to in three stages:
731     // (1) Immediate children of a multi-column block can span.
732     // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
733     // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
734     // cross the streams and have to cope with both types of continuations mixed together).
735     // This function currently supports (1) and (2).
736     RenderBlock* columnsBlockAncestor = 0;
737     if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
738         && !newChild->isFloatingOrOutOfFlowPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
739         columnsBlockAncestor = containingColumnsBlock(false);
740         if (columnsBlockAncestor) {
741             // Make sure that none of the parent ancestors have a continuation.
742             // If yes, we do not want split the block into continuations.
743             RenderObject* curr = this;
744             while (curr && curr != columnsBlockAncestor) {
745                 if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
746                     columnsBlockAncestor = 0;
747                     break;
748                 }
749                 curr = curr->parent();
750             }
751         }
752     }
753     return columnsBlockAncestor;
754 }
755
756 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
757 {
758     if (beforeChild && beforeChild->parent() != this) {
759         RenderObject* beforeChildContainer = beforeChild->parent();
760         while (beforeChildContainer->parent() != this)
761             beforeChildContainer = beforeChildContainer->parent();
762         ASSERT(beforeChildContainer);
763
764         if (beforeChildContainer->isAnonymous()) {
765             // If the requested beforeChild is not one of our children, then this is because
766             // there is an anonymous container within this object that contains the beforeChild.
767             RenderObject* beforeChildAnonymousContainer = beforeChildContainer;
768             if (beforeChildAnonymousContainer->isAnonymousBlock()
769 #if ENABLE(FULLSCREEN_API)
770                 // Full screen renderers and full screen placeholders act as anonymous blocks, not tables:
771                 || beforeChildAnonymousContainer->isRenderFullScreen()
772                 || beforeChildAnonymousContainer->isRenderFullScreenPlaceholder()
773 #endif
774                 ) {
775                 // Insert the child into the anonymous block box instead of here.
776                 if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
777                     beforeChild->parent()->addChild(newChild, beforeChild);
778                 else
779                     addChild(newChild, beforeChild->parent());
780                 return;
781             }
782
783             ASSERT(beforeChildAnonymousContainer->isTable());
784             if (newChild->isTablePart()) {
785                 // Insert into the anonymous table.
786                 beforeChildAnonymousContainer->addChild(newChild, beforeChild);
787                 return;
788             }
789
790             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
791
792             ASSERT(beforeChild->parent() == this);
793             if (beforeChild->parent() != this) {
794                 // We should never reach here. If we do, we need to use the
795                 // safe fallback to use the topmost beforeChild container.
796                 beforeChild = beforeChildContainer;
797             }
798         } else {
799             // We will reach here when beforeChild is a run-in element.
800             // If run-in element precedes a block-level element, it becomes the
801             // the first inline child of that block level element. The insertion
802             // point will be before that block-level element.
803             ASSERT(beforeChild->isRunIn());
804             beforeChild = beforeChildContainer;
805         }
806     }
807
808     // Nothing goes before the intruded run-in.
809     if (beforeChild && beforeChild->isRunIn() && runInIsPlacedIntoSiblingBlock(beforeChild))
810         beforeChild = beforeChild->nextSibling();
811
812     // Check for a spanning element in columns.
813     if (gColumnFlowSplitEnabled) {
814         RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
815         if (columnsBlockAncestor) {
816             TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
817             // We are placing a column-span element inside a block.
818             RenderBlock* newBox = createAnonymousColumnSpanBlock();
819         
820             if (columnsBlockAncestor != this && !isRenderFlowThread()) {
821                 // We are nested inside a multi-column element and are being split by the span. We have to break up
822                 // our block into continuations.
823                 RenderBoxModelObject* oldContinuation = continuation();
824
825                 // When we split an anonymous block, there's no need to do any continuation hookup,
826                 // since we haven't actually split a real element.
827                 if (!isAnonymousBlock())
828                     setContinuation(newBox);
829
830                 splitFlow(beforeChild, newBox, newChild, oldContinuation);
831                 return;
832             }
833
834             // We have to perform a split of this block's children. This involves creating an anonymous block box to hold
835             // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
836             // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
837             makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
838             return;
839         }
840     }
841
842     bool madeBoxesNonInline = false;
843
844     // A block has to either have all of its children inline, or all of its children as blocks.
845     // So, if our children are currently inline and a block child has to be inserted, we move all our
846     // inline children into anonymous block boxes.
847     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned()) {
848         // This is a block with inline content. Wrap the inline content in anonymous blocks.
849         makeChildrenNonInline(beforeChild);
850         madeBoxesNonInline = true;
851
852         if (beforeChild && beforeChild->parent() != this) {
853             beforeChild = beforeChild->parent();
854             ASSERT(beforeChild->isAnonymousBlock());
855             ASSERT(beforeChild->parent() == this);
856         }
857     } else if (!childrenInline() && (newChild->isFloatingOrOutOfFlowPositioned() || newChild->isInline())) {
858         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
859         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
860         // a new one is created and inserted into our list of children in the appropriate position.
861         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
862
863         if (afterChild && afterChild->isAnonymousBlock()) {
864             afterChild->addChild(newChild);
865             return;
866         }
867
868         if (newChild->isInline()) {
869             // No suitable existing anonymous box - create a new one.
870             RenderBlock* newBox = createAnonymousBlock();
871             RenderBox::addChild(newBox, beforeChild);
872             newBox->addChild(newChild);
873             return;
874         }
875     }
876
877     RenderBox::addChild(newChild, beforeChild);
878  
879     // Handle placement of run-ins.
880     placeRunInIfNeeded(newChild);
881
882     if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
883         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
884     // this object may be dead here
885 }
886
887 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
888 {
889     if (continuation() && !isAnonymousBlock())
890         addChildToContinuation(newChild, beforeChild);
891     else
892         addChildIgnoringContinuation(newChild, beforeChild);
893 }
894
895 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
896 {
897     if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
898         addChildToAnonymousColumnBlocks(newChild, beforeChild);
899     else
900         addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
901 }
902
903 static void getInlineRun(RenderObject* start, RenderObject* boundary,
904                          RenderObject*& inlineRunStart,
905                          RenderObject*& inlineRunEnd)
906 {
907     // Beginning at |start| we find the largest contiguous run of inlines that
908     // we can.  We denote the run with start and end points, |inlineRunStart|
909     // and |inlineRunEnd|.  Note that these two values may be the same if
910     // we encounter only one inline.
911     //
912     // We skip any non-inlines we encounter as long as we haven't found any
913     // inlines yet.
914     //
915     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
916     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
917     // a non-inline.
918     
919     // Start by skipping as many non-inlines as we can.
920     RenderObject * curr = start;
921     bool sawInline;
922     do {
923         while (curr && !(curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()))
924             curr = curr->nextSibling();
925         
926         inlineRunStart = inlineRunEnd = curr;
927         
928         if (!curr)
929             return; // No more inline children to be found.
930         
931         sawInline = curr->isInline();
932         
933         curr = curr->nextSibling();
934         while (curr && (curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()) && (curr != boundary)) {
935             inlineRunEnd = curr;
936             if (curr->isInline())
937                 sawInline = true;
938             curr = curr->nextSibling();
939         }
940     } while (!sawInline);
941 }
942
943 void RenderBlock::deleteLineBoxTree()
944 {
945     if (containsFloats())
946         m_floatingObjects->clearLineBoxTreePointers();
947     m_lineBoxes.deleteLineBoxTree(renderArena());
948
949     if (AXObjectCache* cache = document().existingAXObjectCache())
950         cache->recomputeIsIgnored(this);
951 }
952
953 RootInlineBox* RenderBlock::createRootInlineBox()
954 {
955     return new (renderArena()) RootInlineBox(*this);
956 }
957
958 RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
959 {
960     RootInlineBox* rootBox = createRootInlineBox();
961     m_lineBoxes.appendLineBox(rootBox);
962
963     if (UNLIKELY(AXObjectCache::accessibilityEnabled()) && m_lineBoxes.firstLineBox() == rootBox) {
964         if (AXObjectCache* cache = document().existingAXObjectCache())
965             cache->recomputeIsIgnored(this);
966     }
967
968     return rootBox;
969 }
970
971 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
972 {    
973     // makeChildrenNonInline takes a block whose children are *all* inline and it
974     // makes sure that inline children are coalesced under anonymous
975     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
976     // the new block child that is causing us to have to wrap all the inlines.  This
977     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
978     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
979     // splitting them.
980     ASSERT(isInlineBlockOrInlineTable() || !isInline());
981     ASSERT(!insertionPoint || insertionPoint->parent() == this);
982
983     setChildrenInline(false);
984
985     RenderObject *child = firstChild();
986     if (!child)
987         return;
988
989     deleteLineBoxTree();
990
991     // Since we are going to have block children, we have to move
992     // back the run-in to its original place.
993     if (child->isRunIn()) {
994         moveRunInToOriginalPosition(child);
995         child = firstChild();
996     }
997
998     while (child) {
999         RenderObject *inlineRunStart, *inlineRunEnd;
1000         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
1001
1002         if (!inlineRunStart)
1003             break;
1004
1005         child = inlineRunEnd->nextSibling();
1006
1007         RenderBlock* block = createAnonymousBlock();
1008         children()->insertChildNode(this, block, inlineRunStart);
1009         moveChildrenTo(block, inlineRunStart, child);
1010     }
1011
1012 #ifndef NDEBUG
1013     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
1014         ASSERT(!c->isInline());
1015 #endif
1016
1017     repaint();
1018 }
1019
1020 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
1021 {
1022     ASSERT(child->isAnonymousBlock());
1023     ASSERT(!child->childrenInline());
1024     
1025     if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
1026         return;
1027     
1028     RenderObject* firstAnChild = child->m_children.firstChild();
1029     RenderObject* lastAnChild = child->m_children.lastChild();
1030     if (firstAnChild) {
1031         RenderObject* o = firstAnChild;
1032         while (o) {
1033             o->setParent(this);
1034             o = o->nextSibling();
1035         }
1036         firstAnChild->setPreviousSibling(child->previousSibling());
1037         lastAnChild->setNextSibling(child->nextSibling());
1038         if (child->previousSibling())
1039             child->previousSibling()->setNextSibling(firstAnChild);
1040         if (child->nextSibling())
1041             child->nextSibling()->setPreviousSibling(lastAnChild);
1042             
1043         if (child == m_children.firstChild())
1044             m_children.setFirstChild(firstAnChild);
1045         if (child == m_children.lastChild())
1046             m_children.setLastChild(lastAnChild);
1047     } else {
1048         if (child == m_children.firstChild())
1049             m_children.setFirstChild(child->nextSibling());
1050         if (child == m_children.lastChild())
1051             m_children.setLastChild(child->previousSibling());
1052
1053         if (child->previousSibling())
1054             child->previousSibling()->setNextSibling(child->nextSibling());
1055         if (child->nextSibling())
1056             child->nextSibling()->setPreviousSibling(child->previousSibling());
1057     }
1058
1059     child->children()->setFirstChild(0);
1060     child->m_next = 0;
1061
1062     // Remove all the information in the flow thread associated with the leftover anonymous block.
1063     child->removeFromRenderFlowThread();
1064
1065     child->setParent(0);
1066     child->setPreviousSibling(0);
1067     child->setNextSibling(0);
1068
1069     child->destroy();
1070 }
1071
1072 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
1073 {
1074     if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
1075         return false;
1076
1077     if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
1078         || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
1079         return false;
1080
1081     // FIXME: This check isn't required when inline run-ins can't be split into continuations.
1082     if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
1083         return false;
1084
1085     if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
1086         || (next && (next->isRubyRun() || next->isRubyBase())))
1087         return false;
1088
1089     if (!prev || !next)
1090         return true;
1091
1092     // Make sure the types of the anonymous blocks match up.
1093     return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
1094            && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
1095 }
1096
1097 void RenderBlock::collapseAnonymousBoxChild(RenderBlock* parent, RenderObject* child)
1098 {
1099     parent->setNeedsLayoutAndPrefWidthsRecalc();
1100     parent->setChildrenInline(child->childrenInline());
1101     RenderObject* nextSibling = child->nextSibling();
1102
1103     RenderFlowThread* childFlowThread = child->flowThreadContainingBlock();
1104     CurrentRenderFlowThreadMaintainer flowThreadMaintainer(childFlowThread);
1105     
1106     RenderBlock* anonBlock = toRenderBlock(parent->children()->removeChildNode(parent, child, child->hasLayer()));
1107     anonBlock->moveAllChildrenTo(parent, nextSibling, child->hasLayer());
1108     // Delete the now-empty block's lines and nuke it.
1109     anonBlock->deleteLineBoxTree();
1110     if (childFlowThread && childFlowThread->isRenderNamedFlowThread())
1111         toRenderNamedFlowThread(childFlowThread)->removeFlowChildInfo(anonBlock);
1112     anonBlock->destroy();
1113 }
1114
1115 void RenderBlock::moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert)
1116 {
1117     moveAllChildrenTo(toBlock, fullRemoveInsert);
1118
1119     // When a portion of the render tree is being detached, anonymous blocks
1120     // will be combined as their children are deleted. In this process, the
1121     // anonymous block later in the tree is merged into the one preceeding it.
1122     // It can happen that the later block (this) contains floats that the
1123     // previous block (toBlock) did not contain, and thus are not in the
1124     // floating objects list for toBlock. This can result in toBlock containing
1125     // floats that are not in it's floating objects list, but are in the
1126     // floating objects lists of siblings and parents. This can cause problems
1127     // when the float itself is deleted, since the deletion code assumes that
1128     // if a float is not in it's containing block's floating objects list, it
1129     // isn't in any floating objects list. In order to preserve this condition
1130     // (removing it has serious performance implications), we need to copy the
1131     // floating objects from the old block (this) to the new block (toBlock).
1132     // The float's metrics will likely all be wrong, but since toBlock is
1133     // already marked for layout, this will get fixed before anything gets
1134     // displayed.
1135     // See bug https://bugs.webkit.org/show_bug.cgi?id=115566
1136     if (m_floatingObjects) {
1137         if (!toBlock->m_floatingObjects)
1138             toBlock->createFloatingObjects();
1139
1140         const FloatingObjectSet& fromFloatingObjectSet = m_floatingObjects->set();
1141         FloatingObjectSetIterator end = fromFloatingObjectSet.end();
1142
1143         for (FloatingObjectSetIterator it = fromFloatingObjectSet.begin(); it != end; ++it) {
1144             FloatingObject* floatingObject = *it;
1145
1146             // Don't insert the object again if it's already in the list
1147             if (toBlock->containsFloat(floatingObject->renderer()))
1148                 continue;
1149
1150             toBlock->m_floatingObjects->add(floatingObject->unsafeClone());
1151         }
1152     }
1153 }
1154
1155 void RenderBlock::removeChild(RenderObject* oldChild)
1156 {
1157     // No need to waste time in merging or removing empty anonymous blocks.
1158     // We can just bail out if our document is getting destroyed.
1159     if (documentBeingDestroyed()) {
1160         RenderBox::removeChild(oldChild);
1161         return;
1162     }
1163
1164     // This protects against column split flows when anonymous blocks are getting merged.
1165     TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
1166
1167     // If this child is a block, and if our previous and next siblings are
1168     // both anonymous blocks with inline content, then we can go ahead and
1169     // fold the inline content back together.
1170     RenderObject* prev = oldChild->previousSibling();
1171     RenderObject* next = oldChild->nextSibling();
1172     bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
1173     if (canMergeAnonymousBlocks && prev && next) {
1174         prev->setNeedsLayoutAndPrefWidthsRecalc();
1175         RenderBlock* nextBlock = toRenderBlock(next);
1176         RenderBlock* prevBlock = toRenderBlock(prev);
1177        
1178         if (prev->childrenInline() != next->childrenInline()) {
1179             RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
1180             RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
1181             
1182             // Place the inline children block inside of the block children block instead of deleting it.
1183             // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
1184             // to clear out inherited column properties by just making a new style, and to also clear the
1185             // column span flag if it is set.
1186             ASSERT(!inlineChildrenBlock->continuation());
1187             RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK);
1188             // Cache this value as it might get changed in setStyle() call.
1189             bool inlineChildrenBlockHasLayer = inlineChildrenBlock->hasLayer();
1190             inlineChildrenBlock->setStyle(newStyle);
1191             children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlockHasLayer);
1192             
1193             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
1194             blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
1195                                                             inlineChildrenBlockHasLayer || blockChildrenBlock->hasLayer());
1196             next->setNeedsLayoutAndPrefWidthsRecalc();
1197             
1198             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
1199             // of "this". we null out prev or next so that is not used later in the function.
1200             if (inlineChildrenBlock == prevBlock)
1201                 prev = 0;
1202             else
1203                 next = 0;
1204         } else {
1205             // Take all the children out of the |next| block and put them in
1206             // the |prev| block.
1207             nextBlock->moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
1208             
1209             // Delete the now-empty block's lines and nuke it.
1210             nextBlock->deleteLineBoxTree();
1211             nextBlock->destroy();
1212             next = 0;
1213         }
1214     }
1215
1216     RenderBox::removeChild(oldChild);
1217
1218     RenderObject* child = prev ? prev : next;
1219     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && canCollapseAnonymousBlockChild()) {
1220         // The removal has knocked us down to containing only a single anonymous
1221         // box.  We can go ahead and pull the content right back up into our
1222         // box.
1223         collapseAnonymousBoxChild(this, child);
1224     } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && canCollapseAnonymousBlockChild()) {
1225         // It's possible that the removal has knocked us down to a single anonymous
1226         // block with pseudo-style element siblings (e.g. first-letter). If these
1227         // are floating, then we need to pull the content up also.
1228         RenderBlock* anonBlock = toRenderBlock((prev && prev->isAnonymousBlock()) ? prev : next);
1229         if ((anonBlock->previousSibling() || anonBlock->nextSibling())
1230             && (!anonBlock->previousSibling() || (anonBlock->previousSibling()->style()->styleType() != NOPSEUDO && anonBlock->previousSibling()->isFloating() && !anonBlock->previousSibling()->previousSibling()))
1231             && (!anonBlock->nextSibling() || (anonBlock->nextSibling()->style()->styleType() != NOPSEUDO && anonBlock->nextSibling()->isFloating() && !anonBlock->nextSibling()->nextSibling()))) {
1232             collapseAnonymousBoxChild(this, anonBlock);
1233         }
1234     }
1235
1236     if (!firstChild()) {
1237         // If this was our last child be sure to clear out our line boxes.
1238         if (childrenInline())
1239             deleteLineBoxTree();
1240
1241         // If we are an empty anonymous block in the continuation chain,
1242         // we need to remove ourself and fix the continuation chain.
1243         if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild->isListMarker()) {
1244             RenderObject* containingBlockIgnoringAnonymous = containingBlock();
1245             while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymousBlock())
1246                 containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
1247             for (RenderObject* curr = this; curr; curr = curr->previousInPreOrder(containingBlockIgnoringAnonymous)) {
1248                 if (curr->virtualContinuation() != this)
1249                     continue;
1250
1251                 // Found our previous continuation. We just need to point it to
1252                 // |this|'s next continuation.
1253                 RenderBoxModelObject* nextContinuation = continuation();
1254                 if (curr->isRenderInline())
1255                     toRenderInline(curr)->setContinuation(nextContinuation);
1256                 else if (curr->isRenderBlock())
1257                     toRenderBlock(curr)->setContinuation(nextContinuation);
1258                 else
1259                     ASSERT_NOT_REACHED();
1260
1261                 break;
1262             }
1263             setContinuation(0);
1264             destroy();
1265         }
1266     }
1267 }
1268
1269 bool RenderBlock::isSelfCollapsingBlock() const
1270 {
1271     // We are not self-collapsing if we
1272     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
1273     // (b) are a table,
1274     // (c) have border/padding,
1275     // (d) have a min-height
1276     // (e) have specified that one of our margins can't collapse using a CSS extension
1277     if (logicalHeight() > 0
1278         || isTable() || borderAndPaddingLogicalHeight()
1279         || style()->logicalMinHeight().isPositive()
1280         || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
1281         return false;
1282
1283     Length logicalHeightLength = style()->logicalHeight();
1284     bool hasAutoHeight = logicalHeightLength.isAuto();
1285     if (logicalHeightLength.isPercent() && !document().inQuirksMode()) {
1286         hasAutoHeight = true;
1287         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
1288             if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
1289                 hasAutoHeight = false;
1290         }
1291     }
1292
1293     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
1294     // on whether we have content that is all self-collapsing or not.
1295     if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
1296         // If the block has inline children, see if we generated any line boxes.  If we have any
1297         // line boxes, then we can't be self-collapsing, since we have content.
1298         if (childrenInline())
1299             return !firstLineBox();
1300         
1301         // Whether or not we collapse is dependent on whether all our normal flow children
1302         // are also self-collapsing.
1303         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1304             if (child->isFloatingOrOutOfFlowPositioned())
1305                 continue;
1306             if (!child->isSelfCollapsingBlock())
1307                 return false;
1308         }
1309         return true;
1310     }
1311     return false;
1312 }
1313
1314 void RenderBlock::startDelayUpdateScrollInfo()
1315 {
1316     if (gDelayUpdateScrollInfo == 0) {
1317         ASSERT(!gDelayedUpdateScrollInfoSet);
1318         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
1319     }
1320     ASSERT(gDelayedUpdateScrollInfoSet);
1321     ++gDelayUpdateScrollInfo;
1322 }
1323
1324 void RenderBlock::finishDelayUpdateScrollInfo()
1325 {
1326     --gDelayUpdateScrollInfo;
1327     ASSERT(gDelayUpdateScrollInfo >= 0);
1328     if (gDelayUpdateScrollInfo == 0) {
1329         ASSERT(gDelayedUpdateScrollInfoSet);
1330
1331         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(adoptPtr(gDelayedUpdateScrollInfoSet));
1332         gDelayedUpdateScrollInfoSet = 0;
1333
1334         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
1335             RenderBlock* block = *it;
1336             if (block->hasOverflowClip()) {
1337                 block->layer()->updateScrollInfoAfterLayout();
1338                 block->clearLayoutOverflow();
1339             }
1340         }
1341     }
1342 }
1343
1344 void RenderBlock::updateScrollInfoAfterLayout()
1345 {
1346     if (hasOverflowClip()) {
1347         if (style()->isFlippedBlocksWritingMode()) {
1348             // FIXME: https://bugs.webkit.org/show_bug.cgi?id=97937
1349             // Workaround for now. We cannot delay the scroll info for overflow
1350             // for items with opposite writing directions, as the contents needs
1351             // to overflow in that direction
1352             layer()->updateScrollInfoAfterLayout();
1353             return;
1354         }
1355
1356         if (gDelayUpdateScrollInfo)
1357             gDelayedUpdateScrollInfoSet->add(this);
1358         else
1359             layer()->updateScrollInfoAfterLayout();
1360     }
1361 }
1362
1363 void RenderBlock::layout()
1364 {
1365     StackStats::LayoutCheckPoint layoutCheckPoint;
1366     OverflowEventDispatcher dispatcher(this);
1367
1368     // Update our first letter info now.
1369     updateFirstLetter();
1370
1371     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
1372     // layoutBlock().
1373     layoutBlock(false);
1374     
1375     // It's safe to check for control clip here, since controls can never be table cells.
1376     // If we have a lightweight clip, there can never be any overflow from children.
1377     if (hasControlClip() && m_overflow && !gDelayUpdateScrollInfo)
1378         clearLayoutOverflow();
1379
1380     invalidateBackgroundObscurationStatus();
1381 }
1382
1383 #if ENABLE(CSS_SHAPES)
1384 void RenderBlock::relayoutShapeDescendantIfMoved(RenderBlock* child, LayoutSize offset)
1385 {
1386     LayoutUnit left = isHorizontalWritingMode() ? offset.width() : offset.height();
1387     if (!left || !child || child->shapeInsideInfo() || !layoutShapeInsideInfo())
1388         return;
1389     // Propagate layout markers only up to the child, as we are still in the middle
1390     // of a layout pass
1391     child->setNormalChildNeedsLayout(true);
1392     child->markShapeInsideDescendantsForLayout();
1393     child->layoutIfNeeded();
1394 }
1395
1396 LayoutSize RenderBlock::logicalOffsetFromShapeAncestorContainer(const RenderBlock* container) const
1397 {
1398     const RenderBlock* currentBlock = this;
1399     LayoutRect blockRect(currentBlock->borderBoxRect());
1400     while (currentBlock && !currentBlock->isRenderFlowThread() && currentBlock != container) {
1401         RenderBlock* containerBlock = currentBlock->containingBlock();
1402         ASSERT(containerBlock);
1403         if (!containerBlock)
1404             return LayoutSize();
1405
1406         if (containerBlock->style()->writingMode() != currentBlock->style()->writingMode()) {
1407             // We have to put the block rect in container coordinates
1408             // and we have to take into account both the container and current block flipping modes
1409             // Bug 118073: Flipping inline and block directions at the same time will not work,
1410             // as one of the flipped dimensions will not yet have been set to its final size
1411             if (containerBlock->style()->isFlippedBlocksWritingMode()) {
1412                 if (containerBlock->isHorizontalWritingMode())
1413                     blockRect.setY(currentBlock->height() - blockRect.maxY());
1414                 else
1415                     blockRect.setX(currentBlock->width() - blockRect.maxX());
1416             }
1417             currentBlock->flipForWritingMode(blockRect);
1418         }
1419
1420         blockRect.moveBy(currentBlock->location());
1421         currentBlock = containerBlock;
1422     }
1423
1424     LayoutSize result = isHorizontalWritingMode() ? LayoutSize(blockRect.x(), blockRect.y()) : LayoutSize(blockRect.y(), blockRect.x());
1425     return result;
1426 }
1427
1428 void RenderBlock::imageChanged(WrappedImagePtr image, const IntRect*)
1429 {
1430     RenderBox::imageChanged(image);
1431
1432     if (!parent())
1433         return;
1434
1435     ShapeValue* shapeValue = style()->shapeInside();
1436     if (shapeValue && shapeValue->image() && shapeValue->image()->data() == image) {
1437         ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
1438         shapeInsideInfo->dirtyShapeSize();
1439         markShapeInsideDescendantsForLayout();
1440     }
1441 }
1442
1443 void RenderBlock::updateShapeInsideInfoAfterStyleChange(const ShapeValue* shapeInside, const ShapeValue* oldShapeInside)
1444 {
1445     // FIXME: A future optimization would do a deep comparison for equality.
1446     if (shapeInside == oldShapeInside)
1447         return;
1448
1449     if (shapeInside) {
1450         ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
1451         shapeInsideInfo->dirtyShapeSize();
1452     } else {
1453         setShapeInsideInfo(nullptr);
1454         markShapeInsideDescendantsForLayout();
1455     }
1456 }
1457
1458 void RenderBlock::markShapeInsideDescendantsForLayout()
1459 {
1460     if (!everHadLayout())
1461         return;
1462     if (childrenInline()) {
1463         setNeedsLayout(true);
1464         return;
1465     }
1466     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
1467         if (!child->isRenderBlock())
1468             continue;
1469         RenderBlock* childBlock = toRenderBlock(child);
1470         childBlock->markShapeInsideDescendantsForLayout();
1471     }
1472 }
1473 #endif
1474
1475 #if ENABLE(CSS_SHAPES)
1476 static inline bool shapeInfoRequiresRelayout(const RenderBlock* block)
1477 {
1478     ShapeInsideInfo* info = block->shapeInsideInfo();
1479     if (info)
1480         info->setNeedsLayout(info->shapeSizeDirty());
1481     else
1482         info = block->layoutShapeInsideInfo();
1483     return info && info->needsLayout();
1484 }
1485 #endif
1486
1487 bool RenderBlock::updateShapesBeforeBlockLayout()
1488 {
1489 #if ENABLE(CSS_SHAPES)
1490     if (!flowThreadContainingBlock() && !shapeInsideInfo())
1491         return shapeInfoRequiresRelayout(this);
1492
1493     LayoutUnit oldHeight = logicalHeight();
1494     LayoutUnit oldTop = logicalTop();
1495
1496     // Compute the maximum logical height content may cause this block to expand to
1497     // FIXME: These should eventually use the const computeLogicalHeight rather than updateLogicalHeight
1498     setLogicalHeight(RenderFlowThread::maxLogicalHeight());
1499     updateLogicalHeight();
1500
1501     computeShapeSize();
1502
1503     setLogicalHeight(oldHeight);
1504     setLogicalTop(oldTop);
1505
1506     return shapeInfoRequiresRelayout(this);
1507 #else
1508     return false;
1509 #endif
1510 }
1511
1512 #if ENABLE(CSS_SHAPES)
1513 void RenderBlock::computeShapeSize()
1514 {
1515     ShapeInsideInfo* shapeInsideInfo = this->shapeInsideInfo();
1516     if (shapeInsideInfo) {
1517         bool percentageLogicalHeightResolvable = percentageLogicalHeightIsResolvableFromBlock(this, false);
1518         shapeInsideInfo->setShapeSize(logicalWidth(), percentageLogicalHeightResolvable ? logicalHeight() : LayoutUnit());
1519     }
1520 }
1521 #endif
1522
1523 void RenderBlock::updateShapesAfterBlockLayout(bool heightChanged)
1524 {
1525 #if ENABLE(CSS_SHAPES)
1526     // A previous sibling has changed dimension, so we need to relayout the shape with the content
1527     ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
1528     if (heightChanged && shapeInsideInfo)
1529         shapeInsideInfo->dirtyShapeSize();
1530 #else
1531     UNUSED_PARAM(heightChanged);
1532 #endif
1533 }
1534
1535 bool RenderBlock::updateLogicalWidthAndColumnWidth()
1536 {
1537     LayoutUnit oldWidth = logicalWidth();
1538     LayoutUnit oldColumnWidth = desiredColumnWidth();
1539
1540     updateLogicalWidth();
1541     calcColumnWidth();
1542
1543     bool hasBorderOrPaddingLogicalWidthChanged = m_hasBorderOrPaddingLogicalWidthChanged;
1544     m_hasBorderOrPaddingLogicalWidthChanged = false;
1545
1546     return oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth() || hasBorderOrPaddingLogicalWidthChanged;
1547 }
1548
1549 void RenderBlock::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight)
1550 {
1551     ColumnInfo* colInfo = columnInfo();
1552     if (hasColumns()) {
1553         if (!pageLogicalHeight) {
1554             // We need to go ahead and set our explicit page height if one exists, so that we can
1555             // avoid doing two layout passes.
1556             updateLogicalHeight();
1557             LayoutUnit columnHeight = isRenderView() ? view().pageOrViewLogicalHeight() : contentLogicalHeight();
1558             if (columnHeight > 0) {
1559                 pageLogicalHeight = columnHeight;
1560                 hasSpecifiedPageLogicalHeight = true;
1561             }
1562             setLogicalHeight(0);
1563         }
1564
1565         if (colInfo->columnHeight() != pageLogicalHeight && everHadLayout())
1566             pageLogicalHeightChanged = true;
1567
1568         colInfo->setColumnHeight(pageLogicalHeight);
1569         
1570         if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
1571             colInfo->clearForcedBreaks();
1572
1573         colInfo->setPaginationUnit(paginationUnit());
1574     } else if (isRenderFlowThread()) {
1575         pageLogicalHeight = 1; // This is just a hack to always make sure we have a page logical height.
1576         pageLogicalHeightChanged = toRenderFlowThread(this)->pageLogicalSizeChanged();
1577     }
1578 }
1579
1580 void RenderBlock::layoutBlock(bool, LayoutUnit)
1581 {
1582     ASSERT_NOT_REACHED();
1583     setNeedsLayout(false);
1584 }
1585
1586 void RenderBlock::addOverflowFromChildren()
1587 {
1588     if (!hasColumns()) {
1589         if (childrenInline())
1590             addOverflowFromInlineChildren();
1591         else
1592             addOverflowFromBlockChildren();
1593     } else {
1594         ColumnInfo* colInfo = columnInfo();
1595         if (columnCount(colInfo)) {
1596             LayoutRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
1597             addLayoutOverflow(lastRect);
1598             if (!hasOverflowClip())
1599                 addVisualOverflow(lastRect);
1600         }
1601     }
1602 }
1603
1604 void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats)
1605 {
1606     clearOverflow();
1607
1608     // Add overflow from children.
1609     addOverflowFromChildren();
1610
1611     if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer()))
1612         addOverflowFromFloats();
1613
1614     // Add in the overflow from positioned objects.
1615     addOverflowFromPositionedObjects();
1616
1617     if (hasOverflowClip()) {
1618         // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
1619         // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
1620         // be considered reachable.
1621         LayoutRect clientRect(clientBoxRect());
1622         LayoutRect rectToApply;
1623         if (isHorizontalWritingMode())
1624             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), 1, max<LayoutUnit>(0, oldClientAfterEdge - clientRect.y()));
1625         else
1626             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), max<LayoutUnit>(0, oldClientAfterEdge - clientRect.x()), 1);
1627         addLayoutOverflow(rectToApply);
1628         if (hasRenderOverflow())
1629             m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge);
1630     }
1631         
1632     // Add visual overflow from box-shadow and border-image-outset.
1633     addVisualEffectOverflow();
1634
1635     // Add visual overflow from theme.
1636     addVisualOverflowFromTheme();
1637
1638     if (isRenderNamedFlowThread())
1639         toRenderNamedFlowThread(this)->computeOversetStateForRegions(oldClientAfterEdge);
1640 }
1641
1642 void RenderBlock::clearLayoutOverflow()
1643 {
1644     if (!m_overflow)
1645         return;
1646     
1647     if (visualOverflowRect() == borderBoxRect()) {
1648         // FIXME: Implement complete solution for regions overflow.
1649         clearOverflow();
1650         return;
1651     }
1652     
1653     m_overflow->setLayoutOverflow(borderBoxRect());
1654 }
1655
1656 void RenderBlock::addOverflowFromBlockChildren()
1657 {
1658     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1659         if (!child->isFloatingOrOutOfFlowPositioned())
1660             addOverflowFromChild(child);
1661     }
1662 }
1663
1664 void RenderBlock::addOverflowFromFloats()
1665 {
1666     if (!m_floatingObjects)
1667         return;
1668
1669     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
1670     FloatingObjectSetIterator end = floatingObjectSet.end();
1671     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
1672         FloatingObject* r = *it;
1673         if (r->isDescendant())
1674             addOverflowFromChild(r->renderer(), IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
1675     }
1676 }
1677
1678 void RenderBlock::addOverflowFromPositionedObjects()
1679 {
1680     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
1681     if (!positionedDescendants)
1682         return;
1683
1684     RenderBox* positionedObject;
1685     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
1686     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
1687         positionedObject = *it;
1688         
1689         // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
1690         if (positionedObject->style()->position() != FixedPosition) {
1691             LayoutUnit x = positionedObject->x();
1692             if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
1693                 x -= verticalScrollbarWidth();
1694             addOverflowFromChild(positionedObject, LayoutSize(x, positionedObject->y()));
1695         }
1696     }
1697 }
1698
1699 void RenderBlock::addVisualOverflowFromTheme()
1700 {
1701     if (!style()->hasAppearance())
1702         return;
1703
1704     IntRect inflatedRect = pixelSnappedBorderBoxRect();
1705     theme()->adjustRepaintRect(this, inflatedRect);
1706     addVisualOverflow(inflatedRect);
1707
1708     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
1709         flowThread->addRegionsVisualOverflowFromTheme(this);
1710 }
1711
1712 bool RenderBlock::expandsToEncloseOverhangingFloats() const
1713 {
1714     return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBoxIncludingDeprecated())
1715            || hasColumns() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isRoot();
1716 }
1717
1718 static void destroyRunIn(RenderBoxModelObject* runIn)
1719 {
1720     ASSERT(runIn->isRunIn());
1721     ASSERT(!runIn->firstChild());
1722
1723     // Delete our line box tree. This is needed as our children got moved
1724     // and our line box tree is no longer valid.
1725     if (runIn->isRenderBlock())
1726         toRenderBlock(runIn)->deleteLineBoxTree();
1727     else if (runIn->isRenderInline())
1728         toRenderInline(runIn)->deleteLineBoxTree();
1729     else
1730         ASSERT_NOT_REACHED();
1731
1732     runIn->destroy();
1733 }
1734
1735 void RenderBlock::placeRunInIfNeeded(RenderObject* newChild)
1736 {
1737     if (newChild->isRunIn())
1738         moveRunInUnderSiblingBlockIfNeeded(newChild);
1739     else if (RenderObject* prevSibling = newChild->previousSibling()) {
1740         if (prevSibling->isRunIn())
1741             moveRunInUnderSiblingBlockIfNeeded(prevSibling);
1742     }
1743 }
1744
1745 RenderBoxModelObject* RenderBlock::createReplacementRunIn(RenderBoxModelObject* runIn)
1746 {
1747     ASSERT(runIn->isRunIn());
1748     ASSERT(runIn->element());
1749
1750     RenderBoxModelObject* newRunIn = 0;
1751     if (!runIn->isRenderBlockFlow())
1752         newRunIn = new (renderArena()) RenderBlockFlow(runIn->element());
1753     else
1754         newRunIn = new (renderArena()) RenderInline(runIn->element());
1755
1756     runIn->element()->setRenderer(newRunIn);
1757     newRunIn->setStyle(runIn->style());
1758
1759     runIn->moveAllChildrenTo(newRunIn, true);
1760
1761     return newRunIn;
1762 }
1763
1764 void RenderBlock::moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn)
1765 {
1766     ASSERT(runIn->isRunIn());
1767
1768     // See if we have inline children. If the children aren't inline,
1769     // then just treat the run-in as a normal block.
1770     if (!runIn->childrenInline())
1771         return;
1772
1773     // FIXME: We don't handle non-block elements with run-in for now.
1774     if (!runIn->isRenderBlockFlow())
1775         return;
1776
1777     // FIXME: We don't support run-ins with or as part of a continuation
1778     // as it makes the back-and-forth placing complex.
1779     if (runIn->isElementContinuation() || runIn->virtualContinuation())
1780         return;
1781
1782     // Check if this node is allowed to run-in. E.g. <select> expects its renderer to
1783     // be a RenderListBox or RenderMenuList, and hence cannot be a RenderInline run-in.
1784     if (!runIn->canBeReplacedWithInlineRunIn())
1785         return;
1786
1787     RenderObject* curr = runIn->nextSibling();
1788     if (!curr || !curr->isRenderBlock() || !curr->childrenInline())
1789         return;
1790
1791     if (toRenderBlock(curr)->beingDestroyed())
1792         return;
1793
1794     // Per CSS3, "A run-in cannot run in to a block that already starts with a
1795     // run-in or that itself is a run-in".
1796     if (curr->isRunIn() || (curr->firstChild() && curr->firstChild()->isRunIn()))
1797         return;
1798
1799     if (curr->isAnonymous() || curr->isFloatingOrOutOfFlowPositioned())
1800         return;
1801
1802     RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn);
1803     RenderBoxModelObject* newRunIn = createReplacementRunIn(oldRunIn);
1804     destroyRunIn(oldRunIn);
1805
1806     // Now insert the new child under |curr| block. Use addChild instead of insertChildNode
1807     // since it handles correct placement of the children, especially where we cannot insert
1808     // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
1809     curr->addChild(newRunIn, curr->firstChild());
1810
1811     // Make sure that |this| get a layout since its run-in child moved.
1812     curr->setNeedsLayoutAndPrefWidthsRecalc();
1813 }
1814
1815 bool RenderBlock::runInIsPlacedIntoSiblingBlock(RenderObject* runIn)
1816 {
1817     ASSERT(runIn->isRunIn());
1818
1819     // If we don't have a parent, we can't be moved into our sibling block.
1820     if (!parent())
1821         return false;
1822
1823     // An intruded run-in needs to be an inline.
1824     if (!runIn->isRenderInline())
1825         return false;
1826
1827     return true;
1828 }
1829
1830 void RenderBlock::moveRunInToOriginalPosition(RenderObject* runIn)
1831 {
1832     ASSERT(runIn->isRunIn());
1833
1834     if (!runInIsPlacedIntoSiblingBlock(runIn))
1835         return;
1836
1837     // FIXME: Run-in that are now placed in sibling block can break up into continuation
1838     // chains when new children are added to it. We cannot easily send them back to their
1839     // original place since that requires writing integration logic with RenderInline::addChild
1840     // and all other places that might cause continuations to be created (without blowing away
1841     // |this|). Disabling this feature for now to prevent crashes.
1842     if (runIn->isElementContinuation() || runIn->virtualContinuation())
1843         return;
1844
1845     RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn);
1846     RenderBoxModelObject* newRunIn = createReplacementRunIn(oldRunIn);
1847     destroyRunIn(oldRunIn);
1848
1849     // Add the run-in block as our previous sibling.
1850     parent()->addChild(newRunIn, this);
1851
1852     // Make sure that the parent holding the new run-in gets layout.
1853     parent()->setNeedsLayoutAndPrefWidthsRecalc();
1854 }
1855
1856 LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart, RenderRegion* region)
1857 {
1858     LayoutUnit startPosition = startOffsetForContent(region);
1859
1860     // Add in our start margin.
1861     LayoutUnit oldPosition = startPosition + childMarginStart;
1862     LayoutUnit newPosition = oldPosition;
1863
1864     LayoutUnit blockOffset = logicalTopForChild(child);
1865     if (region)
1866         blockOffset = max(blockOffset, blockOffset + (region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage()));
1867
1868     LayoutUnit startOff = startOffsetForLine(blockOffset, false, region, logicalHeightForChild(child));
1869
1870     if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
1871         if (childMarginStart < 0)
1872             startOff += childMarginStart;
1873         newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
1874     } else if (startOff != startPosition)
1875         newPosition = startOff + childMarginStart;
1876
1877     return newPosition - oldPosition;
1878 }
1879
1880 void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode applyDelta)
1881 {
1882     LayoutUnit startPosition = borderStart() + paddingStart();
1883     if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
1884         startPosition -= verticalScrollbarWidth();
1885     LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
1886
1887     // Add in our start margin.
1888     LayoutUnit childMarginStart = marginStartForChild(child);
1889     LayoutUnit newPosition = startPosition + childMarginStart;
1890         
1891     // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
1892     // to shift over as necessary to dodge any floats that might get in the way.
1893     if (child->avoidsFloats() && containsFloats() && !flowThreadContainingBlock())
1894         newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child));
1895
1896     setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), applyDelta);
1897 }
1898
1899 void RenderBlock::setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode applyDelta)
1900 {
1901     if (isHorizontalWritingMode()) {
1902         if (applyDelta == ApplyLayoutDelta)
1903             view().addLayoutDelta(LayoutSize(child->x() - logicalLeft, 0));
1904         child->setX(logicalLeft);
1905     } else {
1906         if (applyDelta == ApplyLayoutDelta)
1907             view().addLayoutDelta(LayoutSize(0, child->y() - logicalLeft));
1908         child->setY(logicalLeft);
1909     }
1910 }
1911
1912 void RenderBlock::setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode applyDelta)
1913 {
1914     if (isHorizontalWritingMode()) {
1915         if (applyDelta == ApplyLayoutDelta)
1916             view().addLayoutDelta(LayoutSize(0, child->y() - logicalTop));
1917         child->setY(logicalTop);
1918     } else {
1919         if (applyDelta == ApplyLayoutDelta)
1920             view().addLayoutDelta(LayoutSize(child->x() - logicalTop, 0));
1921         child->setX(logicalTop);
1922     }
1923 }
1924
1925 void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox* child)
1926 {
1927     // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
1928     // an auto value. Add a method to determine this, so that we can avoid the relayout.
1929     if (relayoutChildren || (child->hasRelativeLogicalHeight() && !isRenderView()) || child->hasViewportPercentageLogicalHeight())
1930         child->setChildNeedsLayout(true, MarkOnlyThis);
1931
1932     // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
1933     if (relayoutChildren && child->needsPreferredWidthsRecalculation())
1934         child->setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
1935 }
1936
1937 void RenderBlock::dirtyForLayoutFromPercentageHeightDescendants()
1938 {
1939     if (!gPercentHeightDescendantsMap)
1940         return;
1941
1942     TrackedRendererListHashSet* descendants = gPercentHeightDescendantsMap->get(this);
1943     if (!descendants)
1944         return;
1945     
1946     TrackedRendererListHashSet::iterator end = descendants->end();
1947     for (TrackedRendererListHashSet::iterator it = descendants->begin(); it != end; ++it) {
1948         RenderBox* box = *it;
1949         while (box != this) {
1950             if (box->normalChildNeedsLayout())
1951                 break;
1952             box->setChildNeedsLayout(true, MarkOnlyThis);
1953             
1954             // If the width of an image is affected by the height of a child (e.g., an image with an aspect ratio),
1955             // then we have to dirty preferred widths, since even enclosing blocks can become dirty as a result.
1956             // (A horizontal flexbox that contains an inline image wrapped in an anonymous block for example.)
1957             if (box->hasAspectRatio()) 
1958                 box->setPreferredLogicalWidthsDirty(true);
1959             
1960             box = box->containingBlock();
1961             ASSERT(box);
1962             if (!box)
1963                 break;
1964         }
1965     }
1966 }
1967
1968 void RenderBlock::simplifiedNormalFlowLayout()
1969 {
1970     if (childrenInline()) {
1971         ListHashSet<RootInlineBox*> lineBoxes;
1972         for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
1973             RenderObject* o = walker.current();
1974             if (!o->isOutOfFlowPositioned() && (o->isReplaced() || o->isFloating())) {
1975                 o->layoutIfNeeded();
1976                 if (toRenderBox(o)->inlineBoxWrapper())
1977                     lineBoxes.add(&toRenderBox(o)->inlineBoxWrapper()->root());
1978             } else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline()))
1979                 o->setNeedsLayout(false);
1980         }
1981
1982         // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
1983         // FIXME: Find a way to invalidate the knownToHaveNoOverflow flag on the InlineBoxes.
1984         GlyphOverflowAndFallbackFontsMap textBoxDataMap;                  
1985         for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
1986             RootInlineBox* box = *it;
1987             box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
1988         }
1989     } else {
1990         for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
1991             if (!box->isOutOfFlowPositioned())
1992                 box->layoutIfNeeded();
1993         }
1994     }
1995 }
1996
1997 bool RenderBlock::simplifiedLayout()
1998 {
1999     if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
2000         return false;
2001
2002     LayoutStateMaintainer statePusher(&view(), this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
2003     
2004     if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
2005         return false;
2006
2007     // Lay out positioned descendants or objects that just need to recompute overflow.
2008     if (needsSimplifiedNormalFlowLayout())
2009         simplifiedNormalFlowLayout();
2010
2011     // Make sure a forced break is applied after the content if we are a flow thread in a simplified layout.
2012     // This ensures the size information is correctly computed for the last auto-height region receiving content.
2013     if (isRenderFlowThread())
2014         toRenderFlowThread(this)->applyBreakAfterContent(clientLogicalBottom());
2015
2016     // Lay out our positioned objects if our positioned child bit is set.
2017     // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
2018     // child, neither the fixed element nor its container learn of the movement since posChildNeedsLayout() is only marked as far as the 
2019     // relative positioned container. So if we can have fixed pos objects in our positioned objects list check if any of them
2020     // are statically positioned and thus need to move with their absolute ancestors.
2021     bool canContainFixedPosObjects = canContainFixedPositionObjects();
2022     if (posChildNeedsLayout() || canContainFixedPosObjects)
2023         layoutPositionedObjects(false, !posChildNeedsLayout() && canContainFixedPosObjects);
2024
2025     // Recompute our overflow information.
2026     // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
2027     // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
2028     // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
2029     // lowestPosition on every relayout so it's not a regression.
2030     // computeOverflow expects the bottom edge before we clamp our height. Since this information isn't available during
2031     // simplifiedLayout, we cache the value in m_overflow.
2032     LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
2033     computeOverflow(oldClientAfterEdge, true);
2034
2035     statePusher.pop();
2036     
2037     updateLayerTransform();
2038
2039     updateScrollInfoAfterLayout();
2040
2041     setNeedsLayout(false);
2042     return true;
2043 }
2044
2045 void RenderBlock::markFixedPositionObjectForLayoutIfNeeded(RenderObject* child)
2046 {
2047     if (child->style()->position() != FixedPosition)
2048         return;
2049
2050     bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontalWritingMode());
2051     bool hasStaticInlinePosition = child->style()->hasStaticInlinePosition(isHorizontalWritingMode());
2052     if (!hasStaticBlockPosition && !hasStaticInlinePosition)
2053         return;
2054
2055     RenderObject* o = child->parent();
2056     while (o && !o->isRenderView() && o->style()->position() != AbsolutePosition)
2057         o = o->parent();
2058     if (o->style()->position() != AbsolutePosition)
2059         return;
2060
2061     RenderBox* box = toRenderBox(child);
2062     if (hasStaticInlinePosition) {
2063         LogicalExtentComputedValues computedValues;
2064         box->computeLogicalWidthInRegion(computedValues);
2065         LayoutUnit newLeft = computedValues.m_position;
2066         if (newLeft != box->logicalLeft())
2067             child->setChildNeedsLayout(true, MarkOnlyThis);
2068     } else if (hasStaticBlockPosition) {
2069         LayoutUnit oldTop = box->logicalTop();
2070         box->updateLogicalHeight();
2071         if (box->logicalTop() != oldTop)
2072             child->setChildNeedsLayout(true, MarkOnlyThis);
2073     }
2074 }
2075
2076 void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly)
2077 {
2078     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
2079     if (!positionedDescendants)
2080         return;
2081         
2082     if (hasColumns())
2083         view().layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
2084
2085     RenderBox* r;
2086     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
2087     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
2088         r = *it;
2089         
2090         estimateRegionRangeForBoxChild(r);
2091
2092         // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
2093         // 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. 
2094         // it has static position.
2095         markFixedPositionObjectForLayoutIfNeeded(r);
2096         if (fixedPositionObjectsOnly) {
2097             r->layoutIfNeeded();
2098             continue;
2099         }
2100
2101         // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
2102         // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
2103         // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
2104         // positioned explicitly) this should not incur a performance penalty.
2105         if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this))
2106             r->setChildNeedsLayout(true, MarkOnlyThis);
2107             
2108         // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
2109         if (relayoutChildren && r->needsPreferredWidthsRecalculation())
2110             r->setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
2111         
2112         if (!r->needsLayout())
2113             r->markForPaginationRelayoutIfNeeded();
2114         
2115         // We don't have to do a full layout.  We just have to update our position. Try that first. If we have shrink-to-fit width
2116         // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
2117         if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
2118             r->setNeedsLayout(false);
2119             
2120         // If we are paginated or in a line grid, go ahead and compute a vertical position for our object now.
2121         // If it's wrong we'll lay out again.
2122         LayoutUnit oldLogicalTop = 0;
2123         bool needsBlockDirectionLocationSetBeforeLayout = r->needsLayout() && view().layoutState()->needsBlockDirectionLocationSetBeforeLayout();
2124         if (needsBlockDirectionLocationSetBeforeLayout) {
2125             if (isHorizontalWritingMode() == r->isHorizontalWritingMode())
2126                 r->updateLogicalHeight();
2127             else
2128                 r->updateLogicalWidth();
2129             oldLogicalTop = logicalTopForChild(r);
2130         }
2131
2132         r->layoutIfNeeded();
2133
2134         // Lay out again if our estimate was wrong.
2135         if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop) {
2136             r->setChildNeedsLayout(true, MarkOnlyThis);
2137             r->layoutIfNeeded();
2138         }
2139
2140         if (updateRegionRangeForBoxChild(r)) {
2141             r->setNeedsLayout(true, MarkOnlyThis);
2142             r->layoutIfNeeded();
2143         }
2144     }
2145     
2146     if (hasColumns())
2147         view().layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
2148 }
2149
2150 void RenderBlock::markPositionedObjectsForLayout()
2151 {
2152     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
2153     if (positionedDescendants) {
2154         RenderBox* r;
2155         TrackedRendererListHashSet::iterator end = positionedDescendants->end();
2156         for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
2157             r = *it;
2158             r->setChildNeedsLayout(true);
2159         }
2160     }
2161 }
2162
2163 void RenderBlock::markForPaginationRelayoutIfNeeded()
2164 {
2165     ASSERT(!needsLayout());
2166     if (needsLayout())
2167         return;
2168
2169     if (view().layoutState()->pageLogicalHeightChanged() || (view().layoutState()->pageLogicalHeight() && view().layoutState()->pageLogicalOffset(this, logicalTop()) != pageLogicalOffset()))
2170         setChildNeedsLayout(true, MarkOnlyThis);
2171 }
2172
2173 void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
2174 {
2175     // Repaint any overhanging floats (if we know we're the one to paint them).
2176     // Otherwise, bail out.
2177     if (!hasOverhangingFloats())
2178         return;
2179
2180     // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
2181     // in this block. Better yet would be to push extra state for the containers of other floats.
2182     LayoutStateDisabler layoutStateDisabler(&view());
2183     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2184     FloatingObjectSetIterator end = floatingObjectSet.end();
2185     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
2186         FloatingObject* r = *it;
2187         // Only repaint the object if it is overhanging, is not in its own layer, and
2188         // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
2189         // condition is replaced with being a descendant of us.
2190         if (r->logicalBottom(isHorizontalWritingMode()) > logicalHeight()
2191             && !r->renderer()->hasSelfPaintingLayer()
2192             && (r->shouldPaint() || (paintAllDescendants && r->renderer()->isDescendantOf(this)))) {
2193             r->renderer()->repaint();
2194             r->renderer()->repaintOverhangingFloats(false);
2195         }
2196     }
2197 }
2198  
2199 void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2200 {
2201     LayoutPoint adjustedPaintOffset = paintOffset + location();
2202     
2203     PaintPhase phase = paintInfo.phase;
2204
2205     // Check if we need to do anything at all.
2206     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
2207     // paints the root's background.
2208     if (!isRoot()) {
2209         LayoutRect overflowBox = overflowRectForPaintRejection();
2210         flipForWritingMode(overflowBox);
2211         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
2212         overflowBox.moveBy(adjustedPaintOffset);
2213         if (!overflowBox.intersects(paintInfo.rect))
2214             return;
2215     }
2216
2217     bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset);
2218     paintObject(paintInfo, adjustedPaintOffset);
2219     if (pushedClip)
2220         popContentsClip(paintInfo, phase, adjustedPaintOffset);
2221
2222     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
2223     // z-index.  We paint after we painted the background/border, so that the scrollbars will
2224     // sit above the background/border.
2225     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this) && !paintInfo.paintRootBackgroundOnly())
2226         layer()->paintOverflowControls(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect);
2227 }
2228
2229 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2230 {
2231     if (paintInfo.context->paintingDisabled())
2232         return;
2233
2234     const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
2235     bool ruleTransparent = style()->columnRuleIsTransparent();
2236     EBorderStyle ruleStyle = style()->columnRuleStyle();
2237     LayoutUnit ruleThickness = style()->columnRuleWidth();
2238     LayoutUnit colGap = columnGap();
2239     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
2240     if (!renderRule)
2241         return;
2242
2243     ColumnInfo* colInfo = columnInfo();
2244     unsigned colCount = columnCount(colInfo);
2245
2246     bool antialias = shouldAntialiasLines(paintInfo.context);
2247
2248     if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
2249         bool leftToRight = style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed();
2250         LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : contentLogicalWidth();
2251         LayoutUnit ruleAdd = logicalLeftOffsetForContent();
2252         LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : contentLogicalWidth();
2253         LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
2254         BoxSide boxSide = isHorizontalWritingMode()
2255             ? leftToRight ? BSLeft : BSRight
2256             : leftToRight ? BSTop : BSBottom;
2257
2258         for (unsigned i = 0; i < colCount; i++) {
2259             // Move to the next position.
2260             if (leftToRight) {
2261                 ruleLogicalLeft += inlineDirectionSize + colGap / 2;
2262                 currLogicalLeftOffset += inlineDirectionSize + colGap;
2263             } else {
2264                 ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
2265                 currLogicalLeftOffset -= (inlineDirectionSize + colGap);
2266             }
2267            
2268             // Now paint the column rule.
2269             if (i < colCount - 1) {
2270                 LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft() + paddingLeft();
2271                 LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
2272                 LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
2273                 LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
2274                 IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
2275                 drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
2276             }
2277             
2278             ruleLogicalLeft = currLogicalLeftOffset;
2279         }
2280     } else {
2281         bool topToBottom = !style()->isFlippedBlocksWritingMode() ^ colInfo->progressionIsReversed();
2282         LayoutUnit ruleLeft = isHorizontalWritingMode()
2283             ? borderLeft() + paddingLeft()
2284             : colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderAndPaddingBefore() : borderAndPaddingAfter());
2285         LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : ruleThickness;
2286         LayoutUnit ruleTop = isHorizontalWritingMode()
2287             ? colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderAndPaddingBefore() : borderAndPaddingAfter())
2288             : borderStart() + paddingStart();
2289         LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : contentHeight();
2290         LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
2291
2292         if (!topToBottom) {
2293             if (isHorizontalWritingMode())
2294                 ruleRect.setY(height() - ruleRect.maxY());
2295             else
2296                 ruleRect.setX(width() - ruleRect.maxX());
2297         }
2298
2299         ruleRect.moveBy(paintOffset);
2300
2301         BoxSide boxSide = isHorizontalWritingMode()
2302             ? topToBottom ? BSTop : BSBottom
2303             : topToBottom ? BSLeft : BSRight;
2304
2305         LayoutSize step(0, topToBottom ? colInfo->columnHeight() + colGap : -(colInfo->columnHeight() + colGap));
2306         if (!isHorizontalWritingMode())
2307             step = step.transposedSize();
2308
2309         for (unsigned i = 1; i < colCount; i++) {
2310             ruleRect.move(step);
2311             IntRect pixelSnappedRuleRect = pixelSnappedIntRect(ruleRect);
2312             drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
2313         }
2314     }
2315 }
2316
2317 LayoutUnit RenderBlock::initialBlockOffsetForPainting() const
2318 {
2319     ColumnInfo* colInfo = columnInfo();
2320     LayoutUnit result = 0;
2321     if (colInfo->progressionAxis() == ColumnInfo::BlockAxis && colInfo->progressionIsReversed()) {
2322         LayoutRect colRect = columnRectAt(colInfo, 0);
2323         result = isHorizontalWritingMode() ? colRect.y() : colRect.x();
2324         result -= borderAndPaddingBefore();
2325         if (style()->isFlippedBlocksWritingMode())
2326             result = -result;
2327     }
2328     return result;
2329 }
2330     
2331 LayoutUnit RenderBlock::blockDeltaForPaintingNextColumn() const
2332 {
2333     ColumnInfo* colInfo = columnInfo();
2334     LayoutUnit blockDelta = -colInfo->columnHeight();
2335     LayoutUnit colGap = columnGap();
2336     if (colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
2337         if (!colInfo->progressionIsReversed())
2338             blockDelta = colGap;
2339         else
2340             blockDelta -= (colInfo->columnHeight() + colGap);
2341     }
2342     if (style()->isFlippedBlocksWritingMode())
2343         blockDelta = -blockDelta;
2344     return blockDelta;
2345 }
2346
2347 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool paintingFloats)
2348 {
2349     // We need to do multiple passes, breaking up our child painting into strips.
2350     GraphicsContext* context = paintInfo.context;
2351     ColumnInfo* colInfo = columnInfo();
2352     unsigned colCount = columnCount(colInfo);
2353     if (!colCount)
2354         return;
2355     LayoutUnit colGap = columnGap();
2356     LayoutUnit currLogicalTopOffset = initialBlockOffsetForPainting();
2357     LayoutUnit blockDelta = blockDeltaForPaintingNextColumn();
2358     for (unsigned i = 0; i < colCount; i++) {
2359         // For each rect, we clip to the rect, and then we adjust our coords.
2360         LayoutRect colRect = columnRectAt(colInfo, i);
2361         flipForWritingMode(colRect);
2362         
2363         LayoutUnit logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
2364         LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(logicalLeftOffset, currLogicalTopOffset) : LayoutSize(currLogicalTopOffset, logicalLeftOffset);
2365         colRect.moveBy(paintOffset);
2366         PaintInfo info(paintInfo);
2367         info.rect.intersect(pixelSnappedIntRect(colRect));
2368         
2369         if (!info.rect.isEmpty()) {
2370             GraphicsContextStateSaver stateSaver(*context);
2371             LayoutRect clipRect(colRect);
2372             
2373             if (i < colCount - 1) {
2374                 if (isHorizontalWritingMode())
2375                     clipRect.expand(colGap / 2, 0);
2376                 else
2377                     clipRect.expand(0, colGap / 2);
2378             }
2379             // Each strip pushes a clip, since column boxes are specified as being
2380             // like overflow:hidden.
2381             // FIXME: Content and column rules that extend outside column boxes at the edges of the multi-column element
2382             // are clipped according to the 'overflow' property.
2383             context->clip(pixelSnappedIntRect(clipRect));
2384
2385             // Adjust our x and y when painting.
2386             LayoutPoint adjustedPaintOffset = paintOffset + offset;
2387             if (paintingFloats)
2388                 paintFloats(info, adjustedPaintOffset, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
2389             else
2390                 paintContents(info, adjustedPaintOffset);
2391         }
2392         currLogicalTopOffset += blockDelta;
2393     }
2394 }
2395
2396 void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2397 {
2398     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
2399     // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
2400     // will do a full repaint.
2401     if (document().didLayoutWithPendingStylesheets() && !isRenderView())
2402         return;
2403
2404     if (childrenInline())
2405         m_lineBoxes.paint(this, paintInfo, paintOffset);
2406     else {
2407         PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
2408         newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
2409
2410         // We don't paint our own background, but we do let the kids paint their backgrounds.
2411         PaintInfo paintInfoForChild(paintInfo);
2412         paintInfoForChild.phase = newPhase;
2413         paintInfoForChild.updateSubtreePaintRootForChildren(this);
2414
2415         // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
2416         // NSViews. Do not add any more code for this.
2417         bool usePrintRect = !view().printRect().isEmpty();
2418         paintChildren(paintInfo, paintOffset, paintInfoForChild, usePrintRect);
2419     }
2420 }
2421
2422 void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset, PaintInfo& paintInfoForChild, bool usePrintRect)
2423 {
2424     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
2425         if (!paintChild(child, paintInfo, paintOffset, paintInfoForChild, usePrintRect))
2426             return;
2427     }
2428 }
2429
2430 bool RenderBlock::paintChild(RenderBox* child, PaintInfo& paintInfo, const LayoutPoint& paintOffset, PaintInfo& paintInfoForChild, bool usePrintRect)
2431 {
2432     // Check for page-break-before: always, and if it's set, break and bail.
2433     bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
2434     LayoutUnit absoluteChildY = paintOffset.y() + child->y();
2435     if (checkBeforeAlways
2436         && absoluteChildY > paintInfo.rect.y()
2437         && absoluteChildY < paintInfo.rect.maxY()) {
2438         view().setBestTruncatedAt(absoluteChildY, this, true);
2439         return false;
2440     }
2441
2442     if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= view().printRect().height()) {
2443         // Paginate block-level replaced elements.
2444         if (absoluteChildY + child->height() > view().printRect().maxY()) {
2445             if (absoluteChildY < view().truncatedAt())
2446                 view().setBestTruncatedAt(absoluteChildY, child);
2447             // If we were able to truncate, don't paint.
2448             if (absoluteChildY >= view().truncatedAt())
2449                 return false;
2450         }
2451     }
2452
2453     LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
2454     if (!child->hasSelfPaintingLayer() && !child->isFloating())
2455         child->paint(paintInfoForChild, childPoint);
2456
2457     // Check for page-break-after: always, and if it's set, break and bail.
2458     bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
2459     if (checkAfterAlways
2460         && (absoluteChildY + child->height()) > paintInfo.rect.y()
2461         && (absoluteChildY + child->height()) < paintInfo.rect.maxY()) {
2462         view().setBestTruncatedAt(absoluteChildY + child->height() + max<LayoutUnit>(0, child->collapsedMarginAfter()), this, true);
2463         return false;
2464     }
2465     return true;
2466 }
2467
2468
2469 void RenderBlock::paintCaret(PaintInfo& paintInfo, const LayoutPoint& paintOffset, CaretType type)
2470 {
2471     // Paint the caret if the FrameSelection says so or if caret browsing is enabled
2472     bool caretBrowsing = frame().settings().caretBrowsingEnabled();
2473     RenderObject* caretPainter;
2474     bool isContentEditable;
2475     if (type == CursorCaret) {
2476         caretPainter = frame().selection().caretRenderer();
2477         isContentEditable = frame().selection().rendererIsEditable();
2478     } else {
2479         caretPainter = frame().page()->dragCaretController().caretRenderer();
2480         isContentEditable = frame().page()->dragCaretController().isContentEditable();
2481     }
2482
2483     if (caretPainter == this && (isContentEditable || caretBrowsing)) {
2484         if (type == CursorCaret)
2485             frame().selection().paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
2486         else
2487             frame().page()->dragCaretController().paintDragCaret(&frame(), paintInfo.context, paintOffset, paintInfo.rect);
2488     }
2489 }
2490
2491 void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2492 {
2493     PaintPhase paintPhase = paintInfo.phase;
2494
2495     // 1. paint background, borders etc
2496     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
2497         if (hasBoxDecorations())
2498             paintBoxDecorations(paintInfo, paintOffset);
2499         if (hasColumns() && !paintInfo.paintRootBackgroundOnly())
2500             paintColumnRules(paintInfo, paintOffset);
2501     }
2502
2503     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
2504         paintMask(paintInfo, paintOffset);
2505         return;
2506     }
2507
2508     // We're done.  We don't bother painting any children.
2509     if (paintPhase == PaintPhaseBlockBackground || paintInfo.paintRootBackgroundOnly())
2510         return;
2511
2512     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
2513     LayoutPoint scrolledOffset = paintOffset;
2514     if (hasOverflowClip())
2515         scrolledOffset.move(-scrolledContentOffset());
2516
2517     // 2. paint contents
2518     if (paintPhase != PaintPhaseSelfOutline) {
2519         if (hasColumns())
2520             paintColumnContents(paintInfo, scrolledOffset);
2521         else
2522             paintContents(paintInfo, scrolledOffset);
2523     }
2524
2525     // 3. paint selection
2526     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
2527     bool isPrinting = document().printing();
2528     if (!isPrinting && !hasColumns())
2529         paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks.
2530
2531     // 4. paint floats.
2532     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
2533         if (hasColumns())
2534             paintColumnContents(paintInfo, scrolledOffset, true);
2535         else
2536             paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
2537     }
2538
2539     // 5. paint outline.
2540     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
2541         paintOutline(paintInfo, LayoutRect(paintOffset, size()));
2542
2543     // 6. paint continuation outlines.
2544     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
2545         RenderInline* inlineCont = inlineElementContinuation();
2546         if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
2547             RenderInline* inlineRenderer = toRenderInline(inlineCont->element()->renderer());
2548             RenderBlock* cb = containingBlock();
2549
2550             bool inlineEnclosedInSelfPaintingLayer = false;
2551             for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
2552                 if (box->hasSelfPaintingLayer()) {
2553                     inlineEnclosedInSelfPaintingLayer = true;
2554                     break;
2555                 }
2556             }
2557
2558             // Do not add continuations for outline painting by our containing block if we are a relative positioned
2559             // anonymous block (i.e. have our own layer), paint them straightaway instead. This is because a block depends on renderers in its continuation table being
2560             // in the same layer. 
2561             if (!inlineEnclosedInSelfPaintingLayer && !hasLayer())
2562                 cb->addContinuationWithOutline(inlineRenderer);
2563             else if (!inlineRenderer->firstLineBox() || (!inlineEnclosedInSelfPaintingLayer && hasLayer()))
2564                 inlineRenderer->paintOutline(paintInfo, paintOffset - locationOffset() + inlineRenderer->containingBlock()->location());
2565         }
2566         paintContinuationOutlines(paintInfo, paintOffset);
2567     }
2568
2569     // 7. paint caret.
2570     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
2571     // then paint the caret.
2572     if (paintPhase == PaintPhaseForeground) {        
2573         paintCaret(paintInfo, paintOffset, CursorCaret);
2574         paintCaret(paintInfo, paintOffset, DragCaret);
2575     }
2576 }
2577
2578 LayoutPoint RenderBlock::flipFloatForWritingModeForChild(const FloatingObject* child, const LayoutPoint& point) const
2579 {
2580     if (!style()->isFlippedBlocksWritingMode())
2581         return point;
2582     
2583     // This is similar to RenderBox::flipForWritingModeForChild. We have to subtract out our left/top offsets twice, since
2584     // it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped
2585     // case.
2586     if (isHorizontalWritingMode())
2587         return LayoutPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
2588     return LayoutPoint(point.x() + width() - child->renderer()->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
2589 }
2590
2591 void RenderBlock::paintFloats(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool preservePhase)
2592 {
2593     if (!m_floatingObjects)
2594         return;
2595
2596     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2597     FloatingObjectSetIterator end = floatingObjectSet.end();
2598     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
2599         FloatingObject* r = *it;
2600         // Only paint the object if our m_shouldPaint flag is set.
2601         if (r->shouldPaint() && !r->renderer()->hasSelfPaintingLayer()) {
2602             PaintInfo currentPaintInfo(paintInfo);
2603             currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
2604             // FIXME: LayoutPoint version of xPositionForFloatIncludingMargin would make this much cleaner.
2605             LayoutPoint childPoint = flipFloatForWritingModeForChild(r, LayoutPoint(paintOffset.x() + xPositionForFloatIncludingMargin(r) - r->renderer()->x(), paintOffset.y() + yPositionForFloatIncludingMargin(r) - r->renderer()->y()));
2606             r->renderer()->paint(currentPaintInfo, childPoint);
2607             if (!preservePhase) {
2608                 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
2609                 r->renderer()->paint(currentPaintInfo, childPoint);
2610                 currentPaintInfo.phase = PaintPhaseFloat;
2611                 r->renderer()->paint(currentPaintInfo, childPoint);
2612                 currentPaintInfo.phase = PaintPhaseForeground;
2613                 r->renderer()->paint(currentPaintInfo, childPoint);
2614                 currentPaintInfo.phase = PaintPhaseOutline;
2615                 r->renderer()->paint(currentPaintInfo, childPoint);
2616             }
2617         }
2618     }
2619 }
2620
2621 RenderInline* RenderBlock::inlineElementContinuation() const
2622
2623     RenderBoxModelObject* continuation = this->continuation();
2624     return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
2625 }
2626
2627 RenderBlock* RenderBlock::blockElementContinuation() const
2628 {
2629     RenderBoxModelObject* currentContinuation = continuation();
2630     if (!currentContinuation || currentContinuation->isInline())
2631         return 0;
2632     RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
2633     if (nextContinuation->isAnonymousBlock())
2634         return nextContinuation->blockElementContinuation();
2635     return nextContinuation;
2636 }
2637     
2638 static ContinuationOutlineTableMap* continuationOutlineTable()
2639 {
2640     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
2641     return &table;
2642 }
2643
2644 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
2645 {
2646     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
2647     // way of painting.
2648     ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
2649     
2650     ContinuationOutlineTableMap* table = continuationOutlineTable();
2651     ListHashSet<RenderInline*>* continuations = table->get(this);
2652     if (!continuations) {
2653         continuations = new ListHashSet<RenderInline*>;
2654         table->set(this, adoptPtr(continuations));
2655     }
2656     
2657     continuations->add(flow);
2658 }
2659
2660 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
2661 {
2662     ContinuationOutlineTableMap* table = continuationOutlineTable();
2663     if (table->isEmpty())
2664         return false;
2665         
2666     ListHashSet<RenderInline*>* continuations = table->get(this);
2667     if (!continuations)
2668         return false;
2669
2670     return continuations->contains(flow);
2671 }
2672
2673 void RenderBlock::paintContinuationOutlines(PaintInfo& info, const LayoutPoint& paintOffset)
2674 {
2675     ContinuationOutlineTableMap* table = continuationOutlineTable();
2676     if (table->isEmpty())
2677         return;
2678         
2679     OwnPtr<ListHashSet<RenderInline*> > continuations = table->take(this);
2680     if (!continuations)
2681         return;
2682
2683     LayoutPoint accumulatedPaintOffset = paintOffset;
2684     // Paint each continuation outline.
2685     ListHashSet<RenderInline*>::iterator end = continuations->end();
2686     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
2687         // Need to add in the coordinates of the intervening blocks.
2688         RenderInline* flow = *it;
2689         RenderBlock* block = flow->containingBlock();
2690         for ( ; block && block != this; block = block->containingBlock())
2691             accumulatedPaintOffset.moveBy(block->location());
2692         ASSERT(block);   
2693         flow->paintOutline(info, accumulatedPaintOffset);
2694     }
2695 }
2696
2697 bool RenderBlock::shouldPaintSelectionGaps() const
2698 {
2699     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
2700 }
2701
2702 bool RenderBlock::isSelectionRoot() const
2703 {
2704     if (isPseudoElement())
2705         return false;
2706     ASSERT(element() || isAnonymous());
2707         
2708     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
2709     if (isTable())
2710         return false;
2711         
2712     if (isBody() || isRoot() || hasOverflowClip()
2713         || isPositioned() || isFloating()
2714         || isTableCell() || isInlineBlockOrInlineTable()
2715         || hasTransform() || hasReflection() || hasMask() || isWritingModeRoot()
2716         || isRenderFlowThread())
2717         return true;
2718     
2719     if (view().selectionStart()) {
2720         Node* startElement = view().selectionStart()->node();
2721         if (startElement && startElement->rootEditableElement() == element())
2722             return true;
2723     }
2724     
2725     return false;
2726 }
2727
2728 GapRects RenderBlock::selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer)
2729 {
2730     ASSERT(!needsLayout());
2731
2732     if (!shouldPaintSelectionGaps())
2733         return GapRects();
2734
2735     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
2736     mapLocalToContainer(repaintContainer, transformState, ApplyContainerFlip | UseTransforms);
2737     LayoutPoint offsetFromRepaintContainer = roundedLayoutPoint(transformState.mappedPoint());
2738
2739     if (hasOverflowClip())
2740         offsetFromRepaintContainer -= scrolledContentOffset();
2741
2742     LogicalSelectionOffsetCaches cache(this);
2743     LayoutUnit lastTop = 0;
2744     LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop, cache);
2745     LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop, cache);
2746     
2747     return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight, cache);
2748 }
2749
2750 void RenderBlock::paintSelection(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2751 {
2752     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
2753         LogicalSelectionOffsetCaches cache(this);
2754         LayoutUnit lastTop = 0;
2755         LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop, cache);
2756         LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop, cache);
2757         GraphicsContextStateSaver stateSaver(*paintInfo.context);
2758
2759         LayoutRect gapRectsBounds = selectionGaps(this, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight, cache, &paintInfo);
2760         if (!gapRectsBounds.isEmpty()) {
2761             if (RenderLayer* layer = enclosingLayer()) {
2762                 gapRectsBounds.moveBy(-paintOffset);
2763                 if (!hasLayer()) {
2764                     LayoutRect localBounds(gapRectsBounds);
2765                     flipForWritingMode(localBounds);
2766                     gapRectsBounds = localToContainerQuad(FloatRect(localBounds), &layer->renderer()).enclosingBoundingBox();
2767                     if (layer->renderer().hasOverflowClip())
2768                         gapRectsBounds.move(layer->renderBox()->scrolledContentOffset());
2769                 }
2770                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
2771             }
2772         }
2773     }
2774 }
2775
2776 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, TrackedRendererListHashSet* positionedObjects)
2777 {
2778     if (!positionedObjects)
2779         return;
2780     
2781     TrackedRendererListHashSet::const_iterator end = positionedObjects->end();
2782     for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
2783         RenderBox* r = *it;
2784         paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
2785     }
2786 }
2787
2788 static LayoutUnit blockDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
2789 {
2790     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
2791 }
2792
2793 static LayoutUnit inlineDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
2794 {
2795     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
2796 }
2797
2798 LayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPhysicalPosition, const LayoutRect& logicalRect)
2799 {
2800     LayoutRect result;
2801     if (isHorizontalWritingMode())
2802         result = logicalRect;
2803     else
2804         result = LayoutRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
2805     flipForWritingMode(result);
2806     result.moveBy(rootBlockPhysicalPosition);
2807     return result;
2808 }
2809
2810 GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2811     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
2812 {
2813     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
2814     // Clip out floating and positioned objects when painting selection gaps.
2815     if (paintInfo) {
2816         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
2817         LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
2818         rootBlock->flipForWritingMode(flippedBlockRect);
2819         flippedBlockRect.moveBy(rootBlockPhysicalPosition);
2820         clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positionedObjects());
2821         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
2822             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
2823                 clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->positionedObjects()); // FIXME: Not right for flipped writing modes.
2824         if (m_floatingObjects) {
2825             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2826             FloatingObjectSetIterator end = floatingObjectSet.end();
2827             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
2828                 FloatingObject* r = *it;
2829                 LayoutRect floatBox(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
2830                                     offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
2831                                     r->renderer()->width(), r->renderer()->height());
2832                 rootBlock->flipForWritingMode(floatBox);
2833                 floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
2834                 paintInfo->context->clipOut(pixelSnappedIntRect(floatBox));
2835             }
2836         }
2837     }
2838
2839     // 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
2840     // fixed).
2841     GapRects result;
2842     if (!isRenderBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
2843         return result;
2844
2845     if (hasColumns() || hasTransform() || style()->columnSpan()) {
2846         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
2847         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
2848         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight(), cache);
2849         lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(), cache);
2850         return result;
2851     }
2852
2853     if (childrenInline())
2854         result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, cache, paintInfo);
2855     else
2856         result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, cache, paintInfo);
2857
2858     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
2859     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd)) {
2860         result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
2861             lastLogicalTop, lastLogicalLeft, lastLogicalRight, logicalHeight(), cache, paintInfo));
2862     }
2863
2864     return result;
2865 }
2866
2867 GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2868     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
2869 {
2870     GapRects result;
2871
2872     bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
2873
2874     if (!firstLineBox()) {
2875         if (containsStart) {
2876             // Go ahead and update our lastLogicalTop to be the bottom of the block.  <hr>s or empty blocks with height can trip this
2877             // case.
2878             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
2879             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight(), cache);
2880             lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(), cache);
2881         }
2882         return result;
2883     }
2884
2885     RootInlineBox* lastSelectedLine = 0;
2886     RootInlineBox* curr;
2887     for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
2888
2889     // Now paint the gaps for the lines.
2890     for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
2891         LayoutUnit selTop =  curr->selectionTopAdjustedForPrecedingBlock();
2892         LayoutUnit selHeight = curr->selectionHeightAdjustedForPrecedingBlock();
2893
2894         if (!containsStart && !lastSelectedLine &&
2895             selectionState() != SelectionStart && selectionState() != SelectionBoth)
2896             result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, selTop, cache, paintInfo));
2897         
2898         LayoutRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
2899         logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : offsetFromRootBlock.transposedSize());
2900         LayoutRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
2901         if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
2902             || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
2903             result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, cache, paintInfo));
2904
2905         lastSelectedLine = curr;
2906     }
2907
2908     if (containsStart && !lastSelectedLine)
2909         // VisibleSelection must start just after our last line.
2910         lastSelectedLine = lastRootBox();
2911
2912     if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
2913         // Go ahead and update our lastY to be the bottom of the last selected line.
2914         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
2915         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom(), cache);
2916         lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom(), cache);
2917     }
2918     return result;
2919 }
2920
2921 GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2922     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
2923 {
2924     GapRects result;
2925
2926     // Go ahead and jump right to the first block child that contains some selected objects.
2927     RenderBox* curr;
2928     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
2929     
2930     if (!curr)
2931         return result;
2932
2933     LogicalSelectionOffsetCaches childCache(this, cache);
2934
2935     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
2936         SelectionState childState = curr->selectionState();
2937         if (childState == SelectionBoth || childState == SelectionEnd)
2938             sawSelectionEnd = true;
2939
2940         if (curr->isFloatingOrOutOfFlowPositioned())
2941             continue; // We must be a normal flow object in order to even be considered.
2942
2943         if (curr->isInFlowPositioned() && curr->hasLayer()) {
2944             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
2945             // Just disregard it completely.
2946             LayoutSize relOffset = curr->layer()->offsetForInFlowPosition();
2947             if (relOffset.width() || relOffset.height())
2948                 continue;
2949         }
2950
2951         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
2952         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
2953         if (fillBlockGaps) {
2954             // We need to fill the vertical gap above this object.
2955             if (childState == SelectionEnd || childState == SelectionInside) {
2956                 // Fill the gap above the object.
2957                 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
2958                     lastLogicalTop, lastLogicalLeft, lastLogicalRight, curr->logicalTop(), cache, paintInfo));
2959             }
2960
2961             // 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*
2962             // our object.  We know this if the selection did not end inside our object.
2963             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
2964                 childState = SelectionNone;
2965
2966             // Fill side gaps on this object based off its state.
2967             bool leftGap, rightGap;
2968             getSelectionGapInfo(childState, leftGap, rightGap);
2969
2970             if (leftGap)
2971                 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), cache, paintInfo));
2972             if (rightGap)
2973                 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), cache, paintInfo));
2974
2975             // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
2976             // they can without bumping into floating or positioned objects.  Ideally they will go right up
2977             // to the border of the root selection block.
2978             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
2979             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom(), cache);
2980             lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom(), cache);
2981         } else if (childState != SelectionNone) {
2982             // We must be a block that has some selected object inside it.  Go ahead and recur.
2983             result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()), 
2984                 lastLogicalTop, lastLogicalLeft, lastLogicalRight, childCache, paintInfo));
2985         }
2986     }
2987     return result;
2988 }
2989
2990 LayoutRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2991     LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
2992 {
2993     LayoutUnit logicalTop = lastLogicalTop;
2994     LayoutUnit logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
2995     if (logicalHeight <= 0)
2996         return LayoutRect();
2997
2998     // Get the selection offsets for the bottom of the gap
2999     LayoutUnit logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom, cache));
3000     LayoutUnit logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom, cache));
3001     LayoutUnit logicalWidth = logicalRight - logicalLeft;
3002     if (logicalWidth <= 0)
3003         return LayoutRect();
3004
3005     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
3006     if (paintInfo)
3007         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selectionBackgroundColor(), style()->colorSpace());
3008     return gapRect;
3009 }
3010
3011 LayoutRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
3012     RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
3013 {
3014     LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
3015     LayoutUnit rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop, cache), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight, cache));
3016     LayoutUnit rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalLeft),
3017         min(logicalRightSelectionOffset(rootBlock, logicalTop, cache), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight, cache)));
3018     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
3019     if (rootBlockLogicalWidth <= 0)
3020         return LayoutRect();
3021
3022     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
3023     if (paintInfo)
3024         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
3025     return gapRect;
3026 }
3027
3028 LayoutRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
3029     RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
3030 {
3031     LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
3032     LayoutUnit rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalRight),
3033         max(logicalLeftSelectionOffset(rootBlock, logicalTop, cache), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight, cache)));
3034     LayoutUnit rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop, cache), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight, cache));
3035     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
3036     if (rootBlockLogicalWidth <= 0)
3037         return LayoutRect();
3038
3039     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
3040     if (paintInfo)
3041         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
3042     return gapRect;
3043 }
3044
3045 void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
3046 {
3047     bool ltr = style()->isLeftToRightDirection();
3048     leftGap = (state == RenderObject::SelectionInside) ||
3049               (state == RenderObject::SelectionEnd && ltr) ||
3050               (state == RenderObject::SelectionStart && !ltr);
3051     rightGap = (state == RenderObject::SelectionInside) ||
3052                (state == RenderObject::SelectionStart && ltr) ||
3053                (state == RenderObject::SelectionEnd && !ltr);
3054 }
3055
3056 LayoutUnit RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches& cache)
3057 {
3058     LayoutUnit logicalLeft = logicalLeftOffsetForLine(position, false);
3059     if (logicalLeft == logicalLeftOffsetForContent()) {
3060         if (rootBlock != this) // The border can potentially be further extended by our containingBlock().
3061             return cache.containingBlockInfo(this).logicalLeftSelectionOffset(rootBlock, position + logicalTop());
3062         return logicalLeft;
3063     } else {
3064         RenderBlock* cb = this;
3065         const LogicalSelectionOffsetCaches* currentCache = &cache;
3066         while (cb != rootBlock) {
3067             logicalLeft += cb->logicalLeft();
3068
3069             ASSERT(currentCache);
3070             const LogicalSelectionOffsetCaches::ContainingBlockInfo& info = currentCache->containingBlockInfo(cb);
3071             cb = info.block();
3072             currentCache = info.cache();
3073         }
3074     }
3075     return logicalLeft;
3076 }
3077
3078 LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches& cache)
3079 {
3080     LayoutUnit logicalRight = logicalRightOffsetForLine(position, false);
3081     if (logicalRight == logicalRightOffsetForContent()) {
3082         if (rootBlock != this) // The border can potentially be further extended by our containingBlock().
3083             return cache.containingBlockInfo(this).logicalRightSelectionOffset(rootBlock, position + logicalTop());
3084         return logicalRight;
3085     } else {
3086         RenderBlock* cb = this;
3087         const LogicalSelectionOffsetCaches* currentCache = &cache;
3088         while (cb != rootBlock) {
3089             logicalRight += cb->logicalLeft();
3090
3091             ASSERT(currentCache);
3092             const LogicalSelectionOffsetCaches::ContainingBlockInfo& info = currentCache->containingBlockInfo(cb);
3093             cb = info.block();
3094             currentCache = info.cache();
3095         }
3096     }
3097     return logicalRight;
3098 }
3099
3100 RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
3101 {
3102     if (isSelectionRoot())
3103         return 0;
3104
3105     const RenderObject* object = this;
3106     RenderObject* sibling;
3107     do {
3108         sibling = object->previousSibling();
3109         while (sibling && (!sibling->isRenderBlock() || toRenderBlock(sibling)->isSelectionRoot()))
3110             sibling = sibling->previousSibling();
3111
3112         offset -= LayoutSize(toRenderBlock(object)->logicalLeft(), toRenderBlock(object)->logicalTop());
3113         object = object->parent();
3114     } while (!sibling && object && object->isRenderBlock() && !toRenderBlock(object)->isSelectionRoot());
3115
3116     if (!sibling)
3117         return 0;
3118
3119     RenderBlock* beforeBlock = toRenderBlock(sibling);
3120
3121     offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
3122
3123     RenderObject* child = beforeBlock->lastChild();
3124     while (child && child->isRenderBlock()) {
3125         beforeBlock = toRenderBlock(child);
3126         offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
3127         child = beforeBlock->lastChild();
3128     }
3129     return beforeBlock;
3130 }
3131
3132 void RenderBlock::insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
3133 {
3134     if (!descendantsMap) {
3135         descendantsMap = new TrackedDescendantsMap;
3136         containerMap = new TrackedContainerMap;
3137     }
3138     
3139     TrackedRendererListHashSet* descendantSet = descendantsMap->get(this);
3140     if (!descendantSet) {
3141         descendantSet = new TrackedRendererListHashSet;
3142         descendantsMap->set(this, adoptPtr(descendantSet));
3143     }
3144     bool added = descendantSet->add(descendant).isNewEntry;
3145     if (!added) {
3146         ASSERT(containerMap->get(descendant));
3147         ASSERT(containerMap->get(descendant)->contains(this));
3148         return;
3149     }
3150     
3151     HashSet<RenderBlock*>* containerSet = containerMap->get(descendant);
3152     if (!containerSet) {
3153         containerSet = new HashSet<RenderBlock*>;
3154         containerMap->set(descendant, adoptPtr(containerSet));
3155     }
3156     ASSERT(!containerSet->contains(this));
3157     containerSet->add(this);
3158 }
3159
3160 void RenderBlock::removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
3161 {
3162     if (!descendantsMap)
3163         return;
3164     
3165     OwnPtr<HashSet<RenderBlock*> > containerSet = containerMap->take(descendant);
3166     if (!containerSet)
3167         return;
3168     
3169     HashSet<RenderBlock*>::iterator end = containerSet->end();
3170     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
3171         RenderBlock* container = *it;
3172
3173         // FIXME: Disabling this assert temporarily until we fix the layout
3174         // bugs associated with positioned objects not properly cleared from
3175         // their ancestor chain before being moved. See webkit bug 93766.
3176         // ASSERT(descendant->isDescendantOf(container));
3177
3178         TrackedDescendantsMap::iterator descendantsMapIterator = descendantsMap->find(container);
3179         ASSERT(descendantsMapIterator != descendantsMap->end());
3180         if (descendantsMapIterator == descendantsMap->end())
3181             continue;
3182         TrackedRendererListHashSet* descendantSet = descendantsMapIterator->value.get();
3183         ASSERT(descendantSet->contains(descendant));
3184         descendantSet->remove(descendant);
3185         if (descendantSet->isEmpty())
3186             descendantsMap->remove(descendantsMapIterator);
3187     }
3188 }
3189
3190 TrackedRendererListHashSet* RenderBlock::positionedObjects() const
3191 {
3192     if (gPositionedDescendantsMap)
3193         return gPositionedDescendantsMap->get(this);
3194     return 0;
3195 }
3196
3197 void RenderBlock::insertPositionedObject(RenderBox* o)
3198 {
3199     ASSERT(!isAnonymousBlock());
3200
3201     if (o->isRenderFlowThread())
3202         return;
3203     
3204     insertIntoTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
3205 }
3206
3207 void RenderBlock::removePositionedObject(RenderBox* o)
3208 {
3209     removeFromTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
3210 }
3211
3212 void RenderBlock::removePositionedObjects(RenderBlock* o, ContainingBlockState containingBlockState)
3213 {
3214     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
3215     if (!positionedDescendants)
3216         return;
3217     
3218     RenderBox* r;
3219     
3220     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
3221     
3222     Vector<RenderBox*, 16> deadObjects;
3223
3224     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
3225         r = *it;
3226         if (!o || r->isDescendantOf(o)) {
3227             if (containingBlockState == NewContainingBlock)
3228                 r->setChildNeedsLayout(true, MarkOnlyThis);
3229             
3230             // It is parent blocks job to add positioned child to positioned objects list of its containing block
3231             // Parent layout needs to be invalidated to ensure this happens.
3232             RenderObject* p = r->parent();
3233             while (p && !p->isRenderBlock())
3234                 p = p->parent();
3235             if (p)
3236                 p->setChildNeedsLayout(true);
3237             
3238             deadObjects.append(r);
3239         }
3240     }
3241     
3242     for (unsigned i = 0; i < deadObjects.size(); i++)
3243         removePositionedObject(deadObjects.at(i));
3244 }
3245
3246 void RenderBlock::removeFloatingObjects()
3247 {
3248     if (!m_floatingObjects)
3249         return;
3250
3251     m_floatingObjects->clear();
3252 }
3253
3254 FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
3255 {
3256     ASSERT(o->isFloating());
3257
3258     // Create the list of special objects if we don't aleady have one
3259     if (!m_floatingObjects)
3260         createFloatingObjects();
3261     else {
3262         // Don't insert the object again if it's already in the list