Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / 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 "core/rendering/RenderBlock.h"
26
27 #include "HTMLNames.h"
28 #include "core/accessibility/AXObjectCache.h"
29 #include "core/dom/Document.h"
30 #include "core/dom/Element.h"
31 #include "core/events/OverflowEvent.h"
32 #include "core/dom/shadow/ShadowRoot.h"
33 #include "core/editing/Editor.h"
34 #include "core/editing/FrameSelection.h"
35 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
36 #include "core/frame/FrameView.h"
37 #include "core/frame/LocalFrame.h"
38 #include "core/page/Page.h"
39 #include "core/frame/Settings.h"
40 #include "core/rendering/FastTextAutosizer.h"
41 #include "core/rendering/GraphicsContextAnnotator.h"
42 #include "core/rendering/HitTestLocation.h"
43 #include "core/rendering/HitTestResult.h"
44 #include "core/rendering/InlineIterator.h"
45 #include "core/rendering/InlineTextBox.h"
46 #include "core/rendering/LayoutRepainter.h"
47 #include "core/rendering/PaintInfo.h"
48 #include "core/rendering/RenderCombineText.h"
49 #include "core/rendering/RenderDeprecatedFlexibleBox.h"
50 #include "core/rendering/RenderFlexibleBox.h"
51 #include "core/rendering/RenderFlowThread.h"
52 #include "core/rendering/RenderInline.h"
53 #include "core/rendering/RenderLayer.h"
54 #include "core/rendering/RenderMarquee.h"
55 #include "core/rendering/RenderRegion.h"
56 #include "core/rendering/RenderTableCell.h"
57 #include "core/rendering/RenderTextControl.h"
58 #include "core/rendering/RenderTextFragment.h"
59 #include "core/rendering/RenderTheme.h"
60 #include "core/rendering/RenderView.h"
61 #include "core/rendering/shapes/ShapeOutsideInfo.h"
62 #include "core/rendering/style/ContentData.h"
63 #include "core/rendering/style/RenderStyle.h"
64 #include "platform/geometry/FloatQuad.h"
65 #include "platform/geometry/TransformState.h"
66 #include "platform/graphics/GraphicsContextCullSaver.h"
67 #include "platform/graphics/GraphicsContextStateSaver.h"
68 #include "wtf/StdLibExtras.h"
69 #include "wtf/TemporaryChange.h"
70
71 using namespace std;
72 using namespace WTF;
73 using namespace Unicode;
74
75 namespace WebCore {
76
77 using namespace HTMLNames;
78
79 struct SameSizeAsRenderBlock : public RenderBox {
80     void* pointers[1];
81     RenderObjectChildList children;
82     RenderLineBoxList lineBoxes;
83     uint32_t bitfields;
84 };
85
86 struct SameSizeAsRenderBlockRareData {
87     int paginationStrut;
88     int pageLogicalOffset;
89     uint32_t bitfields;
90 };
91
92 COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock_should_stay_small);
93 COMPILE_ASSERT(sizeof(RenderBlock::RenderBlockRareData) == sizeof(SameSizeAsRenderBlockRareData), RenderBlockRareData_should_stay_small);
94
95 typedef WTF::HashMap<const RenderBox*, OwnPtr<ColumnInfo> > ColumnInfoMap;
96 static ColumnInfoMap* gColumnInfoMap = 0;
97
98 static TrackedDescendantsMap* gPositionedDescendantsMap = 0;
99 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0;
100
101 static TrackedContainerMap* gPositionedContainerMap = 0;
102 static TrackedContainerMap* gPercentHeightContainerMap = 0;
103
104 typedef WTF::HashMap<RenderBlock*, OwnPtr<ListHashSet<RenderInline*> > > ContinuationOutlineTableMap;
105
106 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
107 static int gDelayUpdateScrollInfo = 0;
108 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
109
110 static bool gColumnFlowSplitEnabled = true;
111
112 // This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code
113 // only works on RenderBlocks. If this changes, this class should be shared with other RenderBoxes.
114 class OverflowEventDispatcher {
115     WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher);
116 public:
117     OverflowEventDispatcher(const RenderBlock* block)
118         : m_block(block)
119         , m_hadHorizontalLayoutOverflow(false)
120         , m_hadVerticalLayoutOverflow(false)
121     {
122         m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowClip() && m_block->document().hasListenerType(Document::OVERFLOWCHANGED_LISTENER);
123         if (m_shouldDispatchEvent) {
124             m_hadHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
125             m_hadVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
126         }
127     }
128
129     ~OverflowEventDispatcher()
130     {
131         if (!m_shouldDispatchEvent)
132             return;
133
134         bool hasHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
135         bool hasVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
136
137         bool horizontalLayoutOverflowChanged = hasHorizontalLayoutOverflow != m_hadHorizontalLayoutOverflow;
138         bool verticalLayoutOverflowChanged = hasVerticalLayoutOverflow != m_hadVerticalLayoutOverflow;
139
140         if (!horizontalLayoutOverflowChanged && !verticalLayoutOverflowChanged)
141             return;
142
143         RefPtrWillBeRawPtr<OverflowEvent> event = OverflowEvent::create(horizontalLayoutOverflowChanged, hasHorizontalLayoutOverflow, verticalLayoutOverflowChanged, hasVerticalLayoutOverflow);
144         event->setTarget(m_block->node());
145         m_block->document().enqueueAnimationFrameEvent(event.release());
146     }
147
148 private:
149     const RenderBlock* m_block;
150     bool m_shouldDispatchEvent;
151     bool m_hadHorizontalLayoutOverflow;
152     bool m_hadVerticalLayoutOverflow;
153 };
154
155 RenderBlock::RenderBlock(ContainerNode* node)
156     : RenderBox(node)
157     , m_lineHeight(-1)
158     , m_hasMarginBeforeQuirk(false)
159     , m_hasMarginAfterQuirk(false)
160     , m_beingDestroyed(false)
161     , m_hasMarkupTruncation(false)
162     , m_hasBorderOrPaddingLogicalWidthChanged(false)
163     , m_hasOnlySelfCollapsingChildren(false)
164 {
165     setChildrenInline(true);
166 }
167
168 static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
169 {
170     if (OwnPtr<TrackedRendererListHashSet> descendantSet = descendantMap->take(block)) {
171         TrackedRendererListHashSet::iterator end = descendantSet->end();
172         for (TrackedRendererListHashSet::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
173             TrackedContainerMap::iterator it = containerMap->find(*descendant);
174             ASSERT(it != containerMap->end());
175             if (it == containerMap->end())
176                 continue;
177             HashSet<RenderBlock*>* containerSet = it->value.get();
178             ASSERT(containerSet->contains(block));
179             containerSet->remove(block);
180             if (containerSet->isEmpty())
181                 containerMap->remove(it);
182         }
183     }
184 }
185
186 static void appendImageIfNotNull(Vector<ImageResource*>& imageResources, const StyleImage* styleImage)
187 {
188     if (styleImage && styleImage->cachedImage()) {
189         ImageResource* imageResource = styleImage->cachedImage();
190         if (imageResource && !imageResource->isLoaded())
191             imageResources.append(styleImage->cachedImage());
192     }
193 }
194
195 static void appendLayers(Vector<ImageResource*>& images, const FillLayer* styleLayer)
196 {
197     for (const FillLayer* layer = styleLayer; layer; layer = layer->next()) {
198         appendImageIfNotNull(images, layer->image());
199     }
200 }
201
202 static void appendImagesFromStyle(Vector<ImageResource*>& images, RenderStyle& blockStyle)
203 {
204     appendLayers(images, blockStyle.backgroundLayers());
205     appendLayers(images, blockStyle.maskLayers());
206
207     const ContentData* contentData = blockStyle.contentData();
208     if (contentData && contentData->isImage()) {
209         const ImageContentData* imageContentData = static_cast<const ImageContentData*>(contentData);
210         appendImageIfNotNull(images, imageContentData->image());
211     }
212     if (blockStyle.boxReflect())
213         appendImageIfNotNull(images, blockStyle.boxReflect()->mask().image());
214     appendImageIfNotNull(images, blockStyle.listStyleImage());
215     appendImageIfNotNull(images, blockStyle.borderImageSource());
216     appendImageIfNotNull(images, blockStyle.maskBoxImageSource());
217     if (blockStyle.shapeOutside())
218         appendImageIfNotNull(images, blockStyle.shapeOutside()->image());
219 }
220
221 RenderBlock::~RenderBlock()
222 {
223     if (hasColumns())
224         gColumnInfoMap->take(this);
225     if (gPercentHeightDescendantsMap)
226         removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
227     if (gPositionedDescendantsMap)
228         removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap);
229 }
230
231 void RenderBlock::willBeDestroyed()
232 {
233     // Mark as being destroyed to avoid trouble with merges in removeChild().
234     m_beingDestroyed = true;
235
236     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
237     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
238     children()->destroyLeftoverChildren();
239
240     // Destroy our continuation before anything other than anonymous children.
241     // The reason we don't destroy it before anonymous children is that they may
242     // have continuations of their own that are anonymous children of our continuation.
243     RenderBoxModelObject* continuation = this->continuation();
244     if (continuation) {
245         continuation->destroy();
246         setContinuation(0);
247     }
248
249     if (!documentBeingDestroyed()) {
250         if (firstLineBox()) {
251             // We can't wait for RenderBox::destroy to clear the selection,
252             // because by then we will have nuked the line boxes.
253             // FIXME: The FrameSelection should be responsible for this when it
254             // is notified of DOM mutations.
255             if (isSelectionBorder())
256                 view()->clearSelection();
257
258             // If we are an anonymous block, then our line boxes might have children
259             // that will outlast this block. In the non-anonymous block case those
260             // children will be destroyed by the time we return from this function.
261             if (isAnonymousBlock()) {
262                 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
263                     while (InlineBox* childBox = box->firstChild())
264                         childBox->remove();
265                 }
266             }
267         } else if (parent())
268             parent()->dirtyLinesFromChangedChild(this);
269     }
270
271     m_lineBoxes.deleteLineBoxes();
272
273     if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0))
274         gDelayedUpdateScrollInfoSet->remove(this);
275
276     if (FastTextAutosizer* textAutosizer = document().fastTextAutosizer())
277         textAutosizer->destroy(this);
278
279     RenderBox::willBeDestroyed();
280 }
281
282 void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
283 {
284     RenderStyle* oldStyle = style();
285
286     setReplaced(newStyle.isDisplayInlineType());
287
288     if (oldStyle && parent() && diff.needsFullLayout() && oldStyle->position() != newStyle.position()) {
289         if (newStyle.position() == StaticPosition)
290             // Clear our positioned objects list. Our absolutely positioned descendants will be
291             // inserted into our containing block's positioned objects list during layout.
292             removePositionedObjects(0, NewContainingBlock);
293         else if (oldStyle->position() == StaticPosition) {
294             // Remove our absolutely positioned descendants from their current containing block.
295             // They will be inserted into our positioned objects list during layout.
296             RenderObject* cb = parent();
297             while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
298                 if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
299                     cb = cb->containingBlock();
300                     break;
301                 }
302                 cb = cb->parent();
303             }
304
305             if (cb->isRenderBlock())
306                 toRenderBlock(cb)->removePositionedObjects(this, NewContainingBlock);
307         }
308     }
309
310     RenderBox::styleWillChange(diff, newStyle);
311 }
312
313 static bool borderOrPaddingLogicalWidthChanged(const RenderStyle* oldStyle, const RenderStyle* newStyle)
314 {
315     if (newStyle->isHorizontalWritingMode())
316         return oldStyle->borderLeftWidth() != newStyle->borderLeftWidth()
317             || oldStyle->borderRightWidth() != newStyle->borderRightWidth()
318             || oldStyle->paddingLeft() != newStyle->paddingLeft()
319             || oldStyle->paddingRight() != newStyle->paddingRight();
320
321     return oldStyle->borderTopWidth() != newStyle->borderTopWidth()
322         || oldStyle->borderBottomWidth() != newStyle->borderBottomWidth()
323         || oldStyle->paddingTop() != newStyle->paddingTop()
324         || oldStyle->paddingBottom() != newStyle->paddingBottom();
325 }
326
327 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
328 {
329     RenderBox::styleDidChange(diff, oldStyle);
330
331     RenderStyle* newStyle = style();
332
333     if (!isAnonymousBlock()) {
334         // Ensure that all of our continuation blocks pick up the new style.
335         for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
336             RenderBoxModelObject* nextCont = currCont->continuation();
337             currCont->setContinuation(0);
338             currCont->setStyle(newStyle);
339             currCont->setContinuation(nextCont);
340         }
341     }
342
343     if (FastTextAutosizer* textAutosizer = document().fastTextAutosizer())
344         textAutosizer->record(this);
345
346     propagateStyleToAnonymousChildren(true);
347     invalidateLineHeight();
348
349     // It's possible for our border/padding to change, but for the overall logical width of the block to
350     // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
351     m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff.needsFullLayout() && needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, newStyle);
352
353     // If the style has unloaded images, want to notify the ResourceLoadPriorityOptimizer so that
354     // network priorities can be set.
355     Vector<ImageResource*> images;
356     appendImagesFromStyle(images, *newStyle);
357     if (images.isEmpty())
358         ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->removeRenderObject(this);
359     else
360         ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->addRenderObject(this);
361 }
362
363 void RenderBlock::repaintTreeAfterLayout()
364 {
365     if (!shouldCheckForInvalidationAfterLayout())
366         return;
367
368     RenderBox::repaintTreeAfterLayout();
369
370     // Take care of positioned objects. This is required as LayoutState keeps a single clip rect.
371     if (TrackedRendererListHashSet* positionedObjects = this->positionedObjects()) {
372         TrackedRendererListHashSet::iterator end = positionedObjects->end();
373         LayoutStateMaintainer statePusher(*this, isTableRow() ? LayoutSize() : locationOffset());
374         for (TrackedRendererListHashSet::iterator it = positionedObjects->begin(); it != end; ++it)
375             (*it)->repaintTreeAfterLayout();
376     }
377 }
378
379 RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
380 {
381     if (beforeChild && beforeChild->parent() == this)
382         return this;
383
384     RenderBlock* curr = toRenderBlock(continuation());
385     RenderBlock* nextToLast = this;
386     RenderBlock* last = this;
387     while (curr) {
388         if (beforeChild && beforeChild->parent() == curr) {
389             if (curr->firstChild() == beforeChild)
390                 return last;
391             return curr;
392         }
393
394         nextToLast = last;
395         last = curr;
396         curr = toRenderBlock(curr->continuation());
397     }
398
399     if (!beforeChild && !last->firstChild())
400         return nextToLast;
401     return last;
402 }
403
404 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
405 {
406     RenderBlock* flow = continuationBefore(beforeChild);
407     ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
408     RenderBoxModelObject* beforeChildParent = 0;
409     if (beforeChild)
410         beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
411     else {
412         RenderBoxModelObject* cont = flow->continuation();
413         if (cont)
414             beforeChildParent = cont;
415         else
416             beforeChildParent = flow;
417     }
418
419     if (newChild->isFloatingOrOutOfFlowPositioned()) {
420         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
421         return;
422     }
423
424     // A continuation always consists of two potential candidates: a block or an anonymous
425     // column span box holding column span children.
426     bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
427     bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
428     bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
429
430     if (flow == beforeChildParent) {
431         flow->addChildIgnoringContinuation(newChild, beforeChild);
432         return;
433     }
434
435     // The goal here is to match up if we can, so that we can coalesce and create the
436     // minimal # of continuations needed for the inline.
437     if (childIsNormal == bcpIsNormal) {
438         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
439         return;
440     }
441     if (flowIsNormal == childIsNormal) {
442         flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
443         return;
444     }
445     beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
446 }
447
448
449 void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
450 {
451     ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
452
453     // The goal is to locate a suitable box in which to place our child.
454     RenderBlock* beforeChildParent = 0;
455     if (beforeChild) {
456         RenderObject* curr = beforeChild;
457         while (curr && curr->parent() != this)
458             curr = curr->parent();
459         beforeChildParent = toRenderBlock(curr);
460         ASSERT(beforeChildParent);
461         ASSERT(beforeChildParent->isAnonymousColumnsBlock() || beforeChildParent->isAnonymousColumnSpanBlock());
462     } else
463         beforeChildParent = toRenderBlock(lastChild());
464
465     // If the new child is floating or positioned it can just go in that block.
466     if (newChild->isFloatingOrOutOfFlowPositioned()) {
467         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
468         return;
469     }
470
471     // See if the child can be placed in the box.
472     bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline();
473     bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
474
475     if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) {
476         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
477         return;
478     }
479
480     if (!beforeChild) {
481         // Create a new block of the correct type.
482         RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
483         children()->appendChildNode(this, newBox);
484         newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
485         return;
486     }
487
488     RenderObject* immediateChild = beforeChild;
489     bool isPreviousBlockViable = true;
490     while (immediateChild->parent() != this) {
491         if (isPreviousBlockViable)
492             isPreviousBlockViable = !immediateChild->previousSibling();
493         immediateChild = immediateChild->parent();
494     }
495     if (isPreviousBlockViable && immediateChild->previousSibling()) {
496         toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
497         return;
498     }
499
500     // Split our anonymous blocks.
501     RenderObject* newBeforeChild = splitAnonymousBoxesAroundChild(beforeChild);
502
503
504     // Create a new anonymous box of the appropriate type.
505     RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
506     children()->insertChildNode(this, newBox, newBeforeChild);
507     newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
508     return;
509 }
510
511 RenderBlockFlow* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
512 {
513     RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
514     for (RenderObject* curr = this; curr; curr = curr->parent()) {
515         if (!curr->isRenderBlock() || curr->isFloatingOrOutOfFlowPositioned() || curr->isTableCell() || curr->isDocumentElement() || curr->isRenderView() || curr->hasOverflowClip()
516             || curr->isInlineBlockOrInlineTable())
517             return 0;
518
519         // FIXME: Renderers that do special management of their children (tables, buttons,
520         // lists, flexboxes, etc.) breaks when the flow is split through them. Disabling
521         // multi-column for them to avoid this problem.)
522         if (!curr->isRenderBlockFlow() || curr->isListItem())
523             return 0;
524
525         RenderBlockFlow* currBlock = toRenderBlockFlow(curr);
526         if (!currBlock->createsAnonymousWrapper())
527             firstChildIgnoringAnonymousWrappers = currBlock;
528
529         if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
530             return toRenderBlockFlow(firstChildIgnoringAnonymousWrappers);
531
532         if (currBlock->isAnonymousColumnSpanBlock())
533             return 0;
534     }
535     return 0;
536 }
537
538 RenderBlock* RenderBlock::clone() const
539 {
540     RenderBlock* cloneBlock;
541     if (isAnonymousBlock()) {
542         cloneBlock = createAnonymousBlock();
543         cloneBlock->setChildrenInline(childrenInline());
544     }
545     else {
546         RenderObject* cloneRenderer = toElement(node())->createRenderer(style());
547         cloneBlock = toRenderBlock(cloneRenderer);
548         cloneBlock->setStyle(style());
549
550         // This takes care of setting the right value of childrenInline in case
551         // generated content is added to cloneBlock and 'this' does not have
552         // generated content added yet.
553         cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->firstChild()->isInline() : childrenInline());
554     }
555     cloneBlock->setFlowThreadState(flowThreadState());
556     return cloneBlock;
557 }
558
559 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
560                               RenderBlock* middleBlock,
561                               RenderObject* beforeChild, RenderBoxModelObject* oldCont)
562 {
563     // Create a clone of this inline.
564     RenderBlock* cloneBlock = clone();
565     if (!isAnonymousBlock())
566         cloneBlock->setContinuation(oldCont);
567
568     if (!beforeChild && isAfterContent(lastChild()))
569         beforeChild = lastChild();
570
571     // If we are moving inline children from |this| to cloneBlock, then we need
572     // to clear our line box tree.
573     if (beforeChild && childrenInline())
574         deleteLineBoxTree();
575
576     // Now take all of the children from beforeChild to the end and remove
577     // them from |this| and place them in the clone.
578     moveChildrenTo(cloneBlock, beforeChild, 0, true);
579
580     // Hook |clone| up as the continuation of the middle block.
581     if (!cloneBlock->isAnonymousBlock())
582         middleBlock->setContinuation(cloneBlock);
583
584     // We have been reparented and are now under the fromBlock.  We need
585     // to walk up our block parent chain until we hit the containing anonymous columns block.
586     // Once we hit the anonymous columns block we're done.
587     RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
588     RenderBoxModelObject* currChild = this;
589     RenderObject* currChildNextSibling = currChild->nextSibling();
590
591     while (curr && curr->isDescendantOf(fromBlock) && curr != fromBlock) {
592         ASSERT_WITH_SECURITY_IMPLICATION(curr->isRenderBlock());
593
594         RenderBlock* blockCurr = toRenderBlock(curr);
595
596         // Create a new clone.
597         RenderBlock* cloneChild = cloneBlock;
598         cloneBlock = blockCurr->clone();
599
600         // Insert our child clone as the first child.
601         cloneBlock->addChildIgnoringContinuation(cloneChild, 0);
602
603         // Hook the clone up as a continuation of |curr|.  Note we do encounter
604         // anonymous blocks possibly as we walk up the block chain.  When we split an
605         // anonymous block, there's no need to do any continuation hookup, since we haven't
606         // actually split a real element.
607         if (!blockCurr->isAnonymousBlock()) {
608             oldCont = blockCurr->continuation();
609             blockCurr->setContinuation(cloneBlock);
610             cloneBlock->setContinuation(oldCont);
611         }
612
613         // Now we need to take all of the children starting from the first child
614         // *after* currChild and append them all to the clone.
615         blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true);
616
617         // Keep walking up the chain.
618         currChild = curr;
619         currChildNextSibling = currChild->nextSibling();
620         curr = toRenderBoxModelObject(curr->parent());
621     }
622
623     // Now we are at the columns block level. We need to put the clone into the toBlock.
624     toBlock->children()->appendChildNode(toBlock, cloneBlock);
625
626     // Now take all the children after currChild and remove them from the fromBlock
627     // and put them in the toBlock.
628     fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true);
629 }
630
631 void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
632                             RenderObject* newChild, RenderBoxModelObject* oldCont)
633 {
634     RenderBlock* pre = 0;
635     RenderBlock* block = containingColumnsBlock();
636
637     // Delete our line boxes before we do the inline split into continuations.
638     block->deleteLineBoxTree();
639
640     bool madeNewBeforeBlock = false;
641     if (block->isAnonymousColumnsBlock()) {
642         // We can reuse this block and make it the preBlock of the next continuation.
643         pre = block;
644         pre->removePositionedObjects(0);
645         if (block->isRenderBlockFlow())
646             toRenderBlockFlow(pre)->removeFloatingObjects();
647         block = toRenderBlock(block->parent());
648     } else {
649         // No anonymous block available for use.  Make one.
650         pre = block->createAnonymousColumnsBlock();
651         pre->setChildrenInline(false);
652         madeNewBeforeBlock = true;
653     }
654
655     RenderBlock* post = block->createAnonymousColumnsBlock();
656     post->setChildrenInline(false);
657
658     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
659     if (madeNewBeforeBlock)
660         block->children()->insertChildNode(block, pre, boxFirst);
661     block->children()->insertChildNode(block, newBlockBox, boxFirst);
662     block->children()->insertChildNode(block, post, boxFirst);
663     block->setChildrenInline(false);
664
665     if (madeNewBeforeBlock)
666         block->moveChildrenTo(pre, boxFirst, 0, true);
667
668     splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
669
670     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
671     // time in makeChildrenNonInline by just setting this explicitly up front.
672     newBlockBox->setChildrenInline(false);
673
674     newBlockBox->addChild(newChild);
675
676     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
677     // get deleted properly.  Because objects moves from the pre block into the post block, we want to
678     // make new line boxes instead of leaving the old line boxes around.
679     pre->setNeedsLayoutAndPrefWidthsRecalc();
680     block->setNeedsLayoutAndPrefWidthsRecalc();
681     post->setNeedsLayoutAndPrefWidthsRecalc();
682 }
683
684 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlockFlow* newBlockBox, RenderObject* newChild)
685 {
686     RenderBlockFlow* pre = 0;
687     RenderBlockFlow* post = 0;
688     RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
689                                // so that we don't have to patch all of the rest of the code later on.
690
691     // Delete the block's line boxes before we do the split.
692     block->deleteLineBoxTree();
693
694     if (beforeChild && beforeChild->parent() != this)
695         beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
696
697     if (beforeChild != firstChild()) {
698         pre = block->createAnonymousColumnsBlock();
699         pre->setChildrenInline(block->childrenInline());
700     }
701
702     if (beforeChild) {
703         post = block->createAnonymousColumnsBlock();
704         post->setChildrenInline(block->childrenInline());
705     }
706
707     RenderObject* boxFirst = block->firstChild();
708     if (pre)
709         block->children()->insertChildNode(block, pre, boxFirst);
710     block->children()->insertChildNode(block, newBlockBox, boxFirst);
711     if (post)
712         block->children()->insertChildNode(block, post, boxFirst);
713     block->setChildrenInline(false);
714
715     // 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).
716     block->moveChildrenTo(pre, boxFirst, beforeChild, true);
717     block->moveChildrenTo(post, beforeChild, 0, true);
718
719     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
720     // time in makeChildrenNonInline by just setting this explicitly up front.
721     newBlockBox->setChildrenInline(false);
722
723     newBlockBox->addChild(newChild);
724
725     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
726     // get deleted properly.  Because objects moved from the pre block into the post block, we want to
727     // make new line boxes instead of leaving the old line boxes around.
728     if (pre)
729         pre->setNeedsLayoutAndPrefWidthsRecalc();
730     block->setNeedsLayoutAndPrefWidthsRecalc();
731     if (post)
732         post->setNeedsLayoutAndPrefWidthsRecalc();
733 }
734
735 RenderBlockFlow* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
736 {
737     // FIXME: This function is the gateway for the addition of column-span support.  It will
738     // be added to in three stages:
739     // (1) Immediate children of a multi-column block can span.
740     // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
741     // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
742     // cross the streams and have to cope with both types of continuations mixed together).
743     // This function currently supports (1) and (2).
744     RenderBlockFlow* columnsBlockAncestor = 0;
745     if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
746         && !newChild->isFloatingOrOutOfFlowPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
747         columnsBlockAncestor = containingColumnsBlock(false);
748         if (columnsBlockAncestor) {
749             // Make sure that none of the parent ancestors have a continuation.
750             // If yes, we do not want split the block into continuations.
751             RenderObject* curr = this;
752             while (curr && curr != columnsBlockAncestor) {
753                 if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
754                     columnsBlockAncestor = 0;
755                     break;
756                 }
757                 curr = curr->parent();
758             }
759         }
760     }
761     return columnsBlockAncestor;
762 }
763
764 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
765 {
766     if (beforeChild && beforeChild->parent() != this) {
767         RenderObject* beforeChildContainer = beforeChild->parent();
768         while (beforeChildContainer->parent() != this)
769             beforeChildContainer = beforeChildContainer->parent();
770         ASSERT(beforeChildContainer);
771
772         if (beforeChildContainer->isAnonymous()) {
773             // If the requested beforeChild is not one of our children, then this is because
774             // there is an anonymous container within this object that contains the beforeChild.
775             RenderObject* beforeChildAnonymousContainer = beforeChildContainer;
776             if (beforeChildAnonymousContainer->isAnonymousBlock()
777                 // Full screen renderers and full screen placeholders act as anonymous blocks, not tables:
778                 || beforeChildAnonymousContainer->isRenderFullScreen()
779                 || beforeChildAnonymousContainer->isRenderFullScreenPlaceholder()
780                 ) {
781                 // Insert the child into the anonymous block box instead of here.
782                 if (newChild->isInline() || newChild->isFloatingOrOutOfFlowPositioned() || beforeChild->parent()->firstChild() != beforeChild)
783                     beforeChild->parent()->addChild(newChild, beforeChild);
784                 else
785                     addChild(newChild, beforeChild->parent());
786                 return;
787             }
788
789             ASSERT(beforeChildAnonymousContainer->isTable());
790             if (newChild->isTablePart()) {
791                 // Insert into the anonymous table.
792                 beforeChildAnonymousContainer->addChild(newChild, beforeChild);
793                 return;
794             }
795
796             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
797
798             ASSERT(beforeChild->parent() == this);
799             if (beforeChild->parent() != this) {
800                 // We should never reach here. If we do, we need to use the
801                 // safe fallback to use the topmost beforeChild container.
802                 beforeChild = beforeChildContainer;
803             }
804         }
805     }
806
807     // Check for a spanning element in columns.
808     if (gColumnFlowSplitEnabled && !document().regionBasedColumnsEnabled()) {
809         RenderBlockFlow* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
810         if (columnsBlockAncestor) {
811             TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
812             // We are placing a column-span element inside a block.
813             RenderBlockFlow* newBox = createAnonymousColumnSpanBlock();
814
815             if (columnsBlockAncestor != this && !isRenderFlowThread()) {
816                 // We are nested inside a multi-column element and are being split by the span. We have to break up
817                 // our block into continuations.
818                 RenderBoxModelObject* oldContinuation = continuation();
819
820                 // When we split an anonymous block, there's no need to do any continuation hookup,
821                 // since we haven't actually split a real element.
822                 if (!isAnonymousBlock())
823                     setContinuation(newBox);
824
825                 splitFlow(beforeChild, newBox, newChild, oldContinuation);
826                 return;
827             }
828
829             // We have to perform a split of this block's children. This involves creating an anonymous block box to hold
830             // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
831             // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
832             makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
833             return;
834         }
835     }
836
837     bool madeBoxesNonInline = false;
838
839     // A block has to either have all of its children inline, or all of its children as blocks.
840     // So, if our children are currently inline and a block child has to be inserted, we move all our
841     // inline children into anonymous block boxes.
842     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned()) {
843         // This is a block with inline content. Wrap the inline content in anonymous blocks.
844         makeChildrenNonInline(beforeChild);
845         madeBoxesNonInline = true;
846
847         if (beforeChild && beforeChild->parent() != this) {
848             beforeChild = beforeChild->parent();
849             ASSERT(beforeChild->isAnonymousBlock());
850             ASSERT(beforeChild->parent() == this);
851         }
852     } else if (!childrenInline() && (newChild->isFloatingOrOutOfFlowPositioned() || newChild->isInline())) {
853         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
854         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
855         // a new one is created and inserted into our list of children in the appropriate position.
856         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
857
858         if (afterChild && afterChild->isAnonymousBlock()) {
859             afterChild->addChild(newChild);
860             return;
861         }
862
863         if (newChild->isInline()) {
864             // No suitable existing anonymous box - create a new one.
865             RenderBlock* newBox = createAnonymousBlock();
866             RenderBox::addChild(newBox, beforeChild);
867             newBox->addChild(newChild);
868             return;
869         }
870     }
871
872     RenderBox::addChild(newChild, beforeChild);
873
874     if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
875         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
876     // this object may be dead here
877 }
878
879 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
880 {
881     if (continuation() && !isAnonymousBlock())
882         addChildToContinuation(newChild, beforeChild);
883     else
884         addChildIgnoringContinuation(newChild, beforeChild);
885 }
886
887 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
888 {
889     if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
890         addChildToAnonymousColumnBlocks(newChild, beforeChild);
891     else
892         addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
893 }
894
895 static void getInlineRun(RenderObject* start, RenderObject* boundary,
896                          RenderObject*& inlineRunStart,
897                          RenderObject*& inlineRunEnd)
898 {
899     // Beginning at |start| we find the largest contiguous run of inlines that
900     // we can.  We denote the run with start and end points, |inlineRunStart|
901     // and |inlineRunEnd|.  Note that these two values may be the same if
902     // we encounter only one inline.
903     //
904     // We skip any non-inlines we encounter as long as we haven't found any
905     // inlines yet.
906     //
907     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
908     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
909     // a non-inline.
910
911     // Start by skipping as many non-inlines as we can.
912     RenderObject * curr = start;
913     bool sawInline;
914     do {
915         while (curr && !(curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()))
916             curr = curr->nextSibling();
917
918         inlineRunStart = inlineRunEnd = curr;
919
920         if (!curr)
921             return; // No more inline children to be found.
922
923         sawInline = curr->isInline();
924
925         curr = curr->nextSibling();
926         while (curr && (curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()) && (curr != boundary)) {
927             inlineRunEnd = curr;
928             if (curr->isInline())
929                 sawInline = true;
930             curr = curr->nextSibling();
931         }
932     } while (!sawInline);
933 }
934
935 void RenderBlock::deleteLineBoxTree()
936 {
937     m_lineBoxes.deleteLineBoxTree();
938
939     if (AXObjectCache* cache = document().existingAXObjectCache())
940         cache->recomputeIsIgnored(this);
941 }
942
943 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
944 {
945     // makeChildrenNonInline takes a block whose children are *all* inline and it
946     // makes sure that inline children are coalesced under anonymous
947     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
948     // the new block child that is causing us to have to wrap all the inlines.  This
949     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
950     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
951     // splitting them.
952     ASSERT(isInlineBlockOrInlineTable() || !isInline());
953     ASSERT(!insertionPoint || insertionPoint->parent() == this);
954
955     setChildrenInline(false);
956
957     RenderObject *child = firstChild();
958     if (!child)
959         return;
960
961     deleteLineBoxTree();
962
963     while (child) {
964         RenderObject *inlineRunStart, *inlineRunEnd;
965         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
966
967         if (!inlineRunStart)
968             break;
969
970         child = inlineRunEnd->nextSibling();
971
972         RenderBlock* block = createAnonymousBlock();
973         children()->insertChildNode(this, block, inlineRunStart);
974         moveChildrenTo(block, inlineRunStart, child);
975     }
976
977 #ifndef NDEBUG
978     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
979         ASSERT(!c->isInline());
980 #endif
981
982     repaint();
983 }
984
985 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
986 {
987     ASSERT(child->isAnonymousBlock());
988     ASSERT(!child->childrenInline());
989
990     if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
991         return;
992
993     RenderObject* firstAnChild = child->m_children.firstChild();
994     RenderObject* lastAnChild = child->m_children.lastChild();
995     if (firstAnChild) {
996         RenderObject* o = firstAnChild;
997         while (o) {
998             o->setParent(this);
999             o = o->nextSibling();
1000         }
1001         firstAnChild->setPreviousSibling(child->previousSibling());
1002         lastAnChild->setNextSibling(child->nextSibling());
1003         if (child->previousSibling())
1004             child->previousSibling()->setNextSibling(firstAnChild);
1005         if (child->nextSibling())
1006             child->nextSibling()->setPreviousSibling(lastAnChild);
1007
1008         if (child == m_children.firstChild())
1009             m_children.setFirstChild(firstAnChild);
1010         if (child == m_children.lastChild())
1011             m_children.setLastChild(lastAnChild);
1012     } else {
1013         if (child == m_children.firstChild())
1014             m_children.setFirstChild(child->nextSibling());
1015         if (child == m_children.lastChild())
1016             m_children.setLastChild(child->previousSibling());
1017
1018         if (child->previousSibling())
1019             child->previousSibling()->setNextSibling(child->nextSibling());
1020         if (child->nextSibling())
1021             child->nextSibling()->setPreviousSibling(child->previousSibling());
1022     }
1023
1024     child->children()->setFirstChild(0);
1025     child->m_next = 0;
1026
1027     // Remove all the information in the flow thread associated with the leftover anonymous block.
1028     child->removeFromRenderFlowThread();
1029
1030     child->setParent(0);
1031     child->setPreviousSibling(0);
1032     child->setNextSibling(0);
1033
1034     child->destroy();
1035 }
1036
1037 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
1038 {
1039     if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
1040         return false;
1041
1042     if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
1043         || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
1044         return false;
1045
1046     if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
1047         || (next && (next->isRubyRun() || next->isRubyBase())))
1048         return false;
1049
1050     if (!prev || !next)
1051         return true;
1052
1053     // Make sure the types of the anonymous blocks match up.
1054     return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
1055            && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
1056 }
1057
1058 void RenderBlock::collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock* child)
1059 {
1060     // It's possible that this block's destruction may have been triggered by the
1061     // child's removal. Just bail if the anonymous child block is already being
1062     // destroyed. See crbug.com/282088
1063     if (child->beingDestroyed())
1064         return;
1065     parent->setNeedsLayoutAndPrefWidthsRecalc();
1066     parent->setChildrenInline(child->childrenInline());
1067     RenderObject* nextSibling = child->nextSibling();
1068
1069     RenderFlowThread* childFlowThread = child->flowThreadContainingBlock();
1070     CurrentRenderFlowThreadMaintainer flowThreadMaintainer(childFlowThread);
1071
1072     parent->children()->removeChildNode(parent, child, child->hasLayer());
1073     child->moveAllChildrenTo(parent, nextSibling, child->hasLayer());
1074     // Explicitly delete the child's line box tree, or the special anonymous
1075     // block handling in willBeDestroyed will cause problems.
1076     child->deleteLineBoxTree();
1077     child->destroy();
1078 }
1079
1080 void RenderBlock::removeChild(RenderObject* oldChild)
1081 {
1082     // No need to waste time in merging or removing empty anonymous blocks.
1083     // We can just bail out if our document is getting destroyed.
1084     if (documentBeingDestroyed()) {
1085         RenderBox::removeChild(oldChild);
1086         return;
1087     }
1088
1089     // This protects against column split flows when anonymous blocks are getting merged.
1090     TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
1091
1092     // If this child is a block, and if our previous and next siblings are
1093     // both anonymous blocks with inline content, then we can go ahead and
1094     // fold the inline content back together.
1095     RenderObject* prev = oldChild->previousSibling();
1096     RenderObject* next = oldChild->nextSibling();
1097     bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
1098     if (canMergeAnonymousBlocks && prev && next) {
1099         prev->setNeedsLayoutAndPrefWidthsRecalc();
1100         RenderBlockFlow* nextBlock = toRenderBlockFlow(next);
1101         RenderBlockFlow* prevBlock = toRenderBlockFlow(prev);
1102
1103         if (prev->childrenInline() != next->childrenInline()) {
1104             RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
1105             RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
1106
1107             // Place the inline children block inside of the block children block instead of deleting it.
1108             // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
1109             // to clear out inherited column properties by just making a new style, and to also clear the
1110             // column span flag if it is set.
1111             ASSERT(!inlineChildrenBlock->continuation());
1112             RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK);
1113             // Cache this value as it might get changed in setStyle() call.
1114             bool inlineChildrenBlockHasLayer = inlineChildrenBlock->hasLayer();
1115             inlineChildrenBlock->setStyle(newStyle);
1116             children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlockHasLayer);
1117
1118             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
1119             blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
1120                                                             inlineChildrenBlockHasLayer || blockChildrenBlock->hasLayer());
1121             next->setNeedsLayoutAndPrefWidthsRecalc();
1122
1123             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
1124             // of "this". we null out prev or next so that is not used later in the function.
1125             if (inlineChildrenBlock == prevBlock)
1126                 prev = 0;
1127             else
1128                 next = 0;
1129         } else {
1130             // Take all the children out of the |next| block and put them in
1131             // the |prev| block.
1132             nextBlock->moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
1133
1134             // Delete the now-empty block's lines and nuke it.
1135             nextBlock->deleteLineBoxTree();
1136             nextBlock->destroy();
1137             next = 0;
1138         }
1139     }
1140
1141     RenderBox::removeChild(oldChild);
1142
1143     RenderObject* child = prev ? prev : next;
1144     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && canCollapseAnonymousBlockChild()) {
1145         // The removal has knocked us down to containing only a single anonymous
1146         // box.  We can go ahead and pull the content right back up into our
1147         // box.
1148         collapseAnonymousBlockChild(this, toRenderBlock(child));
1149     } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && canCollapseAnonymousBlockChild()) {
1150         // It's possible that the removal has knocked us down to a single anonymous
1151         // block with pseudo-style element siblings (e.g. first-letter). If these
1152         // are floating, then we need to pull the content up also.
1153         RenderBlock* anonymousBlock = toRenderBlock((prev && prev->isAnonymousBlock()) ? prev : next);
1154         if ((anonymousBlock->previousSibling() || anonymousBlock->nextSibling())
1155             && (!anonymousBlock->previousSibling() || (anonymousBlock->previousSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->previousSibling()->isFloating() && !anonymousBlock->previousSibling()->previousSibling()))
1156             && (!anonymousBlock->nextSibling() || (anonymousBlock->nextSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->nextSibling()->isFloating() && !anonymousBlock->nextSibling()->nextSibling()))) {
1157             collapseAnonymousBlockChild(this, anonymousBlock);
1158         }
1159     }
1160
1161     if (!firstChild()) {
1162         // If this was our last child be sure to clear out our line boxes.
1163         if (childrenInline())
1164             deleteLineBoxTree();
1165
1166         // If we are an empty anonymous block in the continuation chain,
1167         // we need to remove ourself and fix the continuation chain.
1168         if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild->isListMarker()) {
1169             RenderObject* containingBlockIgnoringAnonymous = containingBlock();
1170             while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymousBlock())
1171                 containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
1172             for (RenderObject* curr = this; curr; curr = curr->previousInPreOrder(containingBlockIgnoringAnonymous)) {
1173                 if (curr->virtualContinuation() != this)
1174                     continue;
1175
1176                 // Found our previous continuation. We just need to point it to
1177                 // |this|'s next continuation.
1178                 RenderBoxModelObject* nextContinuation = continuation();
1179                 if (curr->isRenderInline())
1180                     toRenderInline(curr)->setContinuation(nextContinuation);
1181                 else if (curr->isRenderBlock())
1182                     toRenderBlock(curr)->setContinuation(nextContinuation);
1183                 else
1184                     ASSERT_NOT_REACHED();
1185
1186                 break;
1187             }
1188             setContinuation(0);
1189             destroy();
1190         }
1191     }
1192 }
1193
1194 bool RenderBlock::isSelfCollapsingBlock() const
1195 {
1196     // We are not self-collapsing if we
1197     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
1198     // (b) are a table,
1199     // (c) have border/padding,
1200     // (d) have a min-height
1201     // (e) have specified that one of our margins can't collapse using a CSS extension
1202     // (f) establish a new block formatting context.
1203
1204     // The early exit must be done before we check for clean layout.
1205     // We should be able to give a quick answer if the box is a relayout boundary.
1206     // Being a relayout boundary implies a block formatting context, and also
1207     // our internal layout shouldn't affect our container in any way.
1208     if (createsBlockFormattingContext())
1209         return false;
1210
1211     // Placeholder elements are not laid out until the dimensions of their parent text control are known, so they
1212     // don't get layout until their parent has had layout - this is unique in the layout tree and means
1213     // when we call isSelfCollapsingBlock on them we find that they still need layout.
1214     ASSERT(!needsLayout() || (node() && node()->isElementNode() && toElement(node())->shadowPseudoId() == "-webkit-input-placeholder"));
1215
1216     if (logicalHeight() > 0
1217         || isTable() || borderAndPaddingLogicalHeight()
1218         || style()->logicalMinHeight().isPositive()
1219         || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
1220         return false;
1221
1222     Length logicalHeightLength = style()->logicalHeight();
1223     bool hasAutoHeight = logicalHeightLength.isAuto();
1224     if (logicalHeightLength.isPercent() && !document().inQuirksMode()) {
1225         hasAutoHeight = true;
1226         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
1227             if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
1228                 hasAutoHeight = false;
1229         }
1230     }
1231
1232     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
1233     // on whether we have content that is all self-collapsing or not.
1234     if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
1235         // If the block has inline children, see if we generated any line boxes.  If we have any
1236         // line boxes, then we can't be self-collapsing, since we have content.
1237         if (childrenInline())
1238             return !firstLineBox();
1239
1240         // Whether or not we collapse is dependent on whether all our normal flow children
1241         // are also self-collapsing.
1242         if (m_hasOnlySelfCollapsingChildren)
1243             return true;
1244         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1245             if (child->isFloatingOrOutOfFlowPositioned())
1246                 continue;
1247             if (!child->isSelfCollapsingBlock())
1248                 return false;
1249         }
1250         return true;
1251     }
1252     return false;
1253 }
1254
1255 void RenderBlock::startDelayUpdateScrollInfo()
1256 {
1257     if (gDelayUpdateScrollInfo == 0) {
1258         ASSERT(!gDelayedUpdateScrollInfoSet);
1259         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
1260     }
1261     ASSERT(gDelayedUpdateScrollInfoSet);
1262     ++gDelayUpdateScrollInfo;
1263 }
1264
1265 void RenderBlock::finishDelayUpdateScrollInfo()
1266 {
1267     --gDelayUpdateScrollInfo;
1268     ASSERT(gDelayUpdateScrollInfo >= 0);
1269     if (gDelayUpdateScrollInfo == 0) {
1270         ASSERT(gDelayedUpdateScrollInfoSet);
1271
1272         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(adoptPtr(gDelayedUpdateScrollInfoSet));
1273         gDelayedUpdateScrollInfoSet = 0;
1274
1275         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
1276             RenderBlock* block = *it;
1277             if (block->hasOverflowClip()) {
1278                 block->layer()->scrollableArea()->updateAfterLayout();
1279             }
1280         }
1281     }
1282 }
1283
1284 void RenderBlock::updateScrollInfoAfterLayout()
1285 {
1286     if (hasOverflowClip()) {
1287         if (style()->isFlippedBlocksWritingMode()) {
1288             // FIXME: https://bugs.webkit.org/show_bug.cgi?id=97937
1289             // Workaround for now. We cannot delay the scroll info for overflow
1290             // for items with opposite writing directions, as the contents needs
1291             // to overflow in that direction
1292             layer()->scrollableArea()->updateAfterLayout();
1293             return;
1294         }
1295
1296         if (gDelayUpdateScrollInfo)
1297             gDelayedUpdateScrollInfoSet->add(this);
1298         else
1299             layer()->scrollableArea()->updateAfterLayout();
1300     }
1301 }
1302
1303 void RenderBlock::layout()
1304 {
1305     OverflowEventDispatcher dispatcher(this);
1306
1307     // Update our first letter info now.
1308     updateFirstLetter();
1309
1310     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
1311     // layoutBlock().
1312     layoutBlock(false);
1313
1314     // It's safe to check for control clip here, since controls can never be table cells.
1315     // If we have a lightweight clip, there can never be any overflow from children.
1316     if (hasControlClip() && m_overflow)
1317         clearLayoutOverflow();
1318
1319     invalidateBackgroundObscurationStatus();
1320 }
1321
1322 bool RenderBlock::updateImageLoadingPriorities()
1323 {
1324     Vector<ImageResource*> images;
1325     appendImagesFromStyle(images, *style());
1326
1327     if (images.isEmpty())
1328         return false;
1329
1330     LayoutRect viewBounds = viewRect();
1331     LayoutRect objectBounds = absoluteContentBox();
1332     // The object bounds might be empty right now, so intersects will fail since it doesn't deal
1333     // with empty rects. Use LayoutRect::contains in that case.
1334     bool isVisible;
1335     if (!objectBounds.isEmpty())
1336         isVisible =  viewBounds.intersects(objectBounds);
1337     else
1338         isVisible = viewBounds.contains(objectBounds);
1339
1340     ResourceLoadPriorityOptimizer::VisibilityStatus status = isVisible ?
1341         ResourceLoadPriorityOptimizer::Visible : ResourceLoadPriorityOptimizer::NotVisible;
1342
1343     LayoutRect screenArea;
1344     if (!objectBounds.isEmpty()) {
1345         screenArea = viewBounds;
1346         screenArea.intersect(objectBounds);
1347     }
1348
1349     for (Vector<ImageResource*>::iterator it = images.begin(), end = images.end(); it != end; ++it)
1350         ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->notifyImageResourceVisibility(*it, status, screenArea);
1351
1352     return true;
1353 }
1354
1355 void RenderBlock::computeRegionRangeForBlock(RenderFlowThread* flowThread)
1356 {
1357     if (flowThread)
1358         flowThread->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage());
1359 }
1360
1361 bool RenderBlock::updateLogicalWidthAndColumnWidth()
1362 {
1363     LayoutUnit oldWidth = logicalWidth();
1364     LayoutUnit oldColumnWidth = desiredColumnWidth();
1365
1366     updateLogicalWidth();
1367     calcColumnWidth();
1368
1369     bool hasBorderOrPaddingLogicalWidthChanged = m_hasBorderOrPaddingLogicalWidthChanged;
1370     m_hasBorderOrPaddingLogicalWidthChanged = false;
1371
1372     return oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth() || hasBorderOrPaddingLogicalWidthChanged;
1373 }
1374
1375 void RenderBlock::layoutBlock(bool)
1376 {
1377     ASSERT_NOT_REACHED();
1378     clearNeedsLayout();
1379 }
1380
1381 void RenderBlock::addOverflowFromChildren()
1382 {
1383     if (!hasColumns()) {
1384         if (childrenInline())
1385             toRenderBlockFlow(this)->addOverflowFromInlineChildren();
1386         else
1387             addOverflowFromBlockChildren();
1388     } else {
1389         ColumnInfo* colInfo = columnInfo();
1390         if (columnCount(colInfo)) {
1391             LayoutRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
1392             addLayoutOverflow(lastRect);
1393             addContentsVisualOverflow(lastRect);
1394         }
1395     }
1396 }
1397
1398 void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool)
1399 {
1400     m_overflow.clear();
1401
1402     // Add overflow from children.
1403     addOverflowFromChildren();
1404
1405     // Add in the overflow from positioned objects.
1406     addOverflowFromPositionedObjects();
1407
1408     if (hasOverflowClip()) {
1409         // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
1410         // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
1411         // be considered reachable.
1412         LayoutRect clientRect(noOverflowRect());
1413         LayoutRect rectToApply;
1414         if (isHorizontalWritingMode())
1415             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), 1, max<LayoutUnit>(0, oldClientAfterEdge - clientRect.y()));
1416         else
1417             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), max<LayoutUnit>(0, oldClientAfterEdge - clientRect.x()), 1);
1418         addLayoutOverflow(rectToApply);
1419         if (hasRenderOverflow())
1420             m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge);
1421     }
1422
1423     addVisualEffectOverflow();
1424
1425     addVisualOverflowFromTheme();
1426 }
1427
1428 void RenderBlock::addOverflowFromBlockChildren()
1429 {
1430     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1431         if (!child->isFloatingOrOutOfFlowPositioned())
1432             addOverflowFromChild(child);
1433     }
1434 }
1435
1436 void RenderBlock::addOverflowFromPositionedObjects()
1437 {
1438     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
1439     if (!positionedDescendants)
1440         return;
1441
1442     RenderBox* positionedObject;
1443     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
1444     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
1445         positionedObject = *it;
1446
1447         // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
1448         if (positionedObject->style()->position() != FixedPosition)
1449             addOverflowFromChild(positionedObject, LayoutSize(positionedObject->x(), positionedObject->y()));
1450     }
1451 }
1452
1453 void RenderBlock::addVisualOverflowFromTheme()
1454 {
1455     if (!style()->hasAppearance())
1456         return;
1457
1458     IntRect inflatedRect = pixelSnappedBorderBoxRect();
1459     RenderTheme::theme().adjustRepaintRect(this, inflatedRect);
1460     addVisualOverflow(inflatedRect);
1461 }
1462
1463 void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox* child)
1464 {
1465     // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
1466     // an auto value. Add a method to determine this, so that we can avoid the relayout.
1467     if (relayoutChildren || (child->hasRelativeLogicalHeight() && !isRenderView()))
1468         child->setChildNeedsLayout(MarkOnlyThis);
1469
1470     // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
1471     if (relayoutChildren && child->needsPreferredWidthsRecalculation())
1472         child->setPreferredLogicalWidthsDirty(MarkOnlyThis);
1473 }
1474
1475 void RenderBlock::simplifiedNormalFlowLayout()
1476 {
1477     if (childrenInline()) {
1478         ListHashSet<RootInlineBox*> lineBoxes;
1479         for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
1480             RenderObject* o = walker.current();
1481             if (!o->isOutOfFlowPositioned() && (o->isReplaced() || o->isFloating())) {
1482                 o->layoutIfNeeded();
1483                 if (toRenderBox(o)->inlineBoxWrapper()) {
1484                     RootInlineBox& box = toRenderBox(o)->inlineBoxWrapper()->root();
1485                     lineBoxes.add(&box);
1486                 }
1487             } else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline())) {
1488                 o->clearNeedsLayout();
1489             }
1490         }
1491
1492         // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
1493         GlyphOverflowAndFallbackFontsMap textBoxDataMap;
1494         for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
1495             RootInlineBox* box = *it;
1496             box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
1497         }
1498     } else {
1499         for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
1500             if (!box->isOutOfFlowPositioned())
1501                 box->layoutIfNeeded();
1502         }
1503     }
1504 }
1505
1506 bool RenderBlock::simplifiedLayout()
1507 {
1508     // Check if we need to do a full layout.
1509     if (normalChildNeedsLayout() || selfNeedsLayout())
1510         return false;
1511
1512     // Check that we actually need to do a simplified layout.
1513     if (!posChildNeedsLayout() && !(needsSimplifiedNormalFlowLayout() || needsPositionedMovementLayout()))
1514         return false;
1515
1516
1517     {
1518         // LayoutStateMaintainer needs this deliberate scope to pop before repaint
1519         LayoutStateMaintainer statePusher(*this, locationOffset());
1520
1521         if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
1522             return false;
1523
1524         FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(this);
1525
1526         // Lay out positioned descendants or objects that just need to recompute overflow.
1527         if (needsSimplifiedNormalFlowLayout())
1528             simplifiedNormalFlowLayout();
1529
1530         // Lay out our positioned objects if our positioned child bit is set.
1531         // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
1532         // child, neither the fixed element nor its container learn of the movement since posChildNeedsLayout() is only marked as far as the
1533         // relative positioned container. So if we can have fixed pos objects in our positioned objects list check if any of them
1534         // are statically positioned and thus need to move with their absolute ancestors.
1535         bool canContainFixedPosObjects = canContainFixedPositionObjects();
1536         if (posChildNeedsLayout() || needsPositionedMovementLayout() || canContainFixedPosObjects)
1537             layoutPositionedObjects(false, needsPositionedMovementLayout() ? ForcedLayoutAfterContainingBlockMoved : (!posChildNeedsLayout() && canContainFixedPosObjects ? LayoutOnlyFixedPositionedObjects : DefaultLayout));
1538
1539         // Recompute our overflow information.
1540         // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
1541         // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
1542         // For now just always recompute overflow. This is no worse performance-wise than the old code that called rightmostPosition and
1543         // lowestPosition on every relayout so it's not a regression.
1544         // computeOverflow expects the bottom edge before we clamp our height. Since this information isn't available during
1545         // simplifiedLayout, we cache the value in m_overflow.
1546         LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
1547         computeOverflow(oldClientAfterEdge, true);
1548     }
1549
1550     updateLayerTransform();
1551
1552     updateScrollInfoAfterLayout();
1553
1554     clearNeedsLayout();
1555     return true;
1556 }
1557
1558 void RenderBlock::markFixedPositionObjectForLayoutIfNeeded(RenderObject* child, SubtreeLayoutScope& layoutScope)
1559 {
1560     if (child->style()->position() != FixedPosition)
1561         return;
1562
1563     bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontalWritingMode());
1564     bool hasStaticInlinePosition = child->style()->hasStaticInlinePosition(isHorizontalWritingMode());
1565     if (!hasStaticBlockPosition && !hasStaticInlinePosition)
1566         return;
1567
1568     RenderObject* o = child->parent();
1569     while (o && !o->isRenderView() && o->style()->position() != AbsolutePosition)
1570         o = o->parent();
1571     if (o->style()->position() != AbsolutePosition)
1572         return;
1573
1574     RenderBox* box = toRenderBox(child);
1575     if (hasStaticInlinePosition) {
1576         LogicalExtentComputedValues computedValues;
1577         box->computeLogicalWidth(computedValues);
1578         LayoutUnit newLeft = computedValues.m_position;
1579         if (newLeft != box->logicalLeft())
1580             layoutScope.setChildNeedsLayout(child);
1581     } else if (hasStaticBlockPosition) {
1582         LayoutUnit oldTop = box->logicalTop();
1583         box->updateLogicalHeight();
1584         if (box->logicalTop() != oldTop)
1585             layoutScope.setChildNeedsLayout(child);
1586     }
1587 }
1588
1589 LayoutUnit RenderBlock::marginIntrinsicLogicalWidthForChild(RenderBox* child) const
1590 {
1591     // A margin has three types: fixed, percentage, and auto (variable).
1592     // Auto and percentage margins become 0 when computing min/max width.
1593     // Fixed margins can be added in as is.
1594     Length marginLeft = child->style()->marginStartUsing(style());
1595     Length marginRight = child->style()->marginEndUsing(style());
1596     LayoutUnit margin = 0;
1597     if (marginLeft.isFixed())
1598         margin += marginLeft.value();
1599     if (marginRight.isFixed())
1600         margin += marginRight.value();
1601     return margin;
1602 }
1603
1604 void RenderBlock::layoutPositionedObjects(bool relayoutChildren, PositionedLayoutBehavior info)
1605 {
1606     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
1607     if (!positionedDescendants)
1608         return;
1609
1610     if (hasColumns())
1611         view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
1612
1613     RenderBox* r;
1614     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
1615     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
1616         r = *it;
1617
1618         // FIXME: this should only be set from clearNeedsLayout crbug.com/361250
1619         r->setLayoutDidGetCalled(true);
1620
1621         SubtreeLayoutScope layoutScope(*r);
1622         // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
1623         // 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.
1624         // it has static position.
1625         markFixedPositionObjectForLayoutIfNeeded(r, layoutScope);
1626         if (info == LayoutOnlyFixedPositionedObjects) {
1627             r->layoutIfNeeded();
1628             continue;
1629         }
1630
1631         // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
1632         // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
1633         // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
1634         // positioned explicitly) this should not incur a performance penalty.
1635         if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this))
1636             layoutScope.setChildNeedsLayout(r);
1637
1638         // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
1639         if (relayoutChildren && r->needsPreferredWidthsRecalculation())
1640             r->setPreferredLogicalWidthsDirty(MarkOnlyThis);
1641
1642         if (!r->needsLayout())
1643             r->markForPaginationRelayoutIfNeeded(layoutScope);
1644
1645         // If we are paginated or in a line grid, go ahead and compute a vertical position for our object now.
1646         // If it's wrong we'll lay out again.
1647         LayoutUnit oldLogicalTop = 0;
1648         bool needsBlockDirectionLocationSetBeforeLayout = r->needsLayout() && view()->layoutState()->needsBlockDirectionLocationSetBeforeLayout();
1649         if (needsBlockDirectionLocationSetBeforeLayout) {
1650             if (isHorizontalWritingMode() == r->isHorizontalWritingMode())
1651                 r->updateLogicalHeight();
1652             else
1653                 r->updateLogicalWidth();
1654             oldLogicalTop = logicalTopForChild(r);
1655         }
1656
1657         // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout() here instead of a full layout. Need
1658         // to investigate why it does not trigger the correct invalidations in that case. crbug.com/350756
1659         if (info == ForcedLayoutAfterContainingBlockMoved)
1660             r->setNeedsLayout();
1661
1662         r->layoutIfNeeded();
1663
1664         // Lay out again if our estimate was wrong.
1665         if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop)
1666             r->forceChildLayout();
1667     }
1668
1669     if (hasColumns())
1670         view()->layoutState()->setColumnInfo(columnInfo()); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
1671 }
1672
1673 void RenderBlock::markPositionedObjectsForLayout()
1674 {
1675     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
1676     if (positionedDescendants) {
1677         RenderBox* r;
1678         TrackedRendererListHashSet::iterator end = positionedDescendants->end();
1679         for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
1680             r = *it;
1681             r->setChildNeedsLayout();
1682         }
1683     }
1684 }
1685
1686 void RenderBlock::markForPaginationRelayoutIfNeeded(SubtreeLayoutScope& layoutScope)
1687 {
1688     ASSERT(!needsLayout());
1689     if (needsLayout())
1690         return;
1691
1692     if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(*this, logicalTop()) != pageLogicalOffset()))
1693         layoutScope.setChildNeedsLayout(this);
1694 }
1695
1696 void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1697 {
1698     ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
1699
1700     LayoutPoint adjustedPaintOffset = paintOffset + location();
1701
1702     PaintPhase phase = paintInfo.phase;
1703
1704     LayoutRect overflowBox;
1705     // Check if we need to do anything at all.
1706     // FIXME: Could eliminate the isDocumentElement() check if we fix background painting so that the RenderView
1707     // paints the root's background.
1708     if (!isDocumentElement()) {
1709         overflowBox = overflowRectForPaintRejection();
1710         flipForWritingMode(overflowBox);
1711         overflowBox.moveBy(adjustedPaintOffset);
1712         if (!overflowBox.intersects(paintInfo.rect))
1713             return;
1714     }
1715
1716     // There are some cases where not all clipped visual overflow is accounted for.
1717     // FIXME: reduce the number of such cases.
1718     ContentsClipBehavior contentsClipBehavior = ForceContentsClip;
1719     if (hasOverflowClip() && !hasControlClip() && !(shouldPaintSelectionGaps() && phase == PaintPhaseForeground) && !hasCaret())
1720         contentsClipBehavior = SkipContentsClipIfPossible;
1721
1722     bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset, contentsClipBehavior);
1723     {
1724         GraphicsContextCullSaver cullSaver(*paintInfo.context);
1725         // Cull if we have more than one child and we didn't already clip.
1726         bool shouldCull = document().settings()->containerCullingEnabled() && !pushedClip && !isDocumentElement()
1727             && firstChild() && lastChild() && firstChild() != lastChild();
1728         if (shouldCull)
1729             cullSaver.cull(overflowBox);
1730
1731         paintObject(paintInfo, adjustedPaintOffset);
1732     }
1733     if (pushedClip)
1734         popContentsClip(paintInfo, phase, adjustedPaintOffset);
1735
1736     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
1737     // z-index.  We paint after we painted the background/border, so that the scrollbars will
1738     // sit above the background/border.
1739     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this) && !paintInfo.paintRootBackgroundOnly())
1740         layer()->scrollableArea()->paintOverflowControls(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect, false /* paintingOverlayControls */);
1741 }
1742
1743 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1744 {
1745     if (paintInfo.context->paintingDisabled())
1746         return;
1747
1748     const Color& ruleColor = resolveColor(CSSPropertyWebkitColumnRuleColor);
1749     bool ruleTransparent = style()->columnRuleIsTransparent();
1750     EBorderStyle ruleStyle = style()->columnRuleStyle();
1751     LayoutUnit ruleThickness = style()->columnRuleWidth();
1752     LayoutUnit colGap = columnGap();
1753     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
1754     if (!renderRule)
1755         return;
1756
1757     ColumnInfo* colInfo = columnInfo();
1758     unsigned colCount = columnCount(colInfo);
1759
1760     bool antialias = shouldAntialiasLines(paintInfo.context);
1761
1762     if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
1763         bool leftToRight = style()->isLeftToRightDirection();
1764         LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : contentLogicalWidth();
1765         LayoutUnit ruleAdd = logicalLeftOffsetForContent();
1766         LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : contentLogicalWidth();
1767         LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
1768         BoxSide boxSide = isHorizontalWritingMode()
1769             ? leftToRight ? BSLeft : BSRight
1770             : leftToRight ? BSTop : BSBottom;
1771
1772         for (unsigned i = 0; i < colCount; i++) {
1773             // Move to the next position.
1774             if (leftToRight) {
1775                 ruleLogicalLeft += inlineDirectionSize + colGap / 2;
1776                 currLogicalLeftOffset += inlineDirectionSize + colGap;
1777             } else {
1778                 ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
1779                 currLogicalLeftOffset -= (inlineDirectionSize + colGap);
1780             }
1781
1782             // Now paint the column rule.
1783             if (i < colCount - 1) {
1784                 LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft() + paddingLeft();
1785                 LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
1786                 LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
1787                 LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
1788                 IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
1789                 drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
1790             }
1791
1792             ruleLogicalLeft = currLogicalLeftOffset;
1793         }
1794     } else {
1795         bool topToBottom = !style()->isFlippedBlocksWritingMode();
1796         LayoutUnit ruleLeft = isHorizontalWritingMode()
1797             ? borderLeft() + paddingLeft()
1798             : colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + paddingBefore();
1799         LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : ruleThickness;
1800         LayoutUnit ruleTop = isHorizontalWritingMode()
1801             ? colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + paddingBefore()
1802             : borderStart() + paddingStart();
1803         LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : contentHeight();
1804         LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
1805
1806         if (!topToBottom) {
1807             if (isHorizontalWritingMode())
1808                 ruleRect.setY(height() - ruleRect.maxY());
1809             else
1810                 ruleRect.setX(width() - ruleRect.maxX());
1811         }
1812
1813         ruleRect.moveBy(paintOffset);
1814
1815         BoxSide boxSide = isHorizontalWritingMode()
1816             ? topToBottom ? BSTop : BSBottom
1817             : topToBottom ? BSLeft : BSRight;
1818
1819         LayoutSize step(0, topToBottom ? colInfo->columnHeight() + colGap : -(colInfo->columnHeight() + colGap));
1820         if (!isHorizontalWritingMode())
1821             step = step.transposedSize();
1822
1823         for (unsigned i = 1; i < colCount; i++) {
1824             ruleRect.move(step);
1825             IntRect pixelSnappedRuleRect = pixelSnappedIntRect(ruleRect);
1826             drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
1827         }
1828     }
1829 }
1830
1831 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool paintingFloats)
1832 {
1833     // We need to do multiple passes, breaking up our child painting into strips.
1834     GraphicsContext* context = paintInfo.context;
1835     ColumnInfo* colInfo = columnInfo();
1836     unsigned colCount = columnCount(colInfo);
1837     if (!colCount)
1838         return;
1839     LayoutUnit currLogicalTopOffset = 0;
1840     LayoutUnit colGap = columnGap();
1841     for (unsigned i = 0; i < colCount; i++) {
1842         // For each rect, we clip to the rect, and then we adjust our coords.
1843         LayoutRect colRect = columnRectAt(colInfo, i);
1844         flipForWritingMode(colRect);
1845         LayoutUnit logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
1846         LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(logicalLeftOffset, currLogicalTopOffset) : LayoutSize(currLogicalTopOffset, logicalLeftOffset);
1847         if (colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
1848             if (isHorizontalWritingMode())
1849                 offset.expand(0, colRect.y() - borderTop() - paddingTop());
1850             else
1851                 offset.expand(colRect.x() - borderLeft() - paddingLeft(), 0);
1852         }
1853         colRect.moveBy(paintOffset);
1854         PaintInfo info(paintInfo);
1855         info.rect.intersect(pixelSnappedIntRect(colRect));
1856
1857         if (!info.rect.isEmpty()) {
1858             GraphicsContextStateSaver stateSaver(*context);
1859             LayoutRect clipRect(colRect);
1860
1861             if (i < colCount - 1) {
1862                 if (isHorizontalWritingMode())
1863                     clipRect.expand(colGap / 2, 0);
1864                 else
1865                     clipRect.expand(0, colGap / 2);
1866             }
1867             // Each strip pushes a clip, since column boxes are specified as being
1868             // like overflow:hidden.
1869             // FIXME: Content and column rules that extend outside column boxes at the edges of the multi-column element
1870             // are clipped according to the 'overflow' property.
1871             context->clip(pixelSnappedIntRect(clipRect));
1872
1873             // Adjust our x and y when painting.
1874             LayoutPoint adjustedPaintOffset = paintOffset + offset;
1875             if (paintingFloats)
1876                 paintFloats(info, adjustedPaintOffset, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
1877             else
1878                 paintContents(info, adjustedPaintOffset);
1879         }
1880
1881         LayoutUnit blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
1882         if (style()->isFlippedBlocksWritingMode())
1883             currLogicalTopOffset += blockDelta;
1884         else
1885             currLogicalTopOffset -= blockDelta;
1886     }
1887 }
1888
1889 void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1890 {
1891     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
1892     // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
1893     // will do a full repaint.
1894     if (document().didLayoutWithPendingStylesheets() && !isRenderView())
1895         return;
1896
1897     if (childrenInline())
1898         m_lineBoxes.paint(this, paintInfo, paintOffset);
1899     else {
1900         PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
1901         newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
1902
1903         // We don't paint our own background, but we do let the kids paint their backgrounds.
1904         PaintInfo paintInfoForChild(paintInfo);
1905         paintInfoForChild.phase = newPhase;
1906         paintInfoForChild.updatePaintingRootForChildren(this);
1907         paintChildren(paintInfoForChild, paintOffset);
1908     }
1909 }
1910
1911 void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1912 {
1913     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox())
1914         paintChild(child, paintInfo, paintOffset);
1915 }
1916
1917 void RenderBlock::paintChild(RenderBox* child, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1918 {
1919     LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
1920     if (!child->hasSelfPaintingLayer() && !child->isFloating())
1921         child->paint(paintInfo, childPoint);
1922 }
1923
1924 void RenderBlock::paintChildAsInlineBlock(RenderBox* child, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1925 {
1926     LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
1927     if (!child->hasSelfPaintingLayer() && !child->isFloating())
1928         paintAsInlineBlock(child, paintInfo, childPoint);
1929 }
1930
1931 void RenderBlock::paintAsInlineBlock(RenderObject* renderer, PaintInfo& paintInfo, const LayoutPoint& childPoint)
1932 {
1933     if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection)
1934         return;
1935
1936     // Paint all phases atomically, as though the element established its own
1937     // stacking context.  (See Appendix E.2, section 7.2.1.4 on
1938     // inline block/table/replaced elements in the CSS2.1 specification.)
1939     // This is also used by other elements (e.g. flex items and grid items).
1940     bool preservePhase = paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip;
1941     PaintInfo info(paintInfo);
1942     info.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
1943     renderer->paint(info, childPoint);
1944     if (!preservePhase) {
1945         info.phase = PaintPhaseChildBlockBackgrounds;
1946         renderer->paint(info, childPoint);
1947         info.phase = PaintPhaseFloat;
1948         renderer->paint(info, childPoint);
1949         info.phase = PaintPhaseForeground;
1950         renderer->paint(info, childPoint);
1951         info.phase = PaintPhaseOutline;
1952         renderer->paint(info, childPoint);
1953     }
1954 }
1955
1956 bool RenderBlock::hasCaret(CaretType type) const
1957 {
1958     // Paint the caret if the FrameSelection says so or if caret browsing is enabled
1959     bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
1960     RenderObject* caretPainter;
1961     bool isContentEditable;
1962     if (type == CursorCaret) {
1963         caretPainter = frame()->selection().caretRenderer();
1964         isContentEditable = frame()->selection().rendererIsEditable();
1965     } else {
1966         caretPainter = frame()->page()->dragCaretController().caretRenderer();
1967         isContentEditable = frame()->page()->dragCaretController().isContentEditable();
1968     }
1969     return caretPainter == this && (isContentEditable || caretBrowsing);
1970 }
1971
1972 void RenderBlock::paintCaret(PaintInfo& paintInfo, const LayoutPoint& paintOffset, CaretType type)
1973 {
1974     if (!hasCaret(type))
1975         return;
1976
1977     if (type == CursorCaret)
1978         frame()->selection().paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
1979     else
1980         frame()->page()->dragCaretController().paintDragCaret(frame(), paintInfo.context, paintOffset, paintInfo.rect);
1981 }
1982
1983 void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1984 {
1985     PaintPhase paintPhase = paintInfo.phase;
1986
1987     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
1988     LayoutPoint scrolledOffset = paintOffset;
1989     if (hasOverflowClip())
1990         scrolledOffset.move(-scrolledContentOffset());
1991
1992     // 1. paint background, borders etc
1993     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
1994         if (hasBoxDecorations())
1995             paintBoxDecorations(paintInfo, paintOffset);
1996         if (hasColumns() && !paintInfo.paintRootBackgroundOnly())
1997             paintColumnRules(paintInfo, scrolledOffset);
1998     }
1999
2000     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
2001         paintMask(paintInfo, paintOffset);
2002         return;
2003     }
2004
2005     if (paintPhase == PaintPhaseClippingMask && style()->visibility() == VISIBLE) {
2006         paintClippingMask(paintInfo, paintOffset);
2007         return;
2008     }
2009
2010     // We're done.  We don't bother painting any children.
2011     if (paintPhase == PaintPhaseBlockBackground || paintInfo.paintRootBackgroundOnly())
2012         return;
2013
2014     // 2. paint contents
2015     if (paintPhase != PaintPhaseSelfOutline) {
2016         if (hasColumns())
2017             paintColumnContents(paintInfo, scrolledOffset);
2018         else
2019             paintContents(paintInfo, scrolledOffset);
2020     }
2021
2022     // 3. paint selection
2023     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
2024     bool isPrinting = document().printing();
2025     if (!isPrinting && !hasColumns())
2026         paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks.
2027
2028     // 4. paint floats.
2029     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
2030         if (hasColumns())
2031             paintColumnContents(paintInfo, scrolledOffset, true);
2032         else
2033             paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
2034     }
2035
2036     // 5. paint outline.
2037     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
2038         paintOutline(paintInfo, LayoutRect(paintOffset, size()));
2039
2040     // 6. paint continuation outlines.
2041     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
2042         RenderInline* inlineCont = inlineElementContinuation();
2043         if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
2044             RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
2045             RenderBlock* cb = containingBlock();
2046
2047             bool inlineEnclosedInSelfPaintingLayer = false;
2048             for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
2049                 if (box->hasSelfPaintingLayer()) {
2050                     inlineEnclosedInSelfPaintingLayer = true;
2051                     break;
2052                 }
2053             }
2054
2055             // Do not add continuations for outline painting by our containing block if we are a relative positioned
2056             // 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
2057             // in the same layer.
2058             if (!inlineEnclosedInSelfPaintingLayer && !hasLayer())
2059                 cb->addContinuationWithOutline(inlineRenderer);
2060             else if (!inlineRenderer->firstLineBox() || (!inlineEnclosedInSelfPaintingLayer && hasLayer()))
2061                 inlineRenderer->paintOutline(paintInfo, paintOffset - locationOffset() + inlineRenderer->containingBlock()->location());
2062         }
2063         paintContinuationOutlines(paintInfo, paintOffset);
2064     }
2065
2066     // 7. paint caret.
2067     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
2068     // then paint the caret.
2069     if (paintPhase == PaintPhaseForeground) {
2070         paintCaret(paintInfo, paintOffset, CursorCaret);
2071         paintCaret(paintInfo, paintOffset, DragCaret);
2072     }
2073 }
2074
2075 RenderInline* RenderBlock::inlineElementContinuation() const
2076 {
2077     RenderBoxModelObject* continuation = this->continuation();
2078     return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
2079 }
2080
2081 RenderBlock* RenderBlock::blockElementContinuation() const
2082 {
2083     RenderBoxModelObject* currentContinuation = continuation();
2084     if (!currentContinuation || currentContinuation->isInline())
2085         return 0;
2086     RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
2087     if (nextContinuation->isAnonymousBlock())
2088         return nextContinuation->blockElementContinuation();
2089     return nextContinuation;
2090 }
2091
2092 static ContinuationOutlineTableMap* continuationOutlineTable()
2093 {
2094     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
2095     return &table;
2096 }
2097
2098 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
2099 {
2100     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
2101     // way of painting.
2102     ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
2103
2104     ContinuationOutlineTableMap* table = continuationOutlineTable();
2105     ListHashSet<RenderInline*>* continuations = table->get(this);
2106     if (!continuations) {
2107         continuations = new ListHashSet<RenderInline*>;
2108         table->set(this, adoptPtr(continuations));
2109     }
2110
2111     continuations->add(flow);
2112 }
2113
2114 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
2115 {
2116     ContinuationOutlineTableMap* table = continuationOutlineTable();
2117     if (table->isEmpty())
2118         return false;
2119
2120     ListHashSet<RenderInline*>* continuations = table->get(this);
2121     if (!continuations)
2122         return false;
2123
2124     return continuations->contains(flow);
2125 }
2126
2127 void RenderBlock::paintContinuationOutlines(PaintInfo& info, const LayoutPoint& paintOffset)
2128 {
2129     ContinuationOutlineTableMap* table = continuationOutlineTable();
2130     if (table->isEmpty())
2131         return;
2132
2133     OwnPtr<ListHashSet<RenderInline*> > continuations = table->take(this);
2134     if (!continuations)
2135         return;
2136
2137     LayoutPoint accumulatedPaintOffset = paintOffset;
2138     // Paint each continuation outline.
2139     ListHashSet<RenderInline*>::iterator end = continuations->end();
2140     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
2141         // Need to add in the coordinates of the intervening blocks.
2142         RenderInline* flow = *it;
2143         RenderBlock* block = flow->containingBlock();
2144         for ( ; block && block != this; block = block->containingBlock())
2145             accumulatedPaintOffset.moveBy(block->location());
2146         ASSERT(block);
2147         flow->paintOutline(info, accumulatedPaintOffset);
2148     }
2149 }
2150
2151 bool RenderBlock::shouldPaintSelectionGaps() const
2152 {
2153     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
2154 }
2155
2156 bool RenderBlock::isSelectionRoot() const
2157 {
2158     if (isPseudoElement())
2159         return false;
2160     ASSERT(node() || isAnonymous());
2161
2162     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
2163     if (isTable())
2164         return false;
2165
2166     if (isBody() || isDocumentElement() || hasOverflowClip()
2167         || isPositioned() || isFloating()
2168         || isTableCell() || isInlineBlockOrInlineTable()
2169         || hasTransform() || hasReflection() || hasMask() || isWritingModeRoot()
2170         || isRenderFlowThread() || isFlexItemIncludingDeprecated())
2171         return true;
2172
2173     if (view() && view()->selectionStart()) {
2174         Node* startElement = view()->selectionStart()->node();
2175         if (startElement && startElement->rootEditableElement() == node())
2176             return true;
2177     }
2178
2179     return false;
2180 }
2181
2182 GapRects RenderBlock::selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer)
2183 {
2184     ASSERT(!needsLayout());
2185
2186     if (!shouldPaintSelectionGaps())
2187         return GapRects();
2188
2189     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
2190     mapLocalToContainer(repaintContainer, transformState, ApplyContainerFlip | UseTransforms);
2191     LayoutPoint offsetFromRepaintContainer = roundedLayoutPoint(transformState.mappedPoint());
2192
2193     if (hasOverflowClip())
2194         offsetFromRepaintContainer -= scrolledContentOffset();
2195
2196     LayoutUnit lastTop = 0;
2197     LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
2198     LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
2199
2200     return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
2201 }
2202
2203 void RenderBlock::paintSelection(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2204 {
2205     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
2206         LayoutUnit lastTop = 0;
2207         LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
2208         LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
2209         GraphicsContextStateSaver stateSaver(*paintInfo.context);
2210
2211         LayoutRect gapRectsBounds = selectionGaps(this, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight, &paintInfo);
2212         if (!gapRectsBounds.isEmpty()) {
2213             RenderLayer* layer = enclosingLayer();
2214             gapRectsBounds.moveBy(-paintOffset);
2215             if (!hasLayer()) {
2216                 LayoutRect localBounds(gapRectsBounds);
2217                 flipForWritingMode(localBounds);
2218                 gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
2219                 if (layer->renderer()->hasOverflowClip())
2220                     gapRectsBounds.move(layer->renderBox()->scrolledContentOffset());
2221             }
2222             layer->addBlockSelectionGapsBounds(gapRectsBounds);
2223         }
2224     }
2225 }
2226
2227 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, TrackedRendererListHashSet* positionedObjects)
2228 {
2229     if (!positionedObjects)
2230         return;
2231
2232     TrackedRendererListHashSet::const_iterator end = positionedObjects->end();
2233     for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
2234         RenderBox* r = *it;
2235         paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
2236     }
2237 }
2238
2239 LayoutUnit RenderBlock::blockDirectionOffset(const LayoutSize& offsetFromBlock) const
2240 {
2241     return isHorizontalWritingMode() ? offsetFromBlock.height() : offsetFromBlock.width();
2242 }
2243
2244 LayoutUnit RenderBlock::inlineDirectionOffset(const LayoutSize& offsetFromBlock) const
2245 {
2246     return isHorizontalWritingMode() ? offsetFromBlock.width() : offsetFromBlock.height();
2247 }
2248
2249 LayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPhysicalPosition, const LayoutRect& logicalRect)
2250 {
2251     LayoutRect result;
2252     if (isHorizontalWritingMode())
2253         result = logicalRect;
2254     else
2255         result = LayoutRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
2256     flipForWritingMode(result);
2257     result.moveBy(rootBlockPhysicalPosition);
2258     return result;
2259 }
2260
2261 GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2262                                     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
2263 {
2264     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
2265     // Clip out floating and positioned objects when painting selection gaps.
2266     if (paintInfo) {
2267         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
2268         LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
2269         rootBlock->flipForWritingMode(flippedBlockRect);
2270         flippedBlockRect.moveBy(rootBlockPhysicalPosition);
2271         clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positionedObjects());
2272         if (isBody() || isDocumentElement()) // The <body> must make sure to examine its containingBlock's positioned objects.
2273             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
2274                 clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->positionedObjects()); // FIXME: Not right for flipped writing modes.
2275         clipOutFloatingObjects(rootBlock, paintInfo, rootBlockPhysicalPosition, offsetFromRootBlock);
2276     }
2277
2278     // 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
2279     // fixed).
2280     GapRects result;
2281     if (!isRenderBlockFlow() && !isFlexibleBoxIncludingDeprecated()) // FIXME: Make multi-column selection gap filling work someday.
2282         return result;
2283
2284     if (hasColumns() || hasTransform() || style()->columnSpan()) {
2285         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
2286         lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalHeight();
2287         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
2288         lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
2289         return result;
2290     }
2291
2292     if (childrenInline())
2293         result = toRenderBlockFlow(this)->inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
2294     else
2295         result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
2296
2297     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
2298     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
2299         result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
2300                                              logicalHeight(), paintInfo));
2301     return result;
2302 }
2303
2304 GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2305                                          LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
2306 {
2307     GapRects result;
2308
2309     // Go ahead and jump right to the first block child that contains some selected objects.
2310     RenderBox* curr;
2311     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
2312
2313     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
2314         SelectionState childState = curr->selectionState();
2315         if (childState == SelectionBoth || childState == SelectionEnd)
2316             sawSelectionEnd = true;
2317
2318         if (curr->isFloatingOrOutOfFlowPositioned())
2319             continue; // We must be a normal flow object in order to even be considered.
2320
2321         if (curr->isInFlowPositioned() && curr->hasLayer()) {
2322             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
2323             // Just disregard it completely.
2324             LayoutSize relOffset = curr->layer()->offsetForInFlowPosition();
2325             if (relOffset.width() || relOffset.height())
2326                 continue;
2327         }
2328
2329         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
2330         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
2331         if (fillBlockGaps) {
2332             // We need to fill the vertical gap above this object.
2333             if (childState == SelectionEnd || childState == SelectionInside)
2334                 // Fill the gap above the object.
2335                 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
2336                                                      curr->logicalTop(), paintInfo));
2337
2338             // 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*
2339             // our object.  We know this if the selection did not end inside our object.
2340             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
2341                 childState = SelectionNone;
2342
2343             // Fill side gaps on this object based off its state.
2344             bool leftGap, rightGap;
2345             getSelectionGapInfo(childState, leftGap, rightGap);
2346
2347             if (leftGap)
2348                 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
2349             if (rightGap)
2350                 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
2351
2352             // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
2353             // they can without bumping into floating or positioned objects.  Ideally they will go right up
2354             // to the border of the root selection block.
2355             lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + curr->logicalBottom();
2356             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
2357             lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
2358         } else if (childState != SelectionNone)
2359             // We must be a block that has some selected object inside it.  Go ahead and recur.
2360             result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
2361                                                             lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
2362     }
2363     return result;
2364 }
2365
2366 LayoutRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2367                                           LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo* paintInfo)
2368 {
2369     LayoutUnit logicalTop = lastLogicalTop;
2370     LayoutUnit logicalHeight = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalBottom - logicalTop;
2371     if (logicalHeight <= 0)
2372         return LayoutRect();
2373
2374     // Get the selection offsets for the bottom of the gap
2375     LayoutUnit logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
2376     LayoutUnit logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
2377     LayoutUnit logicalWidth = logicalRight - logicalLeft;
2378     if (logicalWidth <= 0)
2379         return LayoutRect();
2380
2381     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
2382     if (paintInfo)
2383         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selectionBackgroundColor());
2384     return gapRect;
2385 }
2386
2387 LayoutRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2388                                                 RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
2389 {
2390     LayoutUnit rootBlockLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalTop;
2391     LayoutUnit rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
2392     LayoutUnit rootBlockLogicalRight = min(rootBlock->inlineDirectionOffset(offsetFromRootBlock) + floorToInt(logicalLeft), min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
2393     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
2394     if (rootBlockLogicalWidth <= 0)
2395         return LayoutRect();
2396
2397     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
2398     if (paintInfo)
2399         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor());
2400     return gapRect;
2401 }
2402
2403 LayoutRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2404                                                  RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
2405 {
2406     LayoutUnit rootBlockLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalTop;
2407     LayoutUnit rootBlockLogicalLeft = max(rootBlock->inlineDirectionOffset(offsetFromRootBlock) + floorToInt(logicalRight), max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
2408     LayoutUnit rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
2409     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
2410     if (rootBlockLogicalWidth <= 0)
2411         return LayoutRect();
2412
2413     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
2414     if (paintInfo)
2415         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor());
2416     return gapRect;
2417 }
2418
2419 void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
2420 {
2421     bool ltr = style()->isLeftToRightDirection();
2422     leftGap = (state == RenderObject::SelectionInside) ||
2423               (state == RenderObject::SelectionEnd && ltr) ||
2424               (state == RenderObject::SelectionStart && !ltr);
2425     rightGap = (state == RenderObject::SelectionInside) ||
2426                (state == RenderObject::SelectionStart && ltr) ||
2427                (state == RenderObject::SelectionEnd && !ltr);
2428 }
2429
2430 LayoutUnit RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
2431 {
2432     // The border can potentially be further extended by our containingBlock().
2433     if (rootBlock != this)
2434         return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
2435     return logicalLeftOffsetForContent();
2436 }
2437
2438 LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
2439 {
2440     // The border can potentially be further extended by our containingBlock().
2441     if (rootBlock != this)
2442         return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
2443     return logicalRightOffsetForContent();
2444 }
2445
2446 RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
2447 {
2448     if (isSelectionRoot())
2449         return 0;
2450
2451     const RenderObject* object = this;
2452     RenderObject* sibling;
2453     do {
2454         sibling = object->previousSibling();
2455         while (sibling && (!sibling->isRenderBlock() || toRenderBlock(sibling)->isSelectionRoot()))
2456             sibling = sibling->previousSibling();
2457
2458         offset -= LayoutSize(toRenderBlock(object)->logicalLeft(), toRenderBlock(object)->logicalTop());
2459         object = object->parent();
2460     } while (!sibling && object && object->isRenderBlock() && !toRenderBlock(object)->isSelectionRoot());
2461
2462     if (!sibling)
2463         return 0;
2464
2465     RenderBlock* beforeBlock = toRenderBlock(sibling);
2466
2467     offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
2468
2469     RenderObject* child = beforeBlock->lastChild();
2470     while (child && child->isRenderBlock()) {
2471         beforeBlock = toRenderBlock(child);
2472         offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
2473         child = beforeBlock->lastChild();
2474     }
2475     return beforeBlock;
2476 }
2477
2478 void RenderBlock::insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
2479 {
2480     if (!descendantsMap) {
2481         descendantsMap = new TrackedDescendantsMap;
2482         containerMap = new TrackedContainerMap;
2483     }
2484
2485     TrackedRendererListHashSet* descendantSet = descendantsMap->get(this);
2486     if (!descendantSet) {
2487         descendantSet = new TrackedRendererListHashSet;
2488         descendantsMap->set(this, adoptPtr(descendantSet));
2489     }
2490     bool added = descendantSet->add(descendant).isNewEntry;
2491     if (!added) {
2492         ASSERT(containerMap->get(descendant));
2493         ASSERT(containerMap->get(descendant)->contains(this));
2494         return;
2495     }
2496
2497     HashSet<RenderBlock*>* containerSet = containerMap->get(descendant);
2498     if (!containerSet) {
2499         containerSet = new HashSet<RenderBlock*>;
2500         containerMap->set(descendant, adoptPtr(containerSet));
2501     }
2502     ASSERT(!containerSet->contains(this));
2503     containerSet->add(this);
2504 }
2505
2506 void RenderBlock::removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
2507 {
2508     if (!descendantsMap)
2509         return;
2510
2511     OwnPtr<HashSet<RenderBlock*> > containerSet = containerMap->take(descendant);
2512     if (!containerSet)
2513         return;
2514
2515     HashSet<RenderBlock*>::iterator end = containerSet->end();
2516     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
2517         RenderBlock* container = *it;
2518
2519         // FIXME: Disabling this assert temporarily until we fix the layout
2520         // bugs associated with positioned objects not properly cleared from
2521         // their ancestor chain before being moved. See webkit bug 93766.
2522         // ASSERT(descendant->isDescendantOf(container));
2523
2524         TrackedDescendantsMap::iterator descendantsMapIterator = descendantsMap->find(container);
2525         ASSERT(descendantsMapIterator != descendantsMap->end());
2526         if (descendantsMapIterator == descendantsMap->end())
2527             continue;
2528         TrackedRendererListHashSet* descendantSet = descendantsMapIterator->value.get();
2529         ASSERT(descendantSet->contains(descendant));
2530         descendantSet->remove(descendant);
2531         if (descendantSet->isEmpty())
2532             descendantsMap->remove(descendantsMapIterator);
2533     }
2534 }
2535
2536 TrackedRendererListHashSet* RenderBlock::positionedObjects() const
2537 {
2538     if (gPositionedDescendantsMap)
2539         return gPositionedDescendantsMap->get(this);
2540     return 0;
2541 }
2542
2543 void RenderBlock::insertPositionedObject(RenderBox* o)
2544 {
2545     ASSERT(!isAnonymousBlock());
2546
2547     if (o->isRenderFlowThread())
2548         return;
2549
2550     insertIntoTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
2551 }
2552
2553 void RenderBlock::removePositionedObject(RenderBox* o)
2554 {
2555     removeFromTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
2556 }
2557
2558 void RenderBlock::removePositionedObjects(RenderBlock* o, ContainingBlockState containingBlockState)
2559 {
2560     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
2561     if (!positionedDescendants)
2562         return;
2563
2564     RenderBox* r;
2565
2566     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
2567
2568     Vector<RenderBox*, 16> deadObjects;
2569
2570     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
2571         r = *it;
2572         if (!o || r->isDescendantOf(o)) {
2573             if (containingBlockState == NewContainingBlock)
2574                 r->setChildNeedsLayout(MarkOnlyThis);
2575
2576             // It is parent blocks job to add positioned child to positioned objects list of its containing block
2577             // Parent layout needs to be invalidated to ensure this happens.
2578             RenderObject* p = r->parent();
2579             while (p && !p->isRenderBlock())
2580                 p = p->parent();
2581             if (p)
2582                 p->setChildNeedsLayout();
2583
2584             deadObjects.append(r);
2585         }
2586     }
2587
2588     for (unsigned i = 0; i < deadObjects.size(); i++)
2589         removePositionedObject(deadObjects.at(i));
2590 }
2591
2592 void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
2593 {
2594     insertIntoTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
2595 }
2596
2597 void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
2598 {
2599     removeFromTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
2600 }
2601
2602 TrackedRendererListHashSet* RenderBlock::percentHeightDescendants() const
2603 {
2604     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
2605 }
2606
2607 bool RenderBlock::hasPercentHeightContainerMap()
2608 {
2609     return gPercentHeightContainerMap;
2610 }
2611
2612 bool RenderBlock::hasPercentHeightDescendant(RenderBox* descendant)
2613 {
2614     // We don't null check gPercentHeightContainerMap since the caller
2615     // already ensures this and we need to call this function on every
2616     // descendant in clearPercentHeightDescendantsFrom().
2617     ASSERT(gPercentHeightContainerMap);
2618     return gPercentHeightContainerMap->contains(descendant);
2619 }
2620
2621 void RenderBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutScope& layoutScope)
2622 {
2623     if (!gPercentHeightDescendantsMap)
2624         return;
2625
2626     TrackedRendererListHashSet* descendants = gPercentHeightDescendantsMap->get(this);
2627     if (!descendants)
2628         return;
2629
2630     TrackedRendererListHashSet::iterator end = descendants->end();
2631     for (TrackedRendererListHashSet::iterator it = descendants->begin(); it != end; ++it) {
2632         RenderBox* box = *it;
2633         while (box != this) {
2634             if (box->normalChildNeedsLayout())
2635                 break;
2636             layoutScope.setChildNeedsLayout(box);
2637             box = box->containingBlock();
2638             ASSERT(box);
2639             if (!box)
2640                 break;
2641         }
2642     }
2643 }
2644
2645 void RenderBlock::removePercentHeightDescendantIfNeeded(RenderBox* descendant)
2646 {
2647     // We query the map directly, rather than looking at style's
2648     // logicalHeight()/logicalMinHeight()/logicalMaxHeight() since those
2649     // can change with writing mode/directional changes.
2650     if (!hasPercentHeightContainerMap())
2651         return;
2652
2653     if (!hasPercentHeightDescendant(descendant))
2654         return;
2655
2656     removePercentHeightDescendant(descendant);
2657 }
2658
2659 void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox* parent)
2660 {
2661     ASSERT(gPercentHeightContainerMap);
2662     for (RenderObject* curr = parent->firstChild(); curr; curr = curr->nextInPreOrder(parent)) {
2663         if (!curr->isBox())
2664             continue;
2665
2666         RenderBox* box = toRenderBox(curr);
2667         if (!hasPercentHeightDescendant(box))
2668             continue;
2669
2670         removePercentHeightDescendant(box);
2671     }
2672 }
2673
2674 LayoutUnit RenderBlock::textIndentOffset() const
2675 {
2676     LayoutUnit cw = 0;
2677     if (style()->textIndent().isPercent())
2678         cw = containingBlock()->availableLogicalWidth();
2679     return minimumValueForLength(style()->textIndent(), cw);
2680 }
2681
2682 void RenderBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest)
2683 {
2684     if (logicalTop >= logicalBottom)
2685         return;
2686
2687     RootInlineBox* lowestDirtyLine = lastRootBox();
2688     RootInlineBox* afterLowest = lowestDirtyLine;
2689     while (lowestDirtyLine && lowestDirtyLine->lineBottomWithLeading() >= logicalBottom && logicalBottom < LayoutUnit::max()) {
2690         afterLowest = lowestDirtyLine;
2691         lowestDirtyLine = lowestDirtyLine->prevRootBox();
2692     }
2693
2694     while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWithLeading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) {
2695         afterLowest->markDirty();
2696         afterLowest = afterLowest->prevRootBox();
2697     }
2698 }
2699
2700 bool RenderBlock::isPointInOverflowControl(HitTestResult& result, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset)
2701 {
2702     if (!scrollsOverflow())
2703         return false;
2704
2705     return layer()->scrollableArea()->hitTestOverflowControls(result, roundedIntPoint(locationInContainer - toLayoutSize(accumulatedOffset)));
2706 }
2707
2708 Node* RenderBlock::nodeForHitTest() const
2709 {
2710     // If we are in the margins of block elements that are part of a
2711     // continuation we're actually still inside the enclosing element
2712     // that was split. Use the appropriate inner node.
2713     return isAnonymousBlockContinuation() ? continuation()->node() : node();
2714 }
2715
2716 bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
2717 {
2718     LayoutPoint adjustedLocation(accumulatedOffset + location());
2719     LayoutSize localOffset = toLayoutSize(adjustedLocation);
2720
2721     if (!isRenderView()) {
2722         // Check if we need to do anything at all.
2723         // If we have clipping, then we can't have any spillout.
2724         LayoutRect overflowBox = hasOverflowClip() ? borderBoxRect() : visualOverflowRect();
2725         flipForWritingMode(overflowBox);
2726         overflowBox.moveBy(adjustedLocation);
2727         if (!locationInContainer.intersects(overflowBox))
2728             return false;
2729     }
2730
2731     if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground)
2732         && visibleToHitTestRequest(request)
2733         && isPointInOverflowControl(result, locationInContainer.point(), adjustedLocation)) {
2734         updateHitTestResult(result, locationInContainer.point() - localOffset);
2735         // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
2736         if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer))
2737            return true;
2738     }
2739
2740     if (style()->clipPath()) {
2741         switch (style()->clipPath()->type()) {
2742         case ClipPathOperation::SHAPE: {
2743             ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()->clipPath());
2744             // FIXME: handle marginBox etc.
2745             if (!clipPath->path(borderBoxRect()).contains(locationInContainer.point() - localOffset, clipPath->windRule()))
2746                 return false;
2747             break;
2748         }
2749         case ClipPathOperation::REFERENCE:
2750             // FIXME: handle REFERENCE
2751             break;
2752         }
2753     }
2754
2755     // If we have clipping, then we can't have any spillout.
2756     bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
2757     bool useClip = (hasControlClip() || useOverflowClip);
2758     bool checkChildren = !useClip || (hasControlClip() ? locationInContainer.intersects(controlClipRect(adjustedLocation)) : locationInContainer.intersects(overflowClipRect(adjustedLocation, IncludeOverlayScrollbarSize)));
2759     if (checkChildren) {
2760         // Hit test descendants first.
2761         LayoutSize scrolledOffset(localOffset);
2762         if (hasOverflowClip())
2763             scrolledOffset -= scrolledContentOffset();
2764
2765         // Hit test contents if we don't have columns.
2766         if (!hasColumns()) {
2767             if (hitTestContents(request, result, locationInContainer, toLayoutPoint(scrolledOffset), hitTestAction)) {
2768                 updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
2769                 return true;
2770             }
2771             if (hitTestAction == HitTestFloat && hitTestFloats(request, result, locationInContainer, toLayoutPoint(scrolledOffset)))
2772                 return true;
2773         } else if (hitTestColumns(request, result, locationInContainer, toLayoutPoint(scrolledOffset), hitTestAction)) {
2774             updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
2775             return true;
2776         }
2777     }
2778
2779     // Check if the point is outside radii.
2780     if (!isRenderView() && style()->hasBorderRadius()) {
2781         LayoutRect borderRect = borderBoxRect();
2782         borderRect.moveBy(adjustedLocation);
2783         RoundedRect border = style()->getRoundedBorderFor(borderRect);
2784         if (!locationInContainer.intersects(border))
2785             return false;
2786     }
2787
2788     // Now hit test our background
2789     if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
2790         LayoutRect boundsRect(adjustedLocation, size());
2791         if (visibleToHitTestRequest(request) && locationInContainer.intersects(boundsRect)) {
2792             updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
2793             if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer, boundsRect))
2794                 return true;
2795         }
2796     }
2797
2798     return false;
2799 }
2800
2801 class ColumnRectIterator {
2802     WTF_MAKE_NONCOPYABLE(ColumnRectIterator);
2803 public:
2804     ColumnRectIterator(const RenderBlock& block)
2805         : m_block(block)
2806         , m_colInfo(block.columnInfo())
2807         , m_direction(m_block.style()->isFlippedBlocksWritingMode() ? 1 : -1)
2808         , m_isHorizontal(block.isHorizontalWritingMode())
2809         , m_logicalLeft(block.logicalLeftOffsetForContent())
2810     {
2811         int colCount = m_colInfo->columnCount();
2812         m_colIndex = colCount - 1;
2813         m_currLogicalTopOffset = colCount * m_colInfo->columnHeight() * m_direction;
2814         update();
2815     }
2816
2817     void advance()
2818     {
2819         ASSERT(hasMore());
2820         m_colIndex--;
2821         update();
2822     }
2823
2824     LayoutRect columnRect() const { return m_colRect; }
2825     bool hasMore() const { return m_colIndex >= 0; }
2826
2827     void adjust(LayoutSize& offset) const
2828     {
2829         LayoutUnit currLogicalLeftOffset = (m_isHorizontal ? m_colRect.x() : m_colRect.y()) - m_logicalLeft;
2830         offset += m_isHorizontal ? LayoutSize(currLogicalLeftOffset, m_currLogicalTopOffset) : LayoutSize(m_currLogicalTopOffset, currLogicalLeftOffset);
2831         if (m_colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
2832             if (m_isHorizontal)
2833                 offset.expand(0, m_colRect.y() - m_block.borderTop() - m_block.paddingTop());
2834             else
2835                 offset.expand(m_colRect.x() - m_block.borderLeft() - m_block.paddingLeft(), 0);
2836         }
2837     }
2838
2839 private:
2840     void update()
2841     {
2842         if (m_colIndex < 0)
2843             return;
2844
2845         m_colRect = m_block.columnRectAt(const_cast<ColumnInfo*>(m_colInfo), m_colIndex);
2846         m_block.flipForWritingMode(m_colRect);
2847         m_currLogicalTopOffset -= (m_isHorizontal ? m_colRect.height() : m_colRect.width()) * m_direction;
2848     }
2849
2850     const RenderBlock& m_block;
2851     const ColumnInfo* const m_colInfo;
2852     const int m_direction;
2853     const bool m_isHorizontal;
2854     const LayoutUnit m_logicalLeft;
2855     int m_colIndex;
2856     LayoutUnit m_currLogicalTopOffset;
2857     LayoutRect m_colRect;
2858 };
2859
2860 bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
2861 {
2862     // We need to do multiple passes, breaking up our hit testing into strips.
2863     if (!hasColumns())
2864         return false;
2865
2866     for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) {
2867         LayoutRect hitRect = locationInContainer.boundingBox();
2868         LayoutRect colRect = it.columnRect();
2869         colRect.moveBy(accumulatedOffset);
2870         if (locationInContainer.intersects(colRect)) {
2871             // The point is inside this column.
2872             // Adjust accumulatedOffset to change where we hit test.
2873             LayoutSize offset;
2874             it.adjust(offset);
2875             LayoutPoint finalLocation = accumulatedOffset + offset;
2876             if (!result.isRectBasedTest() || colRect.contains(hitRect))
2877                 return hitTestContents(request, result, locationInContainer, finalLocation, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, locationInContainer, finalLocation));
2878
2879             hitTestContents(request, result, locationInContainer, finalLocation, hitTestAction);
2880         }
2881     }
2882
2883     return false;
2884 }
2885
2886 void RenderBlock::adjustForColumnRect(LayoutSize& offset, const LayoutPoint& locationInContainer) const
2887 {
2888     for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) {
2889         LayoutRect colRect = it.columnRect();
2890         if (colRect.contains(locationInContainer)) {
2891             it.adjust(offset);
2892             return;
2893         }
2894     }
2895 }
2896
2897 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
2898 {
2899     if (childrenInline() && !isTable()) {
2900         // We have to hit-test our line boxes.
2901         if (m_lineBoxes.hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction))
2902             return true;
2903     } else {
2904         // Hit test our children.
2905         HitTestAction childHitTest = hitTestAction;
2906         if (hitTestAction == HitTestChildBlockBackgrounds)
2907             childHitTest = HitTestChildBlockBackground;
2908         for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
2909             LayoutPoint childPoint = flipForWritingModeForChild(child, accumulatedOffset);
2910             if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, locationInContainer, childPoint, childHitTest))
2911                 return true;
2912         }
2913     }
2914
2915     return false;
2916 }
2917
2918 Position RenderBlock::positionForBox(InlineBox *box, bool start) const
2919 {
2920     if (!box)
2921         return Position();
2922
2923     if (!box->renderer().nonPseudoNode())
2924         return createLegacyEditingPosition(nonPseudoNode(), start ? caretMinOffset() : caretMaxOffset());
2925
2926     if (!box->isInlineTextBox())
2927         return createLegacyEditingPosition(box->renderer().nonPseudoNode(), start ? box->renderer().caretMinOffset() : box->renderer().caretMaxOffset());
2928
2929     InlineTextBox* textBox = toInlineTextBox(box);
2930     return createLegacyEditingPosition(box->renderer().nonPseudoNode(), start ? textBox->start() : textBox->start() + textBox->len());
2931 }
2932
2933 static inline bool isEditingBoundary(RenderObject* ancestor, RenderObject* child)
2934 {
2935     ASSERT(!ancestor || ancestor->nonPseudoNode());
2936     ASSERT(child && child->nonPseudoNode());
2937     return !ancestor || !ancestor->parent() || (ancestor->hasLayer() && ancestor->parent()->isRenderView())
2938         || ancestor->nonPseudoNode()->rendererIsEditable() == child->nonPseudoNode()->rendererIsEditable();
2939 }
2940
2941 // FIXME: This function should go on RenderObject as an instance method. Then
2942 // all cases in which positionForPoint recurs could call this instead to
2943 // prevent crossing editable boundaries. This would require many tests.
2944 static PositionWithAffinity positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const LayoutPoint& pointInParentCoordinates)
2945 {
2946     LayoutPoint childLocation = child->location();
2947     if (child->isInFlowPositioned())
2948         childLocation += child->offsetForInFlowPosition();
2949
2950     // FIXME: This is wrong if the child's writing-mode is different from the parent's.
2951     LayoutPoint pointInChildCoordinates(toLayoutPoint(pointInParentCoordinates - childLocation));
2952
2953     // If this is an anonymous renderer, we just recur normally
2954     Node* childNode = child->nonPseudoNode();
2955     if (!childNode)
2956         return child->positionForPoint(pointInChildCoordinates);
2957
2958     // Otherwise, first make sure that the editability of the parent and child agree.
2959     // If they don't agree, then we return a visible position just before or after the child
2960     RenderObject* ancestor = parent;
2961     while (ancestor && !ancestor->nonPseudoNode())
2962         ancestor = ancestor->parent();
2963
2964     // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
2965     if (isEditingBoundary(ancestor, child))
2966         return child->positionForPoint(pointInChildCoordinates);
2967
2968     // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
2969     LayoutUnit childMiddle = parent->logicalWidthForChild(child) / 2;
2970     LayoutUnit logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
2971     if (logicalLeft < childMiddle)
2972         return ancestor->createPositionWithAffinity(childNode->nodeIndex(), DOWNSTREAM);
2973     return ancestor->createPositionWithAffinity(childNode->nodeIndex() + 1, UPSTREAM);
2974 }
2975
2976 PositionWithAffinity RenderBlock::positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents)
2977 {
2978     ASSERT(childrenInline());
2979
2980     if (!firstRootBox())
2981         return createPositionWithAffinity(0, DOWNSTREAM);
2982
2983     bool linesAreFlipped = style()->isFlippedLinesWritingMode();
2984     bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
2985
2986     // look for the closest line box in the root box which is at the passed-in y coordinate
2987     InlineBox* closestBox = 0;
2988     RootInlineBox* firstRootBoxWithChildren = 0;
2989     RootInlineBox* lastRootBoxWithChildren = 0;
2990     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
2991         if (!root->firstLeafChild())
2992             continue;
2993         if (!firstRootBoxWithChildren)
2994             firstRootBoxWithChildren = root;
2995
2996         if (!linesAreFlipped && root->isFirstAfterPageBreak() && (pointInLogicalContents.y() < root->lineTopWithLeading()
2997             || (blocksAreFlipped && pointInLogicalContents.y() == root->lineTopWithLeading())))
2998             break;
2999
3000         lastRootBoxWithChildren = root;
3001
3002         // check if this root line box is located at this y coordinate
3003         if (pointInLogicalContents.y() < root->selectionBottom() || (blocksAreFlipped && pointInLogicalContents.y() == root->selectionBottom())) {
3004             if (linesAreFlipped) {
3005                 RootInlineBox* nextRootBoxWithChildren = root->nextRootBox();
3006                 while (nextRootBoxWithChildren && !nextRootBoxWithChildren->firstLeafChild())
3007                     nextRootBoxWithChildren = nextRootBoxWithChildren->nextRootBox();
3008
3009                 if (nextRootBoxWithChildren && nextRootBoxWithChildren->isFirstAfterPageBreak() && (pointInLogicalContents.y() > nextRootBoxWithChildren->lineTopWithLeading()
3010                     || (!blocksAreFlipped && pointInLogicalContents.y() == nextRootBoxWithChildren->lineTopWithLeading())))
3011                     continue;
3012             }
3013             closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
3014             if (closestBox)
3015                 break;
3016         }
3017     }
3018
3019     bool moveCaretToBoundary = document().frame()->editor().behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
3020
3021     if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
3022         // y coordinate is below last root line box, pretend we hit it
3023         closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
3024     }
3025
3026     if (closestBox) {
3027         if (moveCaretToBoundary) {
3028             LayoutUnit firstRootBoxWithChildrenTop = min<LayoutUnit>(firstRootBoxWithChildren->selectionTop(), firstRootBoxWithChildren->logicalTop());
3029             if (pointInLogicalContents.y() < firstRootBoxWithChildrenTop
3030                 || (blocksAreFlipped && pointInLogicalContents.y() == firstRootBoxWithChildrenTop)) {
3031                 InlineBox* box = firstRootBoxWithChildren->firstLeafChild();
3032                 if (box->isLineBreak()) {
3033                     if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak())
3034                         box = newBox;
3035                 }
3036                 // y coordinate is above first root line box, so return the start of the first
3037                 return PositionWithAffinity(positionForBox(box, true), DOWNSTREAM);
3038             }
3039         }
3040
3041         // pass the box a top position that is inside it
3042         LayoutPoint point(pointInLogicalContents.x(), closestBox->root().blockDirectionPointInLine());
3043         if (!isHorizontalWritingMode())
3044             point = point.transposedPoint();
3045         if (closestBox->renderer().isReplaced())
3046             return positionForPointRespectingEditingBoundaries(this, &toRenderBox(closestBox->renderer()), point);
3047         return closestBox->renderer().positionForPoint(point);
3048     }
3049
3050     if (lastRootBoxWithChildren) {
3051         // We hit this case for Mac behavior when the Y coordinate is below the last box.
3052         ASSERT(moveCaretToBoundary);
3053         InlineBox* logicallyLastBox;
3054         if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
3055             return PositionWithAffinity(positionForBox(logicallyLastBox, false), DOWNSTREAM);
3056     }
3057
3058     // Can't reach this. We have a root line box, but it has no kids.
3059     // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
3060     // seems to hit this code path.
3061     return createPositionWithAffinity(0, DOWNSTREAM);
3062 }
3063
3064 static inline bool isChildHitTestCandidate(RenderBox* box)
3065 {
3066     return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrOutOfFlowPositioned();
3067 }
3068
3069 PositionWithAffinity RenderBlock::positionForPoint(const LayoutPoint& point)
3070 {
3071     if (isTable())
3072         return RenderBox::positionForPoint(point);
3073
3074     if (isReplaced()) {
3075         // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
3076         LayoutUnit pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
3077         LayoutUnit pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
3078
3079         if (pointLogicalLeft < 0)
3080             return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM);
3081         if (pointLogicalLeft >= logicalWidth())
3082             return createPositionWithAffinity(caretMaxOffset(), DOWNSTREAM);
3083         if (pointLogicalTop < 0)
3084             return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM);
3085         if (pointLogicalTop >= logicalHeight())
3086             return createPositionWithAffinity(caretMaxOffset(), DOWNSTREAM);
3087     }
3088
3089     LayoutPoint pointInContents = point;
3090     offsetForContents(pointInContents);
3091     LayoutPoint pointInLogicalContents(pointInContents);
3092     if (!isHorizontalWritingMode())
3093         pointInLogicalContents = pointInLogicalContents.transposedPoint();
3094
3095     if (childrenInline())
3096         return positionForPointWithInlineChildren(pointInLogicalContents);
3097
3098     RenderBox* lastCandidateBox = lastChildBox();
3099     while (lastCandidateBox && !isChildHitTestCandidate(lastCandidateBox))
3100         lastCandidateBox = lastCandidateBox->previousSiblingBox();
3101
3102     bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
3103     if (lastCandidateBox) {
3104         if (pointInLogicalContents.y() > logicalTopForChild(lastCandidateBox)
3105             || (!blocksAreFlipped && pointInLogicalContents.y() == logicalTopForChild(lastCandidateBox)))
3106             return positionForPointRespectingEditingBoundaries(this, lastCandidateBox, pointInContents);
3107
3108         for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
3109             if (!isChildHitTestCandidate(childBox))
3110                 continue;
3111             LayoutUnit childLogicalBottom = logicalTopForChild(childBox) + logicalHeightForChild(childBox);
3112             // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
3113             if (isChildHitTestCandidate(childBox) && (pointInLogicalContents.y() < childLogicalBottom
3114                 || (blocksAreFlipped && pointInLogicalContents.y() == childLogicalBottom)))
3115                 return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
3116         }
3117     }
3118
3119     // We only get here if there are no hit test candidate children below the click.
3120     return RenderBox::positionForPoint(point);
3121 }
3122
3123 void RenderBlock::offsetForContents(LayoutPoint& offset) const
3124 {
3125     offset = flipForWritingMode(offset);
3126
3127     if (hasOverflowClip())
3128         offset += scrolledContentOffset();
3129
3130     if (hasColumns())
3131         adjustPointToColumnContents(offset);
3132
3133     offset = flipForWritingMode(offset);
3134 }
3135
3136 LayoutUnit RenderBlock::availableLogicalWidth() const
3137 {
3138     // If we have multiple columns, then the available logical width is reduced to our column width.
3139     if (hasColumns())
3140         return desiredColumnWidth();
3141     return RenderBox::availableLogicalWidth();
3142 }
3143
3144 int RenderBlock::columnGap() const
3145 {
3146     if (style()->hasNormalColumnGap())
3147         return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
3148     return static_cast<int>(style()->columnGap());
3149 }
3150
3151 void RenderBlock::calcColumnWidth()
3152 {
3153     if (document().regionBasedColumnsEnabled())
3154         return;
3155
3156     // Calculate our column width and column count.
3157     // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
3158     unsigned desiredColumnCount = 1;
3159     LayoutUnit desiredColumnWidth = contentLogicalWidth();
3160
3161     // For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
3162     if (document().paginated() || !style()->specifiesColumns()) {
3163         setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
3164         return;
3165     }
3166
3167     LayoutUnit availWidth = desiredColumnWidth;
3168     LayoutUnit colGap = columnGap();
3169     LayoutUnit colWidth = max<LayoutUnit>(1, LayoutUnit(style()->columnWidth()));
3170     int colCount = max<int>(1, style()->columnCount());
3171
3172     if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
3173         desiredColumnCount = colCount;
3174         desiredColumnWidth = max<LayoutUnit>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount);
3175     } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
3176         desiredColumnCount = max<LayoutUnit>(1, (availWidth + colGap) / (colWidth + colGap));
3177         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
3178     } else {
3179         desiredColumnCount = max<LayoutUnit>(min<LayoutUnit>(colCount, (availWidth + colGap) / (colWidth + colGap)), 1);
3180         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
3181     }
3182     setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
3183 }
3184
3185 bool RenderBlock::requiresColumns(int desiredColumnCount) const
3186 {
3187     // Paged overflow is treated as multicol here, unless this element was the one that got its
3188     // overflow propagated to the viewport.
3189     bool isPaginated = style()->isOverflowPaged() && node() != document().viewportDefiningElement();
3190
3191     return firstChild()
3192         && (desiredColumnCount != 1 || !style()->hasAutoColumnWidth() || isPaginated)
3193         && !firstChild()->isAnonymousColumnsBlock()
3194         && !firstChild()->isAnonymousColumnSpanBlock();
3195 }
3196
3197 void RenderBlock::setDesiredColumnCountAndWidth(int count, LayoutUnit width)
3198 {
3199     bool destroyColumns = !requiresColumns(count);
3200     if (destroyColumns) {
3201         if (hasColumns()) {
3202             gColumnInfoMap->take(this);
3203             setHasColumns(false);
3204         }
3205     } else {
3206         ColumnInfo* info;
3207         if (hasColumns())
3208             info = gColumnInfoMap->get(this);
3209         else {
3210             if (!gColumnInfoMap)
3211                 gColumnInfoMap = new ColumnInfoMap;
3212             info = new ColumnInfo;
3213             gColumnInfoMap->add(this, adoptPtr(info));
3214             setHasColumns(true);
3215         }
3216         info->setDesiredColumnWidth(width);
3217         if (style()->isOverflowPaged()) {
3218             info->setDesiredColumnCount(1);
3219             info->setProgressionAxis(style()->hasInlinePaginationAxis() ? ColumnInfo::InlineAxis : ColumnInfo::BlockAxis);
3220         } else {
3221             info->setDesiredColumnCount(count);
3222             info->setProgressionAxis(ColumnInfo::InlineAxis);
3223         }
3224     }
3225 }
3226
3227 LayoutUnit RenderBlock::desiredColumnWidth() const
3228 {
3229     if (!hasColumns())
3230         return contentLogicalWidth();
3231     return gColumnInfoMap->get(this)->desiredColumnWidth();
3232 }
3233
3234 ColumnInfo* RenderBlock::columnInfo() const
3235 {
3236     if (!hasColumns())
3237         return 0;
3238     return gColumnInfoMap->get(this);
3239 }
3240
3241 unsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
3242 {
3243     ASSERT(hasColumns());
3244     ASSERT(gColumnInfoMap->get(this) == colInfo);
3245     return colInfo->columnCount();
3246 }
3247
3248 LayoutRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
3249 {
3250     ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
3251
3252     // Compute the appropriate rect based off our information.
3253     LayoutUnit colLogicalWidth = colInfo->desiredColumnWidth();
3254     LayoutUnit colLogicalHeight = colInfo->columnHeight();
3255     LayoutUnit colLogicalTop = borderBefore() + paddingBefore();
3256     LayoutUnit colLogicalLeft = logicalLeftOffsetForContent();
3257     LayoutUnit colGap = columnGap();
3258     if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
3259         if (style()->isLeftToRightDirection())
3260             colLogicalLeft += index * (colLogicalWidth + colGap);
3261         else
3262             colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap);
3263     } else {
3264         colLogicalTop += index * (colLogicalHeight + colGap);
3265     }
3266
3267     if (isHorizontalWritingMode())
3268         return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
3269     return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
3270 }
3271
3272 void RenderBlock::adjustPointToColumnContents(LayoutPoint& point) const
3273 {
3274     // Just bail if we have no columns.
3275     if (!hasColumns())
3276         return;
3277
3278     ColumnInfo* colInfo = columnInfo();
3279     if (!columnCount(colInfo))
3280         return;
3281
3282     // Determine which columns we intersect.
3283     LayoutUnit colGap = columnGap();
3284     LayoutUnit halfColGap = colGap / 2;
3285     LayoutPoint columnPoint(columnRectAt(colInfo, 0).location());
3286     LayoutUnit logicalOffset = 0;
3287     for (unsigned i = 0; i < colInfo->columnCount(); i++) {
3288         // Add in half the column gap to the left and right of the rect.
3289         LayoutRect colRect = columnRectAt(colInfo, i);
3290         flipForWritingMode(colRect);
3291         if (isHorizontalWritingMode() == (colInfo->progressionAxis() == ColumnInfo::InlineAxis)) {
3292             LayoutRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
3293             if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
3294                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
3295                     // FIXME: The clamping that follows is not completely right for right-to-left
3296                     // content.
3297                     // Clamp everything above the column to its top left.
3298                     if (point.y() < gapAndColumnRect.y())
3299                         point = gapAndColumnRect.location();
3300                     // Clamp everything below the column to the next column's top left. If there is
3301                     // no next column, this still maps to just after this column.
3302                     else if (point.y() >= gapAndColumnRect.maxY()) {
3303                         point = gapAndColumnRect.location();
3304                         point.move(0, gapAndColumnRect.height());
3305                     }
3306                 } else {
3307                     if (point.x() < colRect.x())
3308                         point.setX(colRect.x());
3309                     else if (point.x() >= colRect.maxX())
3310                         point.setX(colRect.maxX() - 1);
3311                 }
3312
3313                 // We're inside the column.  Translate the x and y into our column coordinate space.
3314                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3315                     point.move(columnPoint.x() - colRect.x(), (!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset));
3316                 else
3317                     point.move((!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset) - colRect.x() + borderLeft() + paddingLeft(), 0);
3318                 return;
3319             }
3320
3321             // Move to the next position.
3322             logicalOffset += colInfo->progressionAxis() == ColumnInfo::InlineAxis ? colRect.height() : colRect.width();
3323         } else {
3324             LayoutRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
3325             if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) {
3326                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
3327                     // FIXME: The clamping that follows is not completely right for right-to-left
3328                     // content.
3329                     // Clamp everything above the column to its top left.
3330                     if (point.x() < gapAndColumnRect.x())
3331                         point = gapAndColumnRect.location();
3332                     // Clamp everything below the column to the next column's top left. If there is
3333                     // no next column, this still maps to just after this column.
3334                     else if (point.x() >= gapAndColumnRect.maxX()) {
3335                         point = gapAndColumnRect.location();
3336                         point.move(gapAndColumnRect.width(), 0);
3337                     }
3338                 } else {
3339                     if (point.y() < colRect.y())
3340                         point.setY(colRect.y());
3341                     else if (point.y() >= colRect.maxY())
3342                         point.setY(colRect.maxY() - 1);
3343                 }
3344
3345                 // We're inside the column.  Translate the x and y into our column coordinate space.
3346                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3347                     point.move((!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset), columnPoint.y() - colRect.y());
3348                 else
3349                     point.move(0, (!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset) - colRect.y() + borderTop() + paddingTop());
3350                 return;
3351             }
3352
3353             // Move to the next position.
3354             logicalOffset += colInfo->progressionAxis() == ColumnInfo::InlineAxis ? colRect.width() : colRect.height();
3355         }
3356     }
3357 }
3358
3359 void RenderBlock::adjustRectForColumns(LayoutRect& r) const
3360 {
3361     // Just bail if we have no columns.
3362     if (!hasColumns())
3363         return;
3364
3365     ColumnInfo* colInfo = columnInfo();
3366
3367     // Determine which columns we intersect.
3368     unsigned colCount = columnCount(colInfo);
3369     if (!colCount)
3370         return;
3371
3372     // Begin with a result rect that is empty.
3373     LayoutRect result;
3374
3375     bool isHorizontal = isHorizontalWritingMode();
3376     LayoutUnit beforeBorderPadding = borderBefore() + paddingBefore();
3377     LayoutUnit colHeight = colInfo->columnHeight();
3378     if (!colHeight)
3379         return;
3380
3381     LayoutUnit startOffset = max(isHorizontal ? r.y() : r.x(), beforeBorderPadding);
3382     LayoutUnit endOffset = max(min<LayoutUnit>(isHorizontal ? r.maxY() : r.maxX(), beforeBorderPadding + colCount * colHeight), beforeBorderPadding);
3383
3384     // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
3385     unsigned startColumn = (startOffset - beforeBorderPadding) / colHeight;
3386     unsigned endColumn = (endOffset - beforeBorderPadding) / colHeight;
3387
3388     if (startColumn == endColumn) {
3389         // The rect is fully contained within one column. Adjust for our offsets
3390         // and repaint only that portion.
3391         LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent();
3392         LayoutRect colRect = columnRectAt(colInfo, startColumn);
3393         LayoutRect repaintRect = r;
3394
3395         if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
3396             if (isHorizontal)
3397                 repaintRect.move(colRect.x() - logicalLeftOffset, - static_cast<int>(startColumn) * colHeight);
3398             else
3399                 repaintRect.move(- static_cast<int>(startColumn) * colHeight, colRect.y() - logicalLeftOffset);
3400         } else {
3401             if (isHorizontal)
3402                 repaintRect.move(0, colRect.y() - startColumn * colHeight - beforeBorderPadding);
3403             else
3404                 repaintRect.move(colRect.x() - startColumn * colHeight - beforeBorderPadding, 0);
3405         }
3406         repaintRect.intersect(colRect);
3407         result.unite(repaintRect);
3408     } else {
3409         // We span multiple columns. We can just unite the start and end column to get the final
3410         // repaint rect.
3411         result.unite(columnRectAt(colInfo, startColumn));
3412         result.unite(columnRectAt(colInfo, endColumn));
3413     }
3414
3415     r = result;
3416 }
3417
3418 LayoutPoint RenderBlock::flipForWritingModeIncludingColumns(const LayoutPoint& point) const
3419 {
3420     ASSERT(hasColumns());
3421     if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
3422         return point;
3423     ColumnInfo* colInfo = columnInfo();
3424     LayoutUnit columnLogicalHeight = colInfo->columnHeight();
3425     LayoutUnit expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
3426     if (isHorizontalWritingMode())
3427         return LayoutPoint(point.x(), expandedLogicalHeight - point.y());
3428     return LayoutPoint(expandedLogicalHeight - point.x(), point.y());
3429 }
3430
3431 void RenderBlock::adjustStartEdgeForWritingModeIncludingColumns(LayoutRect& rect) const
3432 {
3433     ASSERT(hasColumns());
3434     if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
3435         return;
3436
3437     ColumnInfo* colInfo = columnInfo();
3438     LayoutUnit columnLogicalHeight = colInfo->columnHeight();
3439     LayoutUnit expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
3440
3441     if (isHorizontalWritingMode())
3442         rect.setY(expandedLogicalHeight - rect.maxY());
3443     else
3444         rect.setX(expandedLogicalHeight - rect.maxX());
3445 }
3446
3447 LayoutSize RenderBlock::columnOffset(const LayoutPoint& point) const
3448 {
3449     if (!hasColumns())
3450         return LayoutSize();
3451
3452     ColumnInfo* colInfo = columnInfo();
3453
3454     LayoutUnit logicalLeft = logicalLeftOffsetForContent();
3455     unsigned colCount = columnCount(colInfo);
3456     LayoutUnit colLogicalWidth = colInfo->desiredColumnWidth();
3457     LayoutUnit colLogicalHeight = colInfo->columnHeight();
3458
3459     for (unsigned i = 0; i < colCount; ++i) {
3460         // Compute the edges for a given column in the block progression direction.
3461         LayoutRect sliceRect = LayoutRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
3462         if (!isHorizontalWritingMode())
3463             sliceRect = sliceRect.transposedRect();
3464
3465         LayoutUnit logicalOffset = i * colLogicalHeight;
3466
3467         // Now we're in the same coordinate space as the point.  See if it is inside the rectangle.
3468         if (isHorizontalWritingMode()) {
3469             if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
3470                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3471                     return LayoutSize(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
3472                 return LayoutSize(0, columnRectAt(colInfo, i).y() - logicalOffset - borderBefore() - paddingBefore());
3473             }
3474         } else {
3475             if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
3476                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3477                     return LayoutSize(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
3478                 return LayoutSize(columnRectAt(colInfo, i).x() - logicalOffset - borderBefore() - paddingBefore(), 0);
3479             }
3480         }
3481     }
3482
3483     return LayoutSize();
3484 }
3485
3486 void RenderBlock::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
3487 {
3488     if (childrenInline()) {
3489         // FIXME: Remove this const_cast.
3490         toRenderBlockFlow(const_cast<RenderBlock*>(this))->computeInlinePreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
3491     } else {
3492         computeBlockPreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
3493     }
3494
3495     maxLogicalWidth = max(minLogicalWidth, maxLogicalWidth);
3496
3497     adjustIntrinsicLogicalWidthsForColumns(minLogicalWidth, maxLogicalWidth);
3498
3499     // A horizontal marquee with inline children has no minimum width.
3500     if (childrenInline() && isMarquee() && toRenderMarquee(this)->isHorizontal())
3501         minLogicalWidth = 0;
3502
3503     if (isTableCell()) {
3504         Length tableCellWidth = toRenderTableCell(this)->styleOrColLogicalWidth();
3505         if (tableCellWidth.isFixed() && tableCellWidth.value() > 0)
3506             maxLogicalWidth = max(minLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(tableCellWidth.value()));
3507     }
3508
3509     int scrollbarWidth = instrinsicScrollbarLogicalWidth();
3510     maxLogicalWidth += scrollbarWidth;
3511     minLogicalWidth += scrollbarWidth;
3512 }
3513
3514 void RenderBlock::computePreferredLogicalWidths()
3515 {
3516     ASSERT(preferredLogicalWidthsDirty());
3517
3518     updateFirstLetter();
3519
3520     m_minPreferredLogicalWidth = 0;
3521     m_maxPreferredLogicalWidth = 0;
3522
3523     // FIXME: The isFixed() calls here should probably be checking for isSpecified since you
3524     // should be able to use percentage, calc or viewport relative values for width.
3525     RenderStyle* styleToUse = style();
3526     if (!isTableCell() && styleToUse->logicalWidth().isFixed() && styleToUse->logicalWidth().value() >= 0
3527         && !(isDeprecatedFlexItem() && !styleToUse->logicalWidth().intValue()))
3528         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalWidth().value());
3529     else
3530         computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
3531
3532     if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
3533         m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
3534         m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
3535     }
3536
3537     if (styleToUse->logicalMaxWidth().isFixed()) {
3538         m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
3539         m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
3540     }
3541
3542     // Table layout uses integers, ceil the preferred widths to ensure that they can contain the contents.
3543     if (isTableCell()) {
3544         m_minPreferredLogicalWidth = m_minPreferredLogicalWidth.ceil();
3545         m_maxPreferredLogicalWidth = m_maxPreferredLogicalWidth.ceil();
3546     }
3547
3548     LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
3549     m_minPreferredLogicalWidth += borderAndPadding;
3550     m_maxPreferredLogicalWidth += borderAndPadding;
3551
3552     clearPreferredLogicalWidthsDirty();
3553 }
3554
3555 void RenderBlock::adjustIntrinsicLogicalWidthsForColumns(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
3556 {
3557     if (!style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth()) {
3558         // The min/max intrinsic widths calculated really tell how much space elements need when
3559         // laid out inside the columns. In order to eventually end up with the desired column width,
3560         // we need to convert them to values pertaining to the multicol container.
3561         int columnCount = style()->hasAutoColumnCount() ? 1 : style()->columnCount();
3562         LayoutUnit columnWidth;
3563         LayoutUnit gapExtra = (columnCount - 1) * columnGap();
3564         if (style()->hasAutoColumnWidth()) {
3565             minLogicalWidth = minLogicalWidth * columnCount + gapExtra;
3566         } else {
3567             columnWidth = style()->columnWidth();
3568             minLogicalWidth = min(minLogicalWidth, columnWidth);
3569         }
3570         // FIXME: If column-count is auto here, we should resolve it to calculate the maximum
3571         // intrinsic width, instead of pretending that it's 1. The only way to do that is by
3572         // performing a layout pass, but this is not an appropriate time or place for layout. The
3573         // good news is that if height is unconstrained and there are no explicit breaks, the
3574         // resolved column-count really should be 1.
3575         maxLogicalWidth = max(maxLogicalWidth, columnWidth) * columnCount + gapExtra;
3576     }
3577 }
3578
3579 void RenderBlock::computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
3580 {
3581     RenderStyle* styleToUse = style();
3582     bool nowrap = styleToUse->whiteSpace() == NOWRAP;
3583
3584     RenderObject* child = firstChild();
3585     RenderBlock* containingBlock = this->containingBlock();
3586     LayoutUnit floatLeftWidth = 0, floatRightWidth = 0;
3587     while (child) {
3588         // Positioned children don't affect the min/max width
3589         if (child->isOutOfFlowPositioned()) {
3590             child = child->nextSibling();
3591             continue;
3592         }
3593
3594         RenderStyle* childStyle = child->style();
3595         if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
3596             LayoutUnit floatTotalWidth = floatLeftWidth + floatRightWidth;
3597             if (childStyle->clear() & CLEFT) {
3598                 maxLogicalWidth = max(floatTotalWidth, maxLogicalWidth);
3599                 floatLeftWidth = 0;
3600             }
3601             if (childStyle->clear() & CRIGHT) {
3602                 maxLogicalWidth = max(floatTotalWidth, maxLogicalWidth);
3603                 floatRightWidth = 0;
3604             }
3605         }
3606
3607         // A margin basically has three types: fixed, percentage, and auto (variable).
3608         // Auto and percentage margins simply become 0 when computing min/max width.
3609         // Fixed margins can be added in as is.
3610         Length startMarginLength = childStyle->marginStartUsing(styleToUse);
3611         Length endMarginLength = childStyle->marginEndUsing(styleToUse);
3612         LayoutUnit margin = 0;
3613         LayoutUnit marginStart = 0;
3614         LayoutUnit marginEnd = 0;
3615         if (startMarginLength.isFixed())
3616             marginStart += startMarginLength.value();
3617         if (endMarginLength.isFixed())
3618             marginEnd += endMarginLength.value();
3619         margin = marginStart + marginEnd;
3620
3621         LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
3622         if (child->isBox() && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
3623             RenderBox* childBox = toRenderBox(child);
3624             LogicalExtentComputedValues computedValues;
3625             childBox->computeLogicalHeight(childBox->borderAndPaddingLogicalHeight(), 0, computedValues);
3626             childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
3627         } else {
3628             childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
3629             childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
3630         }
3631
3632         LayoutUnit w = childMinPreferredLogicalWidth + margin;
3633         minLogicalWidth = max(w, minLogicalWidth);
3634
3635         // IE ignores tables for calculation of nowrap. Makes some sense.
3636         if (nowrap && !child->isTable())
3637             maxLogicalWidth = max(w, maxLogicalWidth);
3638
3639         w = childMaxPreferredLogicalWidth + margin;
3640
3641         if (!child->isFloating()) {
3642             if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
3643                 // Determine a left and right max value based off whether or not the floats can fit in the
3644                 // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
3645                 // is smaller than the float width.
3646                 bool ltr = containingBlock ? containingBlock->style()->isLeftToRightDirection() : styleToUse->isLeftToRightDirection();
3647                 LayoutUnit marginLogicalLeft = ltr ? marginStart : marginEnd;
3648                 LayoutUnit marginLogicalRight = ltr ? marginEnd : marginStart;
3649                 LayoutUnit maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
3650                 LayoutUnit maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
3651                 w = childMaxPreferredLogicalWidth + maxLeft + maxRight;
3652                 w = max(w, floatLeftWidth + floatRightWidth);
3653             }
3654             else
3655                 maxLogicalWidth = max(floatLeftWidth + floatRightWidth, maxLogicalWidth);
3656             floatLeftWidth = floatRightWidth = 0;
3657         }
3658
3659         if (child->isFloating()) {
3660             if (childStyle->floating() == LeftFloat)
3661                 floatLeftWidth += w;
3662             else
3663                 floatRightWidth += w;
3664         } else
3665             maxLogicalWidth = max(w, maxLogicalWidth);
3666
3667         child = child->nextSibling();
3668     }
3669
3670     // Always make sure these values are non-negative.
3671     minLogicalWidth = max<LayoutUnit>(0, minLogicalWidth);
3672     maxLogicalWidth = max<LayoutUnit>(0, maxLogicalWidth);
3673
3674     maxLogicalWidth = max(floatLeftWidth + floatRightWidth, maxLogicalWidth);
3675 }
3676
3677 bool RenderBlock::hasLineIfEmpty() const
3678 {
3679     if (!node())
3680         return false;
3681
3682     if (node()->isRootEditableElement())
3683         return true;
3684
3685     if (node()->isShadowRoot() && isHTMLInputElement(*toShadowRoot(node())->host()))
3686         return true;
3687
3688     return false;
3689 }
3690
3691 LayoutUnit RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
3692 {
3693     // Inline blocks are replaced elements. Otherwise, just pass off to
3694     // the base class.  If we're being queried as though we're the root line
3695     // box, then the fact that we're an inline-block is irrelevant, and we behave
3696     // just like a block.
3697     if (isReplaced() && linePositionMode == PositionOnContainingLine)
3698         return RenderBox::lineHeight(firstLine, direction, linePositionMode);
3699
3700     if (firstLine && document().styleEngine()->usesFirstLineRules()) {
3701         RenderStyle* s = style(firstLine);
3702         if (s != style())
3703             return s->computedLineHeight();
3704     }
3705
3706     if (m_lineHeight == -1)
3707         m_lineHeight = style()->computedLineHeight();
3708
3709     return m_lineHeight;
3710 }
3711
3712 int RenderBlock::beforeMarginInLineDirection(LineDirectionMode direction) const
3713 {
3714     return direction == HorizontalLine ? marginTop() : marginRight();
3715 }
3716
3717 int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
3718 {
3719     // Inline blocks are replaced elements. Otherwise, just pass off to
3720     // the base class.  If we're being queried as though we're the root line
3721     // box, then the fact that we're an inline-block is irrelevant, and we behave
3722     // just like a block.
3723     if (isInline() && linePositionMode == PositionOnContainingLine) {
3724         // For "leaf" theme objects, let the theme decide what the baseline position is.
3725         // FIXME: Might be better to have a custom CSS property instead, so that if the theme
3726         // is turned off, checkboxes/radios will still have decent baselines.
3727         // FIXME: Need to patch form controls to deal with vertical lines.
3728         if (style()->hasAppearance() && !RenderTheme::theme().isControlContainer(style()->appearance()))
3729             return RenderTheme::theme().baselinePosition(this);
3730
3731         // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
3732         // the normal flow.  We make an exception for marquees, since their baselines are meaningless
3733         // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
3734         // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
3735         // vertically (e.g., an overflow:hidden block that has had scrollTop moved).
3736         bool ignoreBaseline = (layer() && layer()->scrollableArea() && (isMarquee() || (direction == HorizontalLine ? (layer()->scrollableArea()->verticalScrollbar() || layer()->scrollableArea()->scrollYOffset())
3737             : (layer()->scrollableArea()->horizontalScrollbar() || layer()->scrollableArea()->scrollXOffset())))) || (isWritingModeRoot() && !isRubyRun());
3738
3739         int baselinePos = ignoreBaseline ? -1 : inlineBlockBaseline(direction);
3740
3741         if (isDeprecatedFlexibleBox()) {
3742             // Historically, we did this check for all baselines. But we can't
3743             // remove this code from deprecated flexbox, because it effectively
3744             // breaks -webkit-line-clamp, which is used in the wild -- we would
3745             // calculate the baseline as if -webkit-line-clamp wasn't used.
3746             // For simplicity, we use this for all uses of deprecated flexbox.
3747             LayoutUnit bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
3748             if (baselinePos > bottomOfContent)
3749                 baselinePos = -1;
3750         }
3751         if (baselinePos != -1)
3752             return beforeMarginInLineDirection(direction) + baselinePos;
3753
3754         return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
3755     }
3756
3757     // If we're not replaced, we'll only get called with PositionOfInteriorLineBoxes.
3758     // Note that inline-block counts as replaced here.
3759     ASSERT(linePositionMode == PositionOfInteriorLineBoxes);
3760
3761     const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
3762     return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
3763 }
3764
3765 LayoutUnit RenderBlock::minLineHeightForReplacedRenderer(bool isFirstLine, LayoutUnit replacedHeight) const
3766 {
3767     if (!document().inNoQuirksMode() && replacedHeight)
3768         return replacedHeight;
3769
3770     if (!(style(isFirstLine)->lineBoxContain() & LineBoxContainBlock))
3771         return 0;
3772
3773     return std::max<LayoutUnit>(replacedHeight, lineHeight(isFirstLine, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
3774 }
3775
3776 int RenderBlock::firstLineBoxBaseline() const
3777 {
3778     if (isWritingModeRoot() && !isRubyRun())
3779         return -1;
3780
3781     if (childrenInline()) {
3782         if (firstLineBox())
3783             return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
3784         else
3785             return -1;
3786     }
3787     else {
3788         for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
3789             if (!curr->isFloatingOrOutOfFlowPositioned()) {
3790                 int result = curr->firstLineBoxBaseline();
3791                 if (result != -1)
3792                     return curr->logicalTop() + result; // Translate to our coordinate space.
3793             }
3794         }
3795     }
3796
3797     return -1;
3798 }
3799
3800 int RenderBlock::inlineBlockBaseline(LineDirectionMode direction) const
3801 {
3802     if (!style()->isOverflowVisible()) {
3803         // We are not calling RenderBox::baselinePosition here because the caller should add the margin-top/margin-right, not us.
3804         return direction == HorizontalLine ? height() + m_marginBox.bottom() : width() + m_marginBox.left();
3805     }
3806
3807     return lastLineBoxBaseline(direction);
3808 }
3809
3810 int RenderBlock::lastLineBoxBaseline(LineDirectionMode lineDirection) const
3811 {
3812     if (isWritingModeRoot() && !isRubyRun())
3813         return -1;
3814
3815     if (childrenInline()) {
3816         if (!firstLineBox() && hasLineIfEmpty()) {
3817             const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
3818             return fontMetrics.ascent()
3819                  + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
3820                  + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
3821         }
3822         if (lastLineBox())
3823             return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
3824         return -1;
3825     } else {
3826         bool haveNormalFlowChild = false;
3827         for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
3828             if (!curr->isFloatingOrOutOfFlowPositioned()) {
3829                 haveNormalFlowChild = true;
3830                 int result = curr->inlineBlockBaseline(lineDirection);
3831                 if (result != -1)
3832                     return curr->logicalTop() + result; // Translate to our coordinate space.
3833             }
3834         }
3835         if (!haveNormalFlowChild && hasLineIfEmpty()) {
3836             const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
3837             return fontMetrics.ascent()
3838                  + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
3839                  + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
3840         }
3841     }
3842
3843     return -1;
3844 }
3845
3846 RenderBlock* RenderBlock::firstLineBlock() const
3847 {
3848     RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
3849     bool hasPseudo = false;
3850     while (true) {
3851         hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
3852         if (hasPseudo)
3853             break;
3854         RenderObject* parentBlock = firstLineBlock->parent();
3855         // We include isRenderButton in this check because buttons are
3856         // implemented using flex box but should still support first-line. The
3857         // flex box spec requires that flex box does not support first-line,
3858         // though.
3859         // FIXME: Remove when buttons are implemented with align-items instead
3860         // of flexbox.
3861         if (firstLineBlock->isReplaced() || firstLineBlock->isFloating()
3862             || !parentBlock || parentBlock->firstChild() != firstLineBlock
3863             || (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButton()))
3864             break;
3865         ASSERT_WITH_SECURITY_IMPLICATION(parentBlock->isRenderBlock());
3866         firstLineBlock = toRenderBlock(parentBlock);
3867     }
3868
3869     if (!hasPseudo)
3870         return 0;
3871
3872     return firstLineBlock;
3873 }
3874
3875 static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer)
3876 {
3877     RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle());
3878     // Force inline display (except for floating first-letters).
3879     pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
3880     // CSS2 says first-letter can't be positioned.
3881     pseudoStyle->setPosition(StaticPosition);
3882     return pseudoStyle;
3883 }
3884
3885 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
3886 // "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
3887 // "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
3888 static inline bool isPunctuationForFirstLetter(UChar c)
3889 {
3890     CharCategory charCategory = category(c);
3891     return charCategory == Punctuation_Open
3892         || charCategory == Punctuation_Close
3893         || charCategory == Punctuation_InitialQuote
3894         || charCategory == Punctuation_FinalQuote
3895         || charCategory == Punctuation_Other;
3896 }
3897
3898 static inline bool isSpaceForFirstLetter(UChar c)
3899 {
3900     return isSpaceOrNewline(c) || c == noBreakSpace;
3901 }
3902
3903 static inline RenderObject* findFirstLetterBlock(RenderBlock* start)
3904 {
3905     RenderObject* firstLetterBlock = start;
3906     while (true) {
3907         // We include isRenderButton in these two checks because buttons are
3908         // implemented using flex box but should still support first-letter.
3909         // The flex box spec requires that flex box does not support
3910         // first-letter, though.
3911         // FIXME: Remove when buttons are implemented with align-items instead
3912         // of flexbox.
3913         bool canHaveFirstLetterRenderer = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
3914             && firstLetterBlock->canHaveGeneratedChildren()
3915             && (!firstLetterBlock->isFlexibleBox() || firstLetterBlock->isRenderButton());
3916         if (canHaveFirstLetterRenderer)
3917             return firstLetterBlock;
3918
3919         RenderObject* parentBlock = firstLetterBlock->parent();
3920         if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
3921             (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButton()))
3922             return 0;
3923         firstLetterBlock = parentBlock;
3924     }
3925
3926     return 0;
3927 }
3928
3929 void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* currentChild)
3930 {
3931     RenderObject* firstLetter = currentChild->parent();
3932     RenderObject* firstLetterContainer = firstLetter->parent();
3933     RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
3934     ASSERT(firstLetter->isFloating() || firstLetter->isInline());
3935
3936     if (RenderStyle::stylePropagationDiff(firstLetter->style(), pseudoStyle) == Reattach) {
3937         // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
3938         RenderBoxModelObject* newFirstLetter;
3939         if (pseudoStyle->display() == INLINE)
3940             newFirstLetter = RenderInline::createAnonymous(&document());
3941         else
3942             newFirstLetter = RenderBlockFlow::createAnonymous(&document());
3943         newFirstLetter->setStyle(pseudoStyle);
3944
3945         // Move the first letter into the new renderer.
3946         LayoutStateDisabler layoutStateDisabler(*this);
3947         while (RenderObject* child = firstLetter->firstChild()) {
3948             if (child->isText())
3949                 toRenderText(child)->removeAndDestroyTextBoxes();
3950             firstLetter->removeChild(child);
3951             newFirstLetter->addChild(child, 0);
3952         }
3953
3954         RenderObject* nextSibling = firstLetter->nextSibling();
3955         if (RenderTextFragment* remainingText = toRenderBoxModelObject(firstLetter)->firstLetterRemainingText()) {
3956             ASSERT(remainingText->isAnonymous() || remainingText->node()->renderer() == remainingText);
3957             // Replace the old renderer with the new one.
3958             remainingText->setFirstLetter(newFirstLetter);
3959             newFirstLetter->setFirstLetterRemainingText(remainingText);
3960         }
3961         // To prevent removal of single anonymous block in RenderBlock::removeChild and causing
3962         // |nextSibling| to go stale, we remove the old first letter using removeChildNode first.
3963         firstLetterContainer->virtualChildren()->removeChildNode(firstLetterContainer, firstLetter);
3964         firstLetter->destroy();
3965         firstLetter = newFirstLetter;
3966         firstLetterContainer->addChild(firstLetter, nextSibling);
3967     } else
3968         firstLetter->setStyle(pseudoStyle);
3969
3970     for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
3971         if (genChild->isText())
3972             genChild->setStyle(pseudoStyle);
3973     }
3974 }
3975
3976 static inline unsigned firstLetterLength(const String& text)
3977 {
3978     unsigned length = 0;
3979     unsigned textLength = text.length();
3980
3981     // Account for leading spaces first.
3982     while (length < textLength && isSpaceForFirstLetter(text[length]))
3983         length++;
3984
3985     // Now account for leading punctuation.
3986     while (length < textLength && isPunctuationForFirstLetter(text[length]))
3987         length++;
3988
3989     // Bail if we didn't find a letter before the end of the text or before a space.
3990     if (isSpaceForFirstLetter(text[length]) || (textLength && length == textLength))
3991         return 0;
3992
3993     // Account the next character for first letter.
3994     length++;
3995
3996     // Keep looking allowed punctuation for the :first-letter.
3997     for (unsigned scanLength = length; scanLength < textLength; ++scanLength) {
3998         UChar c = text[scanLength];
3999
4000         if (!isPunctuationForFirstLetter(c))
4001             break;
4002
4003         length = scanLength + 1;
4004     }
4005
4006     // FIXME: If textLength is 0, length may still be 1!
4007     return length;
4008 }
4009
4010 void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild, unsigned length)
4011 {
4012     ASSERT(length && currentChild->isText());
4013
4014     RenderObject* firstLetterContainer = currentChild->parent();
4015     RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
4016     RenderObject* firstLetter = 0;
4017     if (pseudoStyle->display() == INLINE)
4018         firstLetter = RenderInline::createAnonymous(&document());
4019     else
4020         firstLetter = RenderBlockFlow::createAnonymous(&document());
4021     firstLetter->setStyle(pseudoStyle);
4022
4023     // FIXME: The first letter code should not modify the render tree during
4024     // layout. crbug.com/370458
4025     DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
4026
4027     firstLetterContainer->addChild(firstLetter, currentChild);
4028     RenderText* textObj = toRenderText(currentChild);
4029
4030     // The original string is going to be either a generated content string or a DOM node's
4031     // string.  We want the original string before it got transformed in case first-letter has
4032     // no text-transform or a different text-transform applied to it.
4033     String oldText = textObj->originalText();
4034     ASSERT(oldText.impl());
4035
4036     // Construct a text fragment for the text after the first letter.
4037     // This text fragment might be empty.
4038     RenderTextFragment* remainingText =
4039         new RenderTextFragment(textObj->node() ? textObj->node() : &textObj->document(), oldText.impl(), length, oldText.length() - length);
4040     remainingText->setStyle(textObj->style());
4041     if (remainingText->node())
4042         remainingText->node()->setRenderer(remainingText);
4043
4044     firstLetterContainer->addChild(remainingText, textObj);
4045     firstLetterContainer->removeChild(textObj);
4046     remainingText->setFirstLetter(firstLetter);
4047     toRenderBoxModelObject(firstLetter)->setFirstLetterRemainingText(remainingText);
4048
4049     // construct text fragment for the first letter
4050     RenderTextFragment* letter =
4051         new RenderTextFragment(remainingText->node() ? remainingText->node() : &remainingText->document(), oldText.impl(), 0, length);
4052     letter->setStyle(pseudoStyle);
4053     firstLetter->addChild(letter);
4054
4055     textObj->destroy();
4056 }
4057
4058 void RenderBlock::updateFirstLetter()
4059 {
4060     if (!document().styleEngine()->usesFirstLetterRules())
4061         return;
4062     // Don't recur
4063     if (style()->styleType() == FIRST_LETTER)
4064         return;
4065
4066     // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
4067     // an efficient way to check for that situation though before implementing anything.
4068     RenderObject* firstLetterBlock = findFirstLetterBlock(this);
4069     if (!firstLetterBlock)
4070         return;
4071
4072     // Drill into inlines looking for our first text child.
4073     RenderObject* currChild = firstLetterBlock->firstChild();
4074     unsigned length = 0;
4075     while (currChild) {
4076         if (currChild->isText()) {
4077             // FIXME: If there is leading punctuation in a different RenderText than
4078             // the first letter, we'll not apply the correct style to it.
4079             length = firstLetterLength(toRenderText(currChild)->originalText());
4080             if (length)
4081                 break;
4082             currChild = currChild->nextSibling();
4083         } else if (currChild->isListMarker()) {
4084             currChild = currChild->nextSibling();
4085         } else if (currChild->isFloatingOrOutOfFlowPositioned()) {
4086             if (currChild->style()->styleType() == FIRST_LETTER) {
4087                 currChild = currChild->firstChild();
4088                 break;
4089             }
4090             currChild = currChild->nextSibling();
4091         } else if (currChild->isReplaced() || currChild->isRenderButton() || currChild->isMenuList())
4092             break;
4093         else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild->canHaveGeneratedChildren())  {
4094             // We found a lower-level node with first-letter, which supersedes the higher-level style
4095             firstLetterBlock = currChild;
4096             currChild = currChild->firstChild();
4097         } else
4098             currChild = currChild->firstChild();
4099     }
4100
4101     if (!currChild)
4102         return;
4103
4104     // If the child already has style, then it has already been created, so we just want
4105     // to update it.
4106     if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
4107         updateFirstLetterStyle(firstLetterBlock, currChild);
4108         return;
4109     }
4110
4111     // FIXME: This black-list of disallowed RenderText subclasses is fragile.
4112     // Should counter be on this list? What about RenderTextFragment?
4113     if (!currChild->isText() || currChild->isBR() || toRenderText(currChild)->isWordBreak())
4114         return;
4115
4116     // Our layout state is not valid for the repaints we are going to trigger by
4117     // adding and removing children of firstLetterContainer.
4118     LayoutStateDisabler layoutStateDisabler(*this);
4119
4120     createFirstLetterRenderer(firstLetterBlock, currChild, length);
4121 }
4122
4123 // Helper methods for obtaining the last line, computing line counts and heights for line counts
4124 // (crawling into blocks).
4125 static bool shouldCheckLines(RenderObject* obj)
4126 {
4127     return !obj->isFloatingOrOutOfFlowPositioned()
4128         && obj->isRenderBlock() && obj->style()->height().isAuto()
4129         && (!obj->isDeprecatedFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
4130 }
4131
4132 static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count)
4133 {
4134     if (block->style()->visibility() == VISIBLE) {
4135         if (block->childrenInline()) {
4136             for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
4137                 if (++count == l)
4138                     return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : LayoutUnit());
4139             }
4140         }
4141         else {
4142             RenderBox* normalFlowChildWithoutLines = 0;
4143             for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
4144                 if (shouldCheckLines(obj)) {
4145                     int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
4146                     if (result != -1)
4147                         return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : LayoutUnit());
4148                 } else if (!obj->isFloatingOrOutOfFlowPositioned())
4149                     normalFlowChildWithoutLines = obj;
4150             }
4151             if (normalFlowChildWithoutLines && l == 0)
4152                 return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
4153         }
4154     }
4155
4156     return -1;
4157 }
4158
4159 RootInlineBox* RenderBlock::lineAtIndex(int i) const
4160 {
4161     ASSERT(i >= 0);
4162
4163     if (style()->visibility() != VISIBLE)
4164         return 0;
4165
4166     if (childrenInline()) {
4167         for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
4168             if (!i--)
4169                 return box;
4170     } else {
4171         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
4172             if (!shouldCheckLines(child))
4173                 continue;
4174             if (RootInlineBox* box = toRenderBlock(child)->lineAtIndex(i))
4175                 return box;
4176         }
4177     }
4178
4179     return 0;
4180 }
4181
4182 int RenderBlock::lineCount(const RootInlineBox* stopRootInlineBox, bool* found) const
4183 {
4184     int count = 0;
4185
4186     if (style()->visibility() == VISIBLE) {
4187         if (childrenInline())
4188             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
4189                 count++;
4190                 if (box == stopRootInlineBox) {
4191                     if (found)
4192                         *found = true;
4193                     break;
4194                 }
4195             }
4196         else
4197             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
4198                 if (shouldCheckLines(obj)) {
4199                     bool recursiveFound = false;
4200                     count += toRenderBlock(obj)->lineCount(stopRootInlineBox, &recursiveFound);
4201                     if (recursiveFound) {
4202                         if (found)
4203                             *found = true;
4204                         break;
4205                     }
4206                 }
4207     }
4208     return count;
4209 }
4210
4211 int RenderBlock::heightForLineCount(int l)
4212 {
4213     int count = 0;
4214     return getHeightForLineCount(this, l, true, count);
4215 }
4216
4217 void RenderBlock::adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const
4218 {
4219     // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
4220     // for either overflow or translations via relative positioning.
4221     if (style()->visibility() == VISIBLE) {
4222         if (childrenInline()) {
4223             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
4224                 if (box->firstChild())
4225                     left = min(left, x + static_cast<LayoutUnit>(box->firstChild()->x()));
4226                 if (box->lastChild())
4227                     right = max(right, x + static_cast<LayoutUnit>(ceilf(box->lastChild()->logicalRight())));
4228             }
4229         } else {
4230             for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
4231                 if (!obj->isFloatingOrOutOfFlowPositioned()) {
4232                     if (obj->isRenderBlockFlow() && !obj->hasOverflowClip())
4233                         toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
4234                     else if (obj->style()->visibility() == VISIBLE) {
4235                         // We are a replaced element or some kind of non-block-flow object.
4236                         left = min(left, x + obj->x());
4237                         right = max(right, x + obj->x() + obj->width());
4238                     }
4239                 }
4240             }
4241         }
4242     }
4243 }
4244
4245 void RenderBlock::fitBorderToLinesIfNeeded()
4246 {
4247     if (style()->borderFit() == BorderFitBorder || hasOverrideWidth())
4248         return;
4249
4250     // Walk any normal flow lines to snugly fit.
4251     LayoutUnit left = LayoutUnit::max();
4252     LayoutUnit right = LayoutUnit::min();
4253     LayoutUnit oldWidth = contentWidth();
4254     adjustForBorderFit(0, left, right);
4255
4256     // Clamp to our existing edges. We can never grow. We only shrink.
4257     LayoutUnit leftEdge = borderLeft() + paddingLeft();
4258     LayoutUnit rightEdge = leftEdge + oldWidth;
4259     left = min(rightEdge, max(leftEdge, left));
4260     right = max(left, min(rightEdge, right));
4261
4262     LayoutUnit newContentWidth = right - left;
4263     if (newContentWidth == oldWidth)
4264         return;
4265
4266     setOverrideLogicalContentWidth(newContentWidth);
4267     layoutBlock(false);
4268     clearOverrideLogicalContentWidth();
4269 }
4270
4271 void RenderBlock::clearTruncation()
4272 {
4273     if (style()->visibility() == VISIBLE) {
4274         if (childrenInline() && hasMarkupTruncation()) {
4275             setHasMarkupTruncation(false);
4276             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
4277                 box->clearTruncation();
4278         } else {
4279             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) {
4280                 if (shouldCheckLines(obj))
4281                     toRenderBlock(obj)->clearTruncation();
4282             }
4283         }
4284     }
4285 }
4286
4287 void RenderBlock::setPaginationStrut(LayoutUnit strut)
4288 {
4289     if (!m_rareData) {
4290         if (!strut)
4291             return;
4292         m_rareData = adoptPtr(new RenderBlockRareData());
4293     }
4294     m_rareData->m_paginationStrut = strut;
4295 }
4296
4297 void RenderBlock::setPageLogicalOffset(LayoutUnit logicalOffset)
4298 {
4299     if (!m_rareData) {
4300         if (!logicalOffset)
4301             return;
4302         m_rareData = adoptPtr(new RenderBlockRareData());
4303     }
4304     m_rareData->m_pageLogicalOffset = logicalOffset;
4305 }
4306
4307 void RenderBlock::setBreakAtLineToAvoidWidow(int lineToBreak)
4308 {
4309     ASSERT(lineToBreak >= 0);
4310     if (!m_rareData)
4311         m_rareData = adoptPtr(new RenderBlockRareData());
4312
4313     ASSERT(!m_rareData->m_didBreakAtLineToAvoidWidow);
4314     m_rareData->m_lineBreakToAvoidWidow = lineToBreak;
4315 }
4316
4317 void RenderBlock::setDidBreakAtLineToAvoidWidow()
4318 {
4319     ASSERT(!shouldBreakAtLineToAvoidWidow());
4320
4321     // This function should be called only after a break was applied to avoid widows
4322     // so assert |m_rareData| exists.
4323     ASSERT(m_rareData);
4324
4325     m_rareData->m_didBreakAtLineToAvoidWidow = true;
4326 }
4327
4328 void RenderBlock::clearDidBreakAtLineToAvoidWidow()
4329 {
4330     if (!m_rareData)
4331         return;
4332
4333     m_rareData->m_didBreakAtLineToAvoidWidow = false;
4334 }
4335
4336 void RenderBlock::clearShouldBreakAtLineToAvoidWidow() const
4337 {
4338     ASSERT(shouldBreakAtLineToAvoidWidow());
4339     if (!m_rareData)
4340         return;
4341
4342     m_rareData->m_lineBreakToAvoidWidow = -1;
4343 }
4344
4345 void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
4346 {
4347     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
4348     // inline boxes above and below us (thus getting merged with them to form a single irregular
4349     // shape).
4350     if (isAnonymousBlockContinuation()) {
4351         // FIXME: This is wrong for block-flows that are horizontal.
4352         // https://bugs.webkit.org/show_bug.cgi?id=46781
4353         rects.append(pixelSnappedIntRect(accumulatedOffset.x(), accumulatedOffset.y() - collapsedMarginBefore(),
4354                                 width(), height() + collapsedMarginBefore() + collapsedMarginAfter()));
4355         continuation()->absoluteRects(rects, accumulatedOffset - toLayoutSize(location() +
4356                 inlineElementContinuation()->containingBlock()->location()));
4357     } else
4358         rects.append(pixelSnappedIntRect(accumulatedOffset, size()));
4359 }
4360
4361 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
4362 {
4363     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
4364     // inline boxes above and below us (thus getting merged with them to form a single irregular
4365     // shape).
4366     if (isAnonymousBlockContinuation()) {
4367         // FIXME: This is wrong for block-flows that are horizontal.
4368         // https://bugs.webkit.org/show_bug.cgi?id=46781
4369         FloatRect localRect(0, -collapsedMarginBefore().toFloat(),
4370             width().toFloat(), (height() + collapsedMarginBefore() + collapsedMarginAfter()).toFloat());
4371         quads.append(localToAbsoluteQuad(localRect, 0 /* mode */, wasFixed));
4372         continuation()->absoluteQuads(quads, wasFixed);
4373     } else {
4374         quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width().toFloat(), height().toFloat()), 0 /* mode */, wasFixed));
4375     }
4376 }
4377
4378 LayoutRect RenderBlock::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
4379 {
4380     LayoutRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
4381     if (isAnonymousBlockContinuation())
4382         r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
4383     return r;
4384 }
4385
4386 RenderObject* RenderBlock::hoverAncestor() const
4387 {
4388     return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
4389 }
4390
4391 void RenderBlock::updateDragState(bool dragOn)
4392 {
4393     RenderBox::updateDragState(dragOn);
4394     if (continuation())
4395         continuation()->updateDragState(dragOn);
4396 }
4397
4398 RenderStyle* RenderBlock::outlineStyleForRepaint() const
4399 {
4400     return isAnonymousBlockContinuation() ? continuation()->style() : style();
4401 }
4402
4403 void RenderBlock::childBecameNonInline(RenderObject*)
4404 {
4405     makeChildrenNonInline();
4406     if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
4407         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
4408     // |this| may be dead here
4409 }
4410
4411 void RenderBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
4412 {
4413     if (result.innerNode())
4414         return;
4415
4416     if (Node* n = nodeForHitTest()) {
4417         result.setInnerNode(n);
4418         if (!result.innerNonSharedNode())
4419             result.setInnerNonSharedNode(n);
4420         result.setLocalPoint(point);
4421     }
4422 }
4423
4424 LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
4425 {
4426     // Do the normal calculation in most cases.
4427     if (firstChild())
4428         return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
4429
4430     LayoutRect caretRect = localCaretRectForEmptyElement(width(), textIndentOffset());
4431
4432     if (extraWidthToEndOfLine) {
4433         if (isRenderBlock()) {
4434             *extraWidthToEndOfLine = width() - caretRect.maxX();
4435         } else {
4436             // FIXME: This code looks wrong.
4437             // myRight and containerRight are set up, but then clobbered.
4438             // So *extraWidthToEndOfLine will always be 0 here.
4439
4440             LayoutUnit myRight = caretRect.maxX();
4441             // FIXME: why call localToAbsoluteForContent() twice here, too?
4442             FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight.toFloat(), 0));
4443
4444             LayoutUnit containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
4445             FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight.toFloat(), 0));
4446
4447             *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
4448         }
4449     }
4450
4451     return caretRect;
4452 }
4453
4454 void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
4455 {
4456     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
4457     // inline boxes above and below us (thus getting merged with them to form a single irregular
4458     // shape).
4459     if (inlineElementContinuation()) {
4460         // FIXME: This check really isn't accurate.
4461         bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
4462         // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
4463         // FIXME: This is wrong for block-flows that are horizontal.
4464         // https://bugs.webkit.org/show_bug.cgi?id=46781
4465         bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
4466         LayoutUnit topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : LayoutUnit();
4467         LayoutUnit bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : LayoutUnit();
4468         LayoutRect rect(additionalOffset.x(), additionalOffset.y() - topMargin, width(), height() + topMargin + bottomMargin);
4469         if (!rect.isEmpty())
4470             rects.append(pixelSnappedIntRect(rect));
4471     } else if (width() && height())
4472         rects.append(pixelSnappedIntRect(additionalOffset, size()));
4473
4474     if (!hasOverflowClip() && !hasControlClip()) {
4475         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
4476             LayoutUnit top = max<LayoutUnit>(curr->lineTop(), curr->top());
4477             LayoutUnit bottom = min<LayoutUnit>(curr->lineBottom(), curr->top() + curr->height());
4478             LayoutRect rect(additionalOffset.x() + curr->x(), additionalOffset.y() + top, curr->width(), bottom - top);
4479             if (!rect.isEmpty())
4480                 rects.append(pixelSnappedIntRect(rect));
4481         }
4482
4483         for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
4484             if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
4485                 RenderBox* box = toRenderBox(curr);
4486                 FloatPoint pos;
4487                 // FIXME: This doesn't work correctly with transforms.
4488                 if (box->layer())
4489                     pos = curr->localToContainerPoint(FloatPoint(), paintContainer);
4490                 else
4491                     pos = FloatPoint((additionalOffset.x() + box->x()).toFloat(), (additionalOffset.y() + box->y()).toFloat()); // FIXME: Snap offsets? crbug.com/350474
4492                 box->addFocusRingRects(rects, flooredLayoutPoint(pos), paintContainer);
4493             }
4494         }
4495     }
4496
4497     if (inlineElementContinuation())
4498         inlineElementContinuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + inlineElementContinuation()->containingBlock()->location() - location()), paintContainer);
4499 }
4500
4501 void RenderBlock::computeSelfHitTestRects(Vector<LayoutRect>& rects, const LayoutPoint& layerOffset) const
4502 {
4503     RenderBox::computeSelfHitTestRects(rects, layerOffset);
4504
4505     if (hasHorizontalLayoutOverflow() || hasVerticalLayoutOverflow()) {
4506         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
4507             LayoutUnit top = max<LayoutUnit>(curr->lineTop(), curr->top());
4508             LayoutUnit bottom = min<LayoutUnit>(curr->lineBottom(), curr->top() + curr->height());
4509             LayoutRect rect(layerOffset.x() + curr->x(), layerOffset.y() + top, curr->width(), bottom - top);
4510             // It's common for this rect to be entirely contained in our box, so exclude that simple case.
4511             if (!rect.isEmpty() && (rects.isEmpty() || !rects[0].contains(rect)))
4512                 rects.append(rect);
4513         }
4514     }
4515 }
4516
4517 RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const
4518 {
4519     if (isAnonymousColumnsBlock())
4520         return createAnonymousColumnsWithParentRenderer(parent);
4521     if (isAnonymousColumnSpanBlock())
4522         return createAnonymousColumnSpanWithParentRenderer(parent);
4523     return createAnonymousWithParentRendererAndDisplay(parent, style()->display());
4524 }
4525
4526 LayoutUnit RenderBlock::nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
4527 {
4528     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
4529     if (!pageLogicalHeight)
4530         return logicalOffset;
4531
4532     // The logicalOffset is in our coordinate space.  We can add in our pushed offset.
4533     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset);
4534     if (pageBoundaryRule == ExcludePageBoundary)
4535         return logicalOffset + (remainingLogicalHeight ? remainingLogicalHeight : pageLogicalHeight);
4536     return logicalOffset + remainingLogicalHeight;
4537 }
4538
4539 LayoutUnit RenderBlock::pageLogicalTopForOffset(LayoutUnit offset) const
4540 {
4541     RenderView* renderView = view();
4542     LayoutUnit firstPageLogicalTop = isHorizontalWritingMode() ? renderView->layoutState()->pageOffset().height() : renderView->layoutState()->pageOffset().width();
4543     LayoutUnit blockLogicalTop = isHorizontalWritingMode() ? renderView->layoutState()->layoutOffset().height() : renderView->layoutState()->layoutOffset().width();
4544
4545     LayoutUnit cumulativeOffset = offset + blockLogicalTop;
4546     RenderFlowThread* flowThread = flowThreadContainingBlock();
4547     if (!flowThread) {
4548         LayoutUnit pageLogicalHeight = renderView->layoutState()->pageLogicalHeight();
4549         if (!pageLogicalHeight)
4550             return 0;
4551         return cumulativeOffset - roundToInt(cumulativeOffset - firstPageLogicalTop) % roundToInt(pageLogicalHeight);
4552     }
4553     return flowThread->pageLogicalTopForOffset(cumulativeOffset);
4554 }
4555
4556 LayoutUnit RenderBlock::pageLogicalHeightForOffset(LayoutUnit offset) const
4557 {
4558     RenderView* renderView = view();
4559     RenderFlowThread* flowThread = flowThreadContainingBlock();
4560     if (!flowThread)
4561         return renderView->layoutState()->pageLogicalHeight();
4562     return flowThread->pageLogicalHeightForOffset(offset + offsetFromLogicalTopOfFirstPage());
4563 }
4564
4565 LayoutUnit RenderBlock::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) const
4566 {
4567     RenderView* renderView = view();
4568     offset += offsetFromLogicalTopOfFirstPage();
4569
4570     RenderFlowThread* flowThread = flowThreadContainingBlock();
4571     if (!flowThread) {
4572         LayoutUnit pageLogicalHeight = renderView->layoutState()->pageLogicalHeight();
4573         LayoutUnit remainingHeight = pageLogicalHeight - intMod(offset, pageLogicalHeight);
4574         if (pageBoundaryRule == IncludePageBoundary) {
4575             // If includeBoundaryPoint is true the line exactly on the top edge of a
4576             // column will act as being part of the previous column.
4577             remainingHeight = intMod(remainingHeight, pageLogicalHeight);
4578         }
4579         return remainingHeight;
4580     }
4581
4582     return flowThread->pageRemainingLogicalHeightForOffset(offset, pageBoundaryRule);
4583 }
4584
4585 LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins)
4586 {
4587     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns() || flowThreadContainingBlock();
4588     bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogicalHeight();
4589     bool isUnsplittable = child->isUnsplittableForPagination() || (checkColumnBreaks && child->style()->columnBreakInside() == PBAVOID)
4590         || (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID);
4591     if (!isUnsplittable)
4592         return logicalOffset;
4593     LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit());
4594     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
4595     updateMinimumPageHeight(logicalOffset, childLogicalHeight);
4596     if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
4597         return logicalOffset;
4598     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
4599     if (remainingLogicalHeight < childLogicalHeight)
4600         return logicalOffset + remainingLogicalHeight;
4601     return logicalOffset;
4602 }
4603
4604 void RenderBlock::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
4605 {
4606     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
4607         flowThread->setPageBreak(offsetFromLogicalTopOfFirstPage() + offset, spaceShortage);
4608 }
4609
4610 void RenderBlock::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
4611 {
4612     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
4613         flowThread->updateMinimumPageHeight(offsetFromLogicalTopOfFirstPage() + offset, minHeight);
4614     else if (ColumnInfo* colInfo = view()->layoutState()->columnInfo())
4615         colInfo->updateMinimumColumnHeight(minHeight);
4616 }
4617
4618 static inline LayoutUnit calculateMinimumPageHeight(RenderStyle* renderStyle, RootInlineBox* lastLine, LayoutUnit lineTop, LayoutUnit lineBottom)
4619 {
4620     // We may require a certain minimum number of lines per page in order to satisfy
4621     // orphans and widows, and that may affect the minimum page height.
4622     unsigned lineCount = max<unsigned>(renderStyle->hasAutoOrphans() ? 1 : renderStyle->orphans(), renderStyle->hasAutoWidows() ? 1 : renderStyle->widows());
4623     if (lineCount > 1) {
4624         RootInlineBox* line = lastLine;
4625         for (unsigned i = 1; i < lineCount && line->prevRootBox(); i++)
4626             line = line->prevRootBox();
4627
4628         // FIXME: Paginating using line overflow isn't all fine. See FIXME in
4629         // adjustLinePositionForPagination() for more details.
4630         LayoutRect overflow = line->logicalVisualOverflowRect(line->lineTop(), line->lineBottom());
4631         lineTop = min(line->lineTopWithLeading(), overflow.y());
4632     }
4633     return lineBottom - lineTop;
4634 }
4635
4636 void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, LayoutUnit& delta, RenderFlowThread* flowThread)
4637 {
4638     // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
4639     // put a strut between them for pagination purposes.  However, this really isn't the desired rendering, since
4640     // the line on the top of the next page will appear too far down relative to the same kind of line at the top
4641     // of the first column.
4642     //
4643     // The rendering we would like to see is one where the lineTopWithLeading is at the top of the column, and any line overflow
4644     // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
4645     // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
4646     // for overflow to occur), and then cache visible overflow for each column rect.
4647     //
4648     // Furthermore, the paint we have to do when a column has overflow has to be special.  We need to exclude
4649     // content that paints in a previous column (and content that paints in the following column).
4650     //
4651     // For now we'll at least honor the lineTopWithLeading when paginating if it is above the logical top overflow. This will
4652     // at least make positive leading work in typical cases.
4653     //
4654     // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
4655     // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
4656     // line and all following lines.
4657     LayoutRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
4658     LayoutUnit logicalOffset = min(lineBox->lineTopWithLeading(), logicalVisualOverflow.y());
4659     LayoutUnit logicalBottom = max(lineBox->lineBottomWithLeading(), logicalVisualOverflow.maxY());
4660     LayoutUnit lineHeight = logicalBottom - logicalOffset;
4661     updateMinimumPageHeight(logicalOffset, calculateMinimumPageHeight(style(), lineBox, logicalOffset, logicalBottom));
4662     logicalOffset += delta;
4663     lineBox->setPaginationStrut(0);
4664     lineBox->setIsFirstAfterPageBreak(false);
4665     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
4666     bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
4667     // If lineHeight is greater than pageLogicalHeight, but logicalVisualOverflow.height() still fits, we are
4668     // still going to add a strut, so that the visible overflow fits on a single page.
4669     if (!pageLogicalHeight || (hasUniformPageLogicalHeight && logicalVisualOverflow.height() > pageLogicalHeight))
4670         // FIXME: In case the line aligns with the top of the page (or it's slightly shifted downwards) it will not be marked as the first line in the page.
4671         // From here, the fix is not straightforward because it's not easy to always determine when the current line is the first in the page.
4672         return;
4673     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
4674
4675     int lineIndex = lineCount(lineBox);
4676     if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex)) {
4677         if (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex) {
4678             clearShouldBreakAtLineToAvoidWidow();
4679             setDidBreakAtLineToAvoidWidow();
4680         }
4681         if (lineHeight > pageLogicalHeight) {
4682             // Split the top margin in order to avoid splitting the visible part of the line.
4683             remainingLogicalHeight -= min(lineHeight - pageLogicalHeight, max<LayoutUnit>(0, logicalVisualOverflow.y() - lineBox->lineTopWithLeading()));
4684         }
4685         LayoutUnit totalLogicalHeight = lineHeight + max<LayoutUnit>(0, logicalOffset);
4686         LayoutUnit pageLogicalHeightAtNewOffset = hasUniformPageLogicalHeight ? pageLogicalHeight : pageLogicalHeightForOffset(logicalOffset + remainingLogicalHeight);
4687         setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight);
4688         if (((lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeightAtNewOffset) || (!style()->hasAutoOrphans() && style()->orphans() >= lineIndex))
4689             && !isOutOfFlowPositioned() && !isTableCell())
4690             setPaginationStrut(remainingLogicalHeight + max<LayoutUnit>(0, logicalOffset));
4691         else {
4692             delta += remainingLogicalHeight;
4693             lineBox->setPaginationStrut(remainingLogicalHeight);
4694             lineBox->setIsFirstAfterPageBreak(true);
4695         }
4696     } else if (remainingLogicalHeight == pageLogicalHeight) {
4697         // We're at the very top of a page or column.
4698         if (lineBox != firstRootBox())
4699             lineBox->setIsFirstAfterPageBreak(true);
4700         if (lineBox != firstRootBox() || offsetFromLogicalTopOfFirstPage())
4701             setPageBreak(logicalOffset, lineHeight);
4702     }
4703 }
4704
4705 LayoutUnit RenderBlock::offsetFromLogicalTopOfFirstPage() const
4706 {
4707     LayoutState* layoutState = view()->layoutState();
4708     if (layoutState && !layoutState->isPaginated())
4709         return 0;
4710
4711     RenderFlowThread* flowThread = flowThreadContainingBlock();
4712     if (flowThread)
4713         return flowThread->offsetFromLogicalTopOfFirstRegion(this);
4714
4715     if (layoutState) {
4716         ASSERT(layoutState->renderer() == this);
4717
4718         LayoutSize offsetDelta = layoutState->layoutOffset() - layoutState->pageOffset();
4719         return isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
4720     }
4721
4722     ASSERT_NOT_REACHED();
4723     return 0;
4724 }
4725
4726 LayoutUnit RenderBlock::collapsedMarginBeforeForChild(const RenderBox* child) const
4727 {
4728     // If the child has the same directionality as we do, then we can just return its
4729     // collapsed margin.
4730     if (!child->isWritingModeRoot())
4731         return child->collapsedMarginBefore();
4732
4733     // The child has a different directionality.  If the child is parallel, then it's just
4734     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
4735     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
4736         return child->collapsedMarginAfter();
4737
4738     // The child is perpendicular to us, which means its margins don't collapse but are on the
4739     // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
4740     return marginBeforeForChild(child);
4741 }
4742
4743 LayoutUnit RenderBlock::collapsedMarginAfterForChild(const  RenderBox* child) const
4744 {
4745     // If the child has the same directionality as we do, then we can just return its
4746     // collapsed margin.
4747     if (!child->isWritingModeRoot())
4748         return child->collapsedMarginAfter();
4749
4750     // The child has a different directionality.  If the child is parallel, then it's just
4751     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
4752     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
4753         return child->collapsedMarginBefore();
4754
4755     // The child is perpendicular to us, which means its margins don't collapse but are on the
4756     // "logical left/right" side of the child box.  We can just return the raw margin in this case.
4757     return marginAfterForChild(child);
4758 }
4759
4760 bool RenderBlock::hasMarginBeforeQuirk(const RenderBox* child) const
4761 {
4762     // If the child has the same directionality as we do, then we can just return its
4763     // margin quirk.
4764     if (!child->isWritingModeRoot())
4765         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginBeforeQuirk() : child->style()->hasMarginBeforeQuirk();
4766
4767     // The child has a different directionality. If the child is parallel, then it's just
4768     // flipped relative to us. We can use the opposite edge.
4769     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
4770         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginAfterQuirk() : child->style()->hasMarginAfterQuirk();
4771
4772     // The child is perpendicular to us and box sides are never quirky in html.css, and we don't really care about
4773     // whether or not authors specified quirky ems, since they're an implementation detail.
4774     return false;
4775 }
4776
4777 bool RenderBlock::hasMarginAfterQuirk(const RenderBox* child) const
4778 {
4779     // If the child has the same directionality as we do, then we can just return its
4780     // margin quirk.
4781     if (!child->isWritingModeRoot())
4782         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginAfterQuirk() : child->style()->hasMarginAfterQuirk();
4783
4784     // The child has a different directionality. If the child is parallel, then it's just
4785     // flipped relative to us. We can use the opposite edge.
4786     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
4787         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginBeforeQuirk() : child->style()->hasMarginBeforeQuirk();
4788
4789     // The child is perpendicular to us and box sides are never quirky in html.css, and we don't really care about
4790     // whether or not authors specified quirky ems, since they're an implementation detail.
4791     return false;
4792 }
4793
4794 const char* RenderBlock::renderName() const
4795 {
4796     if (isBody())
4797         return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
4798
4799     if (isFloating())
4800         return "RenderBlock (floating)";
4801     if (isOutOfFlowPositioned())
4802         return "RenderBlock (positioned)";
4803     if (isAnonymousColumnsBlock())
4804         return "RenderBlock (anonymous multi-column)";
4805     if (isAnonymousColumnSpanBlock())
4806         return "RenderBlock (anonymous multi-column span)";
4807     if (isAnonymousBlock())
4808         return "RenderBlock (anonymous)";
4809     // FIXME: Temporary hack while the new generated content system is being implemented.
4810     if (isPseudoElement())
4811         return "RenderBlock (generated)";
4812     if (isAnonymous())
4813         return "RenderBlock (generated)";
4814     if (isRelPositioned())
4815         return "RenderBlock (relative positioned)";
4816     if (isStickyPositioned())
4817         return "RenderBlock (sticky positioned)";
4818     return "RenderBlock";
4819 }
4820
4821 RenderBlock* RenderBlock::createAnonymousWithParentRendererAndDisplay(const RenderObject* parent, EDisplay display)
4822 {
4823     // FIXME: Do we need to convert all our inline displays to block-type in the anonymous logic ?
4824     EDisplay newDisplay;
4825     RenderBlock* newBox = 0;
4826     if (display == BOX || display == INLINE_BOX) {
4827         // FIXME: Remove this case once we have eliminated all internal users of old flexbox
4828         newBox = RenderDeprecatedFlexibleBox::createAnonymous(&parent->document());
4829         newDisplay = BOX;
4830     } else if (display == FLEX || display == INLINE_FLEX) {
4831         newBox = RenderFlexibleBox::createAnonymous(&parent->document());
4832         newDisplay = FLEX;
4833     } else {
4834         newBox = RenderBlockFlow::createAnonymous(&parent->document());
4835         newDisplay = BLOCK;
4836     }
4837
4838     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), newDisplay);
4839     newBox->setStyle(newStyle.release());
4840     return newBox;
4841 }
4842
4843 RenderBlockFlow* RenderBlock::createAnonymousColumnsWithParentRenderer(const RenderObject* parent)
4844 {
4845     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), BLOCK);
4846     newStyle->inheritColumnPropertiesFrom(parent->style());
4847
4848     RenderBlockFlow* newBox = RenderBlockFlow::createAnonymous(&parent->document());
4849     newBox->setStyle(newStyle.release());
4850     return newBox;
4851 }
4852
4853 RenderBlockFlow* RenderBlock::createAnonymousColumnSpanWithParentRenderer(const RenderObject* parent)
4854 {
4855     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), BLOCK);
4856     newStyle->setColumnSpan(ColumnSpanAll);
4857
4858     RenderBlockFlow* newBox = RenderBlockFlow::createAnonymous(&parent->document());
4859     newBox->setStyle(newStyle.release());
4860     return newBox;
4861 }
4862
4863 static bool recalcNormalFlowChildOverflowIfNeeded(RenderObject* renderer)
4864 {
4865     if (renderer->isOutOfFlowPositioned() || !renderer->needsOverflowRecalcAfterStyleChange())
4866         return false;
4867
4868     ASSERT(renderer->isRenderBlock());
4869     return toRenderBlock(renderer)->recalcOverflowAfterStyleChange();
4870 }
4871
4872 bool RenderBlock::recalcChildOverflowAfterStyleChange()
4873 {
4874     ASSERT(childNeedsOverflowRecalcAfterStyleChange());
4875     setChildNeedsOverflowRecalcAfterStyleChange(false);
4876
4877     bool childrenOverflowChanged = false;
4878
4879     if (childrenInline()) {
4880         ListHashSet<RootInlineBox*> lineBoxes;
4881         for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
4882             RenderObject* renderer = walker.current();
4883             if (recalcNormalFlowChildOverflowIfNeeded(renderer)) {
4884                 childrenOverflowChanged = true;
4885                 if (InlineBox* inlineBoxWrapper = toRenderBlock(renderer)->inlineBoxWrapper())
4886                     lineBoxes.add(&inlineBoxWrapper->root());
4887             }
4888         }
4889
4890         // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
4891         GlyphOverflowAndFallbackFontsMap textBoxDataMap;
4892         for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
4893             RootInlineBox* box = *it;
4894             box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
4895         }
4896     } else {
4897         for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
4898             if (recalcNormalFlowChildOverflowIfNeeded(box))
4899                 childrenOverflowChanged = true;
4900         }
4901     }
4902
4903     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
4904     if (!positionedDescendants)
4905         return childrenOverflowChanged;
4906
4907     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
4908     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
4909         RenderBox* box = *it;
4910
4911         if (!box->needsOverflowRecalcAfterStyleChange())
4912             continue;
4913         RenderBlock* block = toRenderBlock(box);
4914         if (!block->recalcOverflowAfterStyleChange() || box->style()->position() == FixedPosition)
4915             continue;
4916
4917         childrenOverflowChanged = true;
4918     }
4919     return childrenOverflowChanged;
4920 }
4921
4922 bool RenderBlock::recalcOverflowAfterStyleChange()
4923 {
4924     ASSERT(needsOverflowRecalcAfterStyleChange());
4925
4926     bool childrenOverflowChanged = false;
4927     if (childNeedsOverflowRecalcAfterStyleChange())
4928         childrenOverflowChanged = recalcChildOverflowAfterStyleChange();
4929
4930     if (!selfNeedsOverflowRecalcAfterStyleChange() && !childrenOverflowChanged)
4931         return false;
4932
4933     setSelfNeedsOverflowRecalcAfterStyleChange(false);
4934     // If the current block needs layout, overflow will be recalculated during
4935     // layout time anyway. We can safely exit here.
4936     if (needsLayout())
4937         return false;
4938
4939     LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
4940     computeOverflow(oldClientAfterEdge, true);
4941
4942     if (hasOverflowClip())
4943         layer()->scrollableArea()->updateAfterOverflowRecalc();
4944
4945     return !hasOverflowClip();
4946 }
4947
4948 #ifndef NDEBUG
4949 void RenderBlock::checkPositionedObjectsNeedLayout()
4950 {
4951     if (!gPositionedDescendantsMap)
4952         return;
4953
4954     if (TrackedRendererListHashSet* positionedDescendantSet = positionedObjects()) {
4955         TrackedRendererListHashSet::const_iterator end = positionedDescendantSet->end();
4956         for (TrackedRendererListHashSet::const_iterator it = positionedDescendantSet->begin(); it != end; ++it) {
4957             RenderBox* currBox = *it;
4958             ASSERT(!currBox->needsLayout());
4959         }
4960     }
4961 }
4962
4963 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* markedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const RenderObject* obj) const
4964 {
4965     showRenderObject();
4966     for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox())
4967         root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLabel2, obj, 1);
4968 }
4969
4970 #endif
4971
4972 } // namespace WebCore