be7b280031146c1271ad5e7d32a91878bb9729f0
[WebKit-https.git] / Source / WebCore / rendering / RenderBlock.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2007 David Smith (catfish.man@gmail.com)
5  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include "config.h"
25 #include "RenderBlock.h"
26
27 #include "AXObjectCache.h"
28 #include "Document.h"
29 #include "Editor.h"
30 #include "Element.h"
31 #include "FloatQuad.h"
32 #include "Frame.h"
33 #include "FrameSelection.h"
34 #include "FrameView.h"
35 #include "GraphicsContext.h"
36 #include "HTMLInputElement.h"
37 #include "HTMLNames.h"
38 #include "HitTestLocation.h"
39 #include "HitTestResult.h"
40 #include "InlineElementBox.h"
41 #include "InlineIterator.h"
42 #include "InlineTextBox.h"
43 #include "LayoutRepainter.h"
44 #include "LogicalSelectionOffsetCaches.h"
45 #include "OverflowEvent.h"
46 #include "Page.h"
47 #include "PaintInfo.h"
48 #include "RenderBlockFlow.h"
49 #include "RenderBoxRegionInfo.h"
50 #include "RenderButton.h"
51 #include "RenderCombineText.h"
52 #include "RenderDeprecatedFlexibleBox.h"
53 #include "RenderFlexibleBox.h"
54 #include "RenderInline.h"
55 #include "RenderIterator.h"
56 #include "RenderLayer.h"
57 #include "RenderListMarker.h"
58 #include "RenderMenuList.h"
59 #include "RenderNamedFlowFragment.h"
60 #include "RenderNamedFlowThread.h"
61 #include "RenderRegion.h"
62 #include "RenderTableCell.h"
63 #include "RenderTextFragment.h"
64 #include "RenderTheme.h"
65 #include "RenderTreePosition.h"
66 #include "RenderView.h"
67 #include "SVGTextRunRenderingContext.h"
68 #include "Settings.h"
69 #include "ShadowRoot.h"
70 #include "TextBreakIterator.h"
71 #include "TransformState.h"
72
73 #include <wtf/NeverDestroyed.h>
74 #include <wtf/Optional.h>
75 #include <wtf/StackStats.h>
76 #include <wtf/TemporaryChange.h>
77
78 #if ENABLE(CSS_SHAPES)
79 #include "ShapeOutsideInfo.h"
80 #endif
81
82 using namespace WTF;
83 using namespace Unicode;
84
85 namespace WebCore {
86
87 using namespace HTMLNames;
88
89 struct SameSizeAsRenderBlock : public RenderBox {
90 };
91
92 COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock_should_stay_small);
93
94 static TrackedDescendantsMap* gPositionedDescendantsMap;
95 static TrackedDescendantsMap* gPercentHeightDescendantsMap;
96
97 static TrackedContainerMap* gPositionedContainerMap;
98 static TrackedContainerMap* gPercentHeightContainerMap;
99
100 typedef HashMap<RenderBlock*, std::unique_ptr<ListHashSet<RenderInline*>>> ContinuationOutlineTableMap;
101
102 struct UpdateScrollInfoAfterLayoutTransaction {
103     UpdateScrollInfoAfterLayoutTransaction(const RenderView& view)
104         : nestedCount(0)
105         , view(&view)
106     {
107     }
108
109     int nestedCount;
110     const RenderView* view;
111     HashSet<RenderBlock*> blocks;
112 };
113
114 typedef Vector<UpdateScrollInfoAfterLayoutTransaction> DelayedUpdateScrollInfoStack;
115 static std::unique_ptr<DelayedUpdateScrollInfoStack>& updateScrollInfoAfterLayoutTransactionStack()
116 {
117     static NeverDestroyed<std::unique_ptr<DelayedUpdateScrollInfoStack>> delayedUpdatedScrollInfoStack;
118     return delayedUpdatedScrollInfoStack;
119 }
120
121 // Allocated only when some of these fields have non-default values
122
123 struct RenderBlockRareData {
124     WTF_MAKE_NONCOPYABLE(RenderBlockRareData); WTF_MAKE_FAST_ALLOCATED;
125 public:
126     RenderBlockRareData()
127         : m_paginationStrut(0)
128         , m_pageLogicalOffset(0)
129         , m_flowThreadContainingBlock(Nullopt)
130     {
131     }
132
133     LayoutUnit m_paginationStrut;
134     LayoutUnit m_pageLogicalOffset;
135
136     Optional<RenderFlowThread*> m_flowThreadContainingBlock;
137 };
138
139 typedef HashMap<const RenderBlock*, std::unique_ptr<RenderBlockRareData>> RenderBlockRareDataMap;
140 static RenderBlockRareDataMap* gRareDataMap = 0;
141
142 // This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code
143 // only works on RenderBlocks. If this change, this class should be shared with other RenderBoxes.
144 class OverflowEventDispatcher {
145     WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher);
146 public:
147     OverflowEventDispatcher(const RenderBlock* block)
148         : m_block(block)
149         , m_hadHorizontalLayoutOverflow(false)
150         , m_hadVerticalLayoutOverflow(false)
151     {
152         m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowClip() && m_block->document().hasListenerType(Document::OVERFLOWCHANGED_LISTENER);
153         if (m_shouldDispatchEvent) {
154             m_hadHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
155             m_hadVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
156         }
157     }
158
159     ~OverflowEventDispatcher()
160     {
161         if (!m_shouldDispatchEvent)
162             return;
163
164         bool hasHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
165         bool hasVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
166
167         bool horizontalLayoutOverflowChanged = hasHorizontalLayoutOverflow != m_hadHorizontalLayoutOverflow;
168         bool verticalLayoutOverflowChanged = hasVerticalLayoutOverflow != m_hadVerticalLayoutOverflow;
169         if (!horizontalLayoutOverflowChanged && !verticalLayoutOverflowChanged)
170             return;
171
172         RefPtr<OverflowEvent> overflowEvent = OverflowEvent::create(horizontalLayoutOverflowChanged, hasHorizontalLayoutOverflow, verticalLayoutOverflowChanged, hasVerticalLayoutOverflow);
173         overflowEvent->setTarget(m_block->element());
174         m_block->document().enqueueOverflowEvent(overflowEvent.release());
175     }
176
177 private:
178     const RenderBlock* m_block;
179     bool m_shouldDispatchEvent;
180     bool m_hadHorizontalLayoutOverflow;
181     bool m_hadVerticalLayoutOverflow;
182 };
183
184 RenderBlock::RenderBlock(Element& element, Ref<RenderStyle>&& style, unsigned baseTypeFlags)
185     : RenderBox(element, WTF::move(style), baseTypeFlags | RenderBlockFlag)
186 {
187 }
188
189 RenderBlock::RenderBlock(Document& document, Ref<RenderStyle>&& style, unsigned baseTypeFlags)
190     : RenderBox(document, WTF::move(style), baseTypeFlags | RenderBlockFlag)
191 {
192 }
193
194 static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
195 {
196     if (std::unique_ptr<TrackedRendererListHashSet> descendantSet = descendantMap->take(block)) {
197         TrackedRendererListHashSet::iterator end = descendantSet->end();
198         for (TrackedRendererListHashSet::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
199             TrackedContainerMap::iterator it = containerMap->find(*descendant);
200             ASSERT(it != containerMap->end());
201             if (it == containerMap->end())
202                 continue;
203             HashSet<RenderBlock*>* containerSet = it->value.get();
204             ASSERT(containerSet->contains(block));
205             containerSet->remove(block);
206             if (containerSet->isEmpty())
207                 containerMap->remove(it);
208         }
209     }
210 }
211
212 RenderBlock::~RenderBlock()
213 {
214     removeFromUpdateScrollInfoAfterLayoutTransaction();
215
216     if (gRareDataMap)
217         gRareDataMap->remove(this);
218     if (gPercentHeightDescendantsMap)
219         removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
220     if (gPositionedDescendantsMap)
221         removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap);
222 }
223
224 void RenderBlock::willBeDestroyed()
225 {
226     if (!documentBeingDestroyed()) {
227         if (parent())
228             parent()->dirtyLinesFromChangedChild(*this);
229     }
230
231     RenderBox::willBeDestroyed();
232 }
233
234 bool RenderBlock::hasRareData() const
235 {
236     return gRareDataMap ? gRareDataMap->contains(this) : false;
237 }
238
239 void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
240 {
241     const RenderStyle* oldStyle = hasInitializedStyle() ? &style() : nullptr;
242
243     setReplaced(newStyle.isDisplayInlineType());
244
245     if (oldStyle && parent() && diff == StyleDifferenceLayout && oldStyle->position() != newStyle.position()) {
246         if (newStyle.position() == StaticPosition)
247             // Clear our positioned objects list. Our absolutely positioned descendants will be
248             // inserted into our containing block's positioned objects list during layout.
249             removePositionedObjects(0, NewContainingBlock);
250         else if (oldStyle->position() == StaticPosition) {
251             // Remove our absolutely positioned descendants from their current containing block.
252             // They will be inserted into our positioned objects list during layout.
253             auto containingBlock = parent();
254             while (containingBlock && (containingBlock->style().position() == StaticPosition || (containingBlock->isInline() && !containingBlock->isReplaced())) && !containingBlock->isRenderView()) {
255                 if (containingBlock->style().position() == RelativePosition && containingBlock->isInline() && !containingBlock->isReplaced()) {
256                     containingBlock = containingBlock->containingBlock();
257                     break;
258                 }
259                 containingBlock = containingBlock->parent();
260             }
261
262             if (is<RenderBlock>(*containingBlock))
263                 downcast<RenderBlock>(*containingBlock).removePositionedObjects(this, NewContainingBlock);
264         }
265     }
266
267     RenderBox::styleWillChange(diff, newStyle);
268 }
269
270 static bool borderOrPaddingLogicalWidthChanged(const RenderStyle* oldStyle, const RenderStyle* newStyle)
271 {
272     if (newStyle->isHorizontalWritingMode())
273         return oldStyle->borderLeftWidth() != newStyle->borderLeftWidth()
274             || oldStyle->borderRightWidth() != newStyle->borderRightWidth()
275             || oldStyle->paddingLeft() != newStyle->paddingLeft()
276             || oldStyle->paddingRight() != newStyle->paddingRight();
277
278     return oldStyle->borderTopWidth() != newStyle->borderTopWidth()
279         || oldStyle->borderBottomWidth() != newStyle->borderBottomWidth()
280         || oldStyle->paddingTop() != newStyle->paddingTop()
281         || oldStyle->paddingBottom() != newStyle->paddingBottom();
282 }
283
284 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
285 {
286     RenderStyle& newStyle = style();
287
288     bool hadTransform = hasTransform();
289     bool flowThreadContainingBlockInvalidated = false;
290     if (oldStyle && oldStyle->position() != newStyle.position()) {
291         invalidateFlowThreadContainingBlockIncludingDescendants();
292         flowThreadContainingBlockInvalidated = true;
293     }
294
295     RenderBox::styleDidChange(diff, oldStyle);
296
297     if (hadTransform != hasTransform() && !flowThreadContainingBlockInvalidated)
298         invalidateFlowThreadContainingBlockIncludingDescendants();
299
300     if (!isAnonymousBlock()) {
301         // Ensure that all of our continuation blocks pick up the new style.
302         for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
303             RenderBoxModelObject* nextCont = currCont->continuation();
304             currCont->setContinuation(0);
305             currCont->setStyle(newStyle);
306             currCont->setContinuation(nextCont);
307         }
308     }
309
310     propagateStyleToAnonymousChildren(PropagateToBlockChildrenOnly);
311
312     // It's possible for our border/padding to change, but for the overall logical width of the block to
313     // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
314     setHasBorderOrPaddingLogicalWidthChanged(oldStyle && diff == StyleDifferenceLayout && needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, &newStyle));
315 }
316
317 RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
318 {
319     if (beforeChild && beforeChild->parent() == this)
320         return this;
321
322     RenderBlock* nextToLast = this;
323     RenderBlock* last = this;
324     for (auto* current = downcast<RenderBlock>(continuation()); current; current = downcast<RenderBlock>(current->continuation())) {
325         if (beforeChild && beforeChild->parent() == current) {
326             if (current->firstChild() == beforeChild)
327                 return last;
328             return current;
329         }
330
331         nextToLast = last;
332         last = current;
333     }
334
335     if (!beforeChild && !last->firstChild())
336         return nextToLast;
337     return last;
338 }
339
340 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
341 {
342     RenderBlock* flow = continuationBefore(beforeChild);
343     ASSERT(!beforeChild || is<RenderBlock>(*beforeChild->parent()));
344     RenderBoxModelObject* beforeChildParent = nullptr;
345     if (beforeChild)
346         beforeChildParent = downcast<RenderBoxModelObject>(beforeChild->parent());
347     else {
348         RenderBoxModelObject* continuation = flow->continuation();
349         if (continuation)
350             beforeChildParent = continuation;
351         else
352             beforeChildParent = flow;
353     }
354
355     if (newChild->isFloatingOrOutOfFlowPositioned()) {
356         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
357         return;
358     }
359
360     bool childIsNormal = newChild->isInline() || !newChild->style().columnSpan();
361     bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style().columnSpan();
362     bool flowIsNormal = flow->isInline() || !flow->style().columnSpan();
363
364     if (flow == beforeChildParent) {
365         flow->addChildIgnoringContinuation(newChild, beforeChild);
366         return;
367     }
368     
369     // The goal here is to match up if we can, so that we can coalesce and create the
370     // minimal # of continuations needed for the inline.
371     if (childIsNormal == bcpIsNormal) {
372         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
373         return;
374     }
375     if (flowIsNormal == childIsNormal) {
376         flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
377         return;
378     }
379     beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
380 }
381
382 RenderPtr<RenderBlock> RenderBlock::clone() const
383 {
384     RenderPtr<RenderBlock> cloneBlock;
385     if (isAnonymousBlock()) {
386         cloneBlock = RenderPtr<RenderBlock>(createAnonymousBlock());
387         cloneBlock->setChildrenInline(childrenInline());
388     } else {
389         RenderTreePosition insertionPosition(*parent());
390         cloneBlock = static_pointer_cast<RenderBlock>(element()->createElementRenderer(style(), insertionPosition));
391         cloneBlock->initializeStyle();
392
393         // This takes care of setting the right value of childrenInline in case
394         // generated content is added to cloneBlock and 'this' does not have
395         // generated content added yet.
396         cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->firstChild()->isInline() : childrenInline());
397     }
398     cloneBlock->setFlowThreadState(flowThreadState());
399     return cloneBlock;
400 }
401
402 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
403 {
404     if (continuation() && !isAnonymousBlock())
405         addChildToContinuation(newChild, beforeChild);
406     else
407         addChildIgnoringContinuation(newChild, beforeChild);
408 }
409
410 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
411 {
412     if (beforeChild && beforeChild->parent() != this) {
413         RenderElement* beforeChildContainer = beforeChild->parent();
414         while (beforeChildContainer->parent() != this)
415             beforeChildContainer = beforeChildContainer->parent();
416         ASSERT(beforeChildContainer);
417
418         if (beforeChildContainer->isAnonymous()) {
419             // If the requested beforeChild is not one of our children, then this is because
420             // there is an anonymous container within this object that contains the beforeChild.
421             RenderElement* beforeChildAnonymousContainer = beforeChildContainer;
422             if (beforeChildAnonymousContainer->isAnonymousBlock()
423 #if ENABLE(FULLSCREEN_API)
424                 // Full screen renderers and full screen placeholders act as anonymous blocks, not tables:
425                 || beforeChildAnonymousContainer->isRenderFullScreen()
426                 || beforeChildAnonymousContainer->isRenderFullScreenPlaceholder()
427 #endif
428                 ) {
429                 // Insert the child into the anonymous block box instead of here.
430                 if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
431                     beforeChild->parent()->addChild(newChild, beforeChild);
432                 else
433                     addChild(newChild, beforeChild->parent());
434                 return;
435             }
436
437             ASSERT(beforeChildAnonymousContainer->isTable());
438             if (newChild->isTablePart()) {
439                 // Insert into the anonymous table.
440                 beforeChildAnonymousContainer->addChild(newChild, beforeChild);
441                 return;
442             }
443
444             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
445
446             ASSERT(beforeChild->parent() == this);
447             if (beforeChild->parent() != this) {
448                 // We should never reach here. If we do, we need to use the
449                 // safe fallback to use the topmost beforeChild container.
450                 beforeChild = beforeChildContainer;
451             }
452         }
453     }
454
455     bool madeBoxesNonInline = false;
456
457     // A block has to either have all of its children inline, or all of its children as blocks.
458     // So, if our children are currently inline and a block child has to be inserted, we move all our
459     // inline children into anonymous block boxes.
460     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned()) {
461         // This is a block with inline content. Wrap the inline content in anonymous blocks.
462         makeChildrenNonInline(beforeChild);
463         madeBoxesNonInline = true;
464
465         if (beforeChild && beforeChild->parent() != this) {
466             beforeChild = beforeChild->parent();
467             ASSERT(beforeChild->isAnonymousBlock());
468             ASSERT(beforeChild->parent() == this);
469         }
470     } else if (!childrenInline() && (newChild->isFloatingOrOutOfFlowPositioned() || newChild->isInline())) {
471         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
472         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
473         // a new one is created and inserted into our list of children in the appropriate position.
474         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
475
476         if (afterChild && afterChild->isAnonymousBlock()) {
477             downcast<RenderBlock>(*afterChild).addChild(newChild);
478             return;
479         }
480
481         if (newChild->isInline()) {
482             // No suitable existing anonymous box - create a new one.
483             RenderBlock* newBox = createAnonymousBlock();
484             RenderBox::addChild(newBox, beforeChild);
485             newBox->addChild(newChild);
486             return;
487         }
488     }
489
490     invalidateLineLayoutPath();
491
492     RenderBox::addChild(newChild, beforeChild);
493  
494     if (madeBoxesNonInline && is<RenderBlock>(parent()) && isAnonymousBlock())
495         downcast<RenderBlock>(*parent()).removeLeftoverAnonymousBlock(this);
496     // this object may be dead here
497 }
498
499 static void getInlineRun(RenderObject* start, RenderObject* boundary,
500                          RenderObject*& inlineRunStart,
501                          RenderObject*& inlineRunEnd)
502 {
503     // Beginning at |start| we find the largest contiguous run of inlines that
504     // we can.  We denote the run with start and end points, |inlineRunStart|
505     // and |inlineRunEnd|.  Note that these two values may be the same if
506     // we encounter only one inline.
507     //
508     // We skip any non-inlines we encounter as long as we haven't found any
509     // inlines yet.
510     //
511     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
512     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
513     // a non-inline.
514     
515     // Start by skipping as many non-inlines as we can.
516     RenderObject * curr = start;
517     bool sawInline;
518     do {
519         while (curr && !(curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()))
520             curr = curr->nextSibling();
521         
522         inlineRunStart = inlineRunEnd = curr;
523         
524         if (!curr)
525             return; // No more inline children to be found.
526         
527         sawInline = curr->isInline();
528         
529         curr = curr->nextSibling();
530         while (curr && (curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()) && (curr != boundary)) {
531             inlineRunEnd = curr;
532             if (curr->isInline())
533                 sawInline = true;
534             curr = curr->nextSibling();
535         }
536     } while (!sawInline);
537 }
538
539 void RenderBlock::deleteLines()
540 {
541     if (AXObjectCache* cache = document().existingAXObjectCache())
542         cache->recomputeIsIgnored(this);
543 }
544
545 void RenderBlock::makeChildrenNonInline(RenderObject* insertionPoint)
546 {    
547     // makeChildrenNonInline takes a block whose children are *all* inline and it
548     // makes sure that inline children are coalesced under anonymous
549     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
550     // the new block child that is causing us to have to wrap all the inlines.  This
551     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
552     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
553     // splitting them.
554     ASSERT(isInlineBlockOrInlineTable() || !isInline());
555     ASSERT(!insertionPoint || insertionPoint->parent() == this);
556
557     setChildrenInline(false);
558
559     RenderObject* child = firstChild();
560     if (!child)
561         return;
562
563     deleteLines();
564
565     while (child) {
566         RenderObject* inlineRunStart;
567         RenderObject* inlineRunEnd;
568         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
569
570         if (!inlineRunStart)
571             break;
572
573         child = inlineRunEnd->nextSibling();
574
575         RenderBlock* block = createAnonymousBlock();
576         insertChildInternal(block, inlineRunStart, NotifyChildren);
577         moveChildrenTo(block, inlineRunStart, child);
578     }
579
580 #ifndef NDEBUG
581     for (RenderObject* c = firstChild(); c; c = c->nextSibling())
582         ASSERT(!c->isInline());
583 #endif
584
585     repaint();
586 }
587
588 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
589 {
590     ASSERT(child->isAnonymousBlock());
591     ASSERT(!child->childrenInline());
592     
593     if (child->continuation())
594         return;
595     
596     RenderObject* firstAnChild = child->firstChild();
597     RenderObject* lastAnChild = child->lastChild();
598     if (firstAnChild) {
599         RenderObject* o = firstAnChild;
600         while (o) {
601             o->setParent(this);
602             o = o->nextSibling();
603         }
604         firstAnChild->setPreviousSibling(child->previousSibling());
605         lastAnChild->setNextSibling(child->nextSibling());
606         if (child->previousSibling())
607             child->previousSibling()->setNextSibling(firstAnChild);
608         if (child->nextSibling())
609             child->nextSibling()->setPreviousSibling(lastAnChild);
610             
611         if (child == firstChild())
612             setFirstChild(firstAnChild);
613         if (child == lastChild())
614             setLastChild(lastAnChild);
615     } else {
616         if (child == firstChild())
617             setFirstChild(child->nextSibling());
618         if (child == lastChild())
619             setLastChild(child->previousSibling());
620
621         if (child->previousSibling())
622             child->previousSibling()->setNextSibling(child->nextSibling());
623         if (child->nextSibling())
624             child->nextSibling()->setPreviousSibling(child->previousSibling());
625     }
626
627     child->setFirstChild(0);
628     child->m_next = 0;
629
630     // Remove all the information in the flow thread associated with the leftover anonymous block.
631     child->removeFromRenderFlowThread();
632
633     child->setParent(0);
634     child->setPreviousSibling(0);
635     child->setNextSibling(0);
636
637     child->destroy();
638 }
639
640 static bool canMergeAnonymousBlock(RenderBlock& anonymousBlock)
641 {
642     if (anonymousBlock.beingDestroyed() || anonymousBlock.continuation())
643         return false;
644     if (anonymousBlock.isRubyRun() || anonymousBlock.isRubyBase())
645         return false;
646     return true;
647 }
648
649 static bool canMergeContiguousAnonymousBlocks(RenderObject& oldChild, RenderObject* previous, RenderObject* next)
650 {
651     if (oldChild.documentBeingDestroyed() || oldChild.isInline() || oldChild.virtualContinuation())
652         return false;
653
654     if (previous) {
655         if (!previous->isAnonymousBlock())
656             return false;
657         RenderBlock& previousAnonymousBlock = downcast<RenderBlock>(*previous);
658         if (!canMergeAnonymousBlock(previousAnonymousBlock))
659             return false;
660     }
661     if (next) {
662         if (!next->isAnonymousBlock())
663             return false;
664         RenderBlock& nextAnonymousBlock = downcast<RenderBlock>(*next);
665         if (!canMergeAnonymousBlock(nextAnonymousBlock))
666             return false;
667     }
668     return true;
669 }
670
671 void RenderBlock::collapseAnonymousBoxChild(RenderBlock& parent, RenderBlock* child)
672 {
673     parent.setNeedsLayoutAndPrefWidthsRecalc();
674     parent.setChildrenInline(child->childrenInline());
675     RenderObject* nextSibling = child->nextSibling();
676
677     if (auto* childFlowThread = child->flowThreadContainingBlock())
678         childFlowThread->removeFlowChildInfo(child);
679
680     parent.removeChildInternal(*child, child->hasLayer() ? NotifyChildren : DontNotifyChildren);
681     child->moveAllChildrenTo(&parent, nextSibling, child->hasLayer());
682     // Delete the now-empty block's lines and nuke it.
683     child->deleteLines();
684     child->destroy();
685 }
686
687 void RenderBlock::removeChild(RenderObject& oldChild)
688 {
689     // No need to waste time in merging or removing empty anonymous blocks.
690     // We can just bail out if our document is getting destroyed.
691     if (documentBeingDestroyed()) {
692         RenderBox::removeChild(oldChild);
693         return;
694     }
695
696     // If this child is a block, and if our previous and next siblings are both anonymous blocks
697     // with inline content, then we can fold the inline content back together.
698     RenderObject* prev = oldChild.previousSibling();
699     RenderObject* next = oldChild.nextSibling();
700     bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
701     if (canMergeAnonymousBlocks && prev && next) {
702         prev->setNeedsLayoutAndPrefWidthsRecalc();
703         RenderBlock& nextBlock = downcast<RenderBlock>(*next);
704         RenderBlock& prevBlock = downcast<RenderBlock>(*prev);
705        
706         if (prev->childrenInline() != next->childrenInline()) {
707             RenderBlock& inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
708             RenderBlock& blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
709             
710             // Place the inline children block inside of the block children block instead of deleting it.
711             // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
712             // to clear out inherited column properties by just making a new style, and to also clear the
713             // column span flag if it is set.
714             ASSERT(!inlineChildrenBlock.continuation());
715             // Cache this value as it might get changed in setStyle() call.
716             bool inlineChildrenBlockHasLayer = inlineChildrenBlock.hasLayer();
717             inlineChildrenBlock.setStyle(RenderStyle::createAnonymousStyleWithDisplay(&style(), BLOCK));
718             removeChildInternal(inlineChildrenBlock, inlineChildrenBlockHasLayer ? NotifyChildren : DontNotifyChildren);
719             
720             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
721             RenderObject* beforeChild = prev == &inlineChildrenBlock ? blockChildrenBlock.firstChild() : nullptr;
722             blockChildrenBlock.insertChildInternal(&inlineChildrenBlock, beforeChild,
723                 (inlineChildrenBlockHasLayer || blockChildrenBlock.hasLayer()) ? NotifyChildren : DontNotifyChildren);
724             next->setNeedsLayoutAndPrefWidthsRecalc();
725             
726             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
727             // of "this". we null out prev or next so that is not used later in the function.
728             if (&inlineChildrenBlock == &prevBlock)
729                 prev = nullptr;
730             else
731                 next = nullptr;
732         } else {
733             // Take all the children out of the |next| block and put them in
734             // the |prev| block.
735             nextBlock.moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock.hasLayer() || prevBlock.hasLayer());
736             
737             // Delete the now-empty block's lines and nuke it.
738             nextBlock.deleteLines();
739             nextBlock.destroy();
740             next = nullptr;
741         }
742     }
743
744     invalidateLineLayoutPath();
745
746     RenderBox::removeChild(oldChild);
747
748     RenderObject* child = prev ? prev : next;
749     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && canCollapseAnonymousBlockChild()) {
750         // The removal has knocked us down to containing only a single anonymous
751         // box. We can pull the content right back up into our box.
752         collapseAnonymousBoxChild(*this, downcast<RenderBlock>(child));
753     } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && canCollapseAnonymousBlockChild()) {
754         // It's possible that the removal has knocked us down to a single anonymous
755         // block with pseudo-style element siblings (e.g. first-letter). If these
756         // are floating, then we need to pull the content up also.
757         RenderBlock* anonBlock = downcast<RenderBlock>((prev && prev->isAnonymousBlock()) ? prev : next);
758         if ((anonBlock->previousSibling() || anonBlock->nextSibling())
759             && (!anonBlock->previousSibling() || (anonBlock->previousSibling()->style().styleType() != NOPSEUDO && anonBlock->previousSibling()->isFloating() && !anonBlock->previousSibling()->previousSibling()))
760             && (!anonBlock->nextSibling() || (anonBlock->nextSibling()->style().styleType() != NOPSEUDO && anonBlock->nextSibling()->isFloating() && !anonBlock->nextSibling()->nextSibling()))) {
761             collapseAnonymousBoxChild(*this, anonBlock);
762         }
763     }
764
765     if (!firstChild()) {
766         // If this was our last child be sure to clear out our line boxes.
767         if (childrenInline())
768             deleteLines();
769
770         // If we are an empty anonymous block in the continuation chain,
771         // we need to remove ourself and fix the continuation chain.
772         if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild.isListMarker()) {
773             auto containingBlockIgnoringAnonymous = containingBlock();
774             while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymousBlock())
775                 containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
776             for (RenderObject* current = this; current; current = current->previousInPreOrder(containingBlockIgnoringAnonymous)) {
777                 if (current->virtualContinuation() != this)
778                     continue;
779
780                 // Found our previous continuation. We just need to point it to
781                 // |this|'s next continuation.
782                 RenderBoxModelObject* nextContinuation = continuation();
783                 if (is<RenderInline>(*current))
784                     downcast<RenderInline>(*current).setContinuation(nextContinuation);
785                 else if (is<RenderBlock>(*current))
786                     downcast<RenderBlock>(*current).setContinuation(nextContinuation);
787                 else
788                     ASSERT_NOT_REACHED();
789
790                 break;
791             }
792             setContinuation(nullptr);
793             destroy();
794         }
795     }
796 }
797
798 bool RenderBlock::isSelfCollapsingBlock() const
799 {
800     // We are not self-collapsing if we
801     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
802     // (b) are a table,
803     // (c) have border/padding,
804     // (d) have a min-height
805     // (e) have specified that one of our margins can't collapse using a CSS extension
806     if (logicalHeight() > 0
807         || isTable() || borderAndPaddingLogicalHeight()
808         || style().logicalMinHeight().isPositive()
809         || style().marginBeforeCollapse() == MSEPARATE || style().marginAfterCollapse() == MSEPARATE)
810         return false;
811
812     Length logicalHeightLength = style().logicalHeight();
813     bool hasAutoHeight = logicalHeightLength.isAuto();
814     if (logicalHeightLength.isPercentOrCalculated() && !document().inQuirksMode()) {
815         hasAutoHeight = true;
816         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
817             if (cb->style().logicalHeight().isFixed() || cb->isTableCell())
818                 hasAutoHeight = false;
819         }
820     }
821
822     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
823     // on whether we have content that is all self-collapsing or not.
824     if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercentOrCalculated()) && logicalHeightLength.isZero())) {
825         // If the block has inline children, see if we generated any line boxes.  If we have any
826         // line boxes, then we can't be self-collapsing, since we have content.
827         if (childrenInline())
828             return !hasLines();
829         
830         // Whether or not we collapse is dependent on whether all our normal flow children
831         // are also self-collapsing.
832         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
833             if (child->isFloatingOrOutOfFlowPositioned())
834                 continue;
835             if (!child->isSelfCollapsingBlock())
836                 return false;
837         }
838         return true;
839     }
840     return false;
841 }
842
843 static inline UpdateScrollInfoAfterLayoutTransaction* currentUpdateScrollInfoAfterLayoutTransaction()
844 {
845     if (!updateScrollInfoAfterLayoutTransactionStack())
846         return nullptr;
847     return &updateScrollInfoAfterLayoutTransactionStack()->last();
848 }
849
850 void RenderBlock::beginUpdateScrollInfoAfterLayoutTransaction()
851 {
852     if (!updateScrollInfoAfterLayoutTransactionStack())
853         updateScrollInfoAfterLayoutTransactionStack() = std::make_unique<DelayedUpdateScrollInfoStack>();
854     if (updateScrollInfoAfterLayoutTransactionStack()->isEmpty() || currentUpdateScrollInfoAfterLayoutTransaction()->view != &view())
855         updateScrollInfoAfterLayoutTransactionStack()->append(UpdateScrollInfoAfterLayoutTransaction(view()));
856     ++currentUpdateScrollInfoAfterLayoutTransaction()->nestedCount;
857 }
858
859 void RenderBlock::endAndCommitUpdateScrollInfoAfterLayoutTransaction()
860 {
861     UpdateScrollInfoAfterLayoutTransaction* transaction = currentUpdateScrollInfoAfterLayoutTransaction();
862     ASSERT(transaction);
863     ASSERT(transaction->view == &view());
864     if (--transaction->nestedCount)
865         return;
866
867     // Calling RenderLayer::updateScrollInfoAfterLayout() may cause its associated block to layout again and
868     // updates its scroll info (i.e. call RenderBlock::updateScrollInfoAfterLayout()). We remove |transaction|
869     // from the transaction stack to ensure that all subsequent calls to RenderBlock::updateScrollInfoAfterLayout()
870     // are dispatched immediately. That is, to ensure that such subsequent calls aren't added to |transaction|
871     // while we are processing it.
872     Vector<RenderBlock*> blocksToUpdate;
873     copyToVector(transaction->blocks, blocksToUpdate);
874     updateScrollInfoAfterLayoutTransactionStack()->removeLast();
875     if (updateScrollInfoAfterLayoutTransactionStack()->isEmpty())
876         updateScrollInfoAfterLayoutTransactionStack() = nullptr;
877
878     for (auto* block : blocksToUpdate) {
879         ASSERT(block->hasOverflowClip());
880         block->layer()->updateScrollInfoAfterLayout();
881         block->clearLayoutOverflow();
882     }
883 }
884
885 void RenderBlock::removeFromUpdateScrollInfoAfterLayoutTransaction()
886 {
887     if (UNLIKELY(updateScrollInfoAfterLayoutTransactionStack().get() != 0)) {
888         UpdateScrollInfoAfterLayoutTransaction* transaction = currentUpdateScrollInfoAfterLayoutTransaction();
889         ASSERT(transaction);
890         if (transaction->view == &view())
891             transaction->blocks.remove(this);
892     }
893 }
894
895 void RenderBlock::updateScrollInfoAfterLayout()
896 {
897     if (hasOverflowClip()) {
898         if (style().isFlippedBlocksWritingMode()) {
899             // FIXME: https://bugs.webkit.org/show_bug.cgi?id=97937
900             // Workaround for now. We cannot delay the scroll info for overflow
901             // for items with opposite writing directions, as the contents needs
902             // to overflow in that direction
903             layer()->updateScrollInfoAfterLayout();
904             return;
905         }
906
907         UpdateScrollInfoAfterLayoutTransaction* transaction = currentUpdateScrollInfoAfterLayoutTransaction();
908         if (transaction && transaction->view == &view()) {
909             transaction->blocks.add(this);
910             return;
911         }
912         layer()->updateScrollInfoAfterLayout();
913     }
914 }
915
916 void RenderBlock::layout()
917 {
918     StackStats::LayoutCheckPoint layoutCheckPoint;
919     OverflowEventDispatcher dispatcher(this);
920
921     // Update our first letter info now.
922     updateFirstLetter();
923
924     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
925     // layoutBlock().
926     layoutBlock(false);
927     
928     // It's safe to check for control clip here, since controls can never be table cells.
929     // If we have a lightweight clip, there can never be any overflow from children.
930     UpdateScrollInfoAfterLayoutTransaction* transaction = currentUpdateScrollInfoAfterLayoutTransaction();
931     bool isDelayingUpdateScrollInfoAfterLayoutInView = transaction && transaction->view == &view();
932     if (hasControlClip() && m_overflow && !isDelayingUpdateScrollInfoAfterLayoutInView)
933         clearLayoutOverflow();
934
935     invalidateBackgroundObscurationStatus();
936 }
937
938 static RenderBlockRareData* getBlockRareData(const RenderBlock* block)
939 {
940     return gRareDataMap ? gRareDataMap->get(block) : nullptr;
941 }
942
943 static RenderBlockRareData& ensureBlockRareData(const RenderBlock* block)
944 {
945     if (!gRareDataMap)
946         gRareDataMap = new RenderBlockRareDataMap;
947     
948     auto& rareData = gRareDataMap->add(block, nullptr).iterator->value;
949     if (!rareData)
950         rareData = std::make_unique<RenderBlockRareData>();
951     return *rareData.get();
952 }
953
954 void RenderBlock::preparePaginationBeforeBlockLayout(bool& relayoutChildren)
955 {
956     // Regions changing widths can force us to relayout our children.
957     RenderFlowThread* flowThread = flowThreadContainingBlock();
958     if (flowThread)
959         flowThread->logicalWidthChangedInRegionsForBlock(this, relayoutChildren);
960 }
961
962 bool RenderBlock::recomputeLogicalWidth()
963 {
964     LayoutUnit oldWidth = logicalWidth();
965     
966     updateLogicalWidth();
967     
968     bool hasBorderOrPaddingLogicalWidthChanged = this->hasBorderOrPaddingLogicalWidthChanged();
969     setHasBorderOrPaddingLogicalWidthChanged(false);
970
971     return oldWidth != logicalWidth() || hasBorderOrPaddingLogicalWidthChanged;
972 }
973
974 void RenderBlock::layoutBlock(bool, LayoutUnit)
975 {
976     ASSERT_NOT_REACHED();
977     clearNeedsLayout();
978 }
979
980 void RenderBlock::addOverflowFromChildren()
981 {
982     if (childrenInline())
983         addOverflowFromInlineChildren();
984     else
985         addOverflowFromBlockChildren();
986     
987     // If this block is flowed inside a flow thread, make sure its overflow is propagated to the containing regions.
988     if (m_overflow) {
989         if (RenderFlowThread* containingFlowThread = flowThreadContainingBlock())
990             containingFlowThread->addRegionsVisualOverflow(this, m_overflow->visualOverflowRect());
991     }
992 }
993
994 void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool)
995 {
996     clearOverflow();
997
998     // Add overflow from children.
999     addOverflowFromChildren();
1000
1001     // Add in the overflow from positioned objects.
1002     addOverflowFromPositionedObjects();
1003
1004     if (hasOverflowClip()) {
1005         // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
1006         // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
1007         // be considered reachable.
1008         LayoutRect clientRect(flippedClientBoxRect());
1009         LayoutRect rectToApply;
1010         if (isHorizontalWritingMode())
1011             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), 1, std::max<LayoutUnit>(0, oldClientAfterEdge - clientRect.y()));
1012         else
1013             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), std::max<LayoutUnit>(0, oldClientAfterEdge - clientRect.x()), 1);
1014         addLayoutOverflow(rectToApply);
1015         if (hasRenderOverflow())
1016             m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge);
1017     }
1018         
1019     // Add visual overflow from box-shadow and border-image-outset.
1020     addVisualEffectOverflow();
1021
1022     // Add visual overflow from theme.
1023     addVisualOverflowFromTheme();
1024 }
1025
1026 void RenderBlock::clearLayoutOverflow()
1027 {
1028     if (!m_overflow)
1029         return;
1030     
1031     if (visualOverflowRect() == borderBoxRect()) {
1032         // FIXME: Implement complete solution for regions overflow.
1033         clearOverflow();
1034         return;
1035     }
1036     
1037     m_overflow->setLayoutOverflow(borderBoxRect());
1038 }
1039
1040 void RenderBlock::addOverflowFromBlockChildren()
1041 {
1042     for (auto child = firstChildBox(); child; child = child->nextSiblingBox()) {
1043         if (!child->isFloatingOrOutOfFlowPositioned())
1044             addOverflowFromChild(child);
1045     }
1046 }
1047
1048 void RenderBlock::addOverflowFromPositionedObjects()
1049 {
1050     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
1051     if (!positionedDescendants)
1052         return;
1053
1054     for (auto it = positionedDescendants->begin(), end = positionedDescendants->end(); it != end; ++it) {
1055         RenderBox* positionedObject = *it;
1056         
1057         // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
1058         if (positionedObject->style().position() != FixedPosition) {
1059             LayoutUnit x = positionedObject->x();
1060             if (style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
1061                 x -= verticalScrollbarWidth();
1062             addOverflowFromChild(positionedObject, LayoutSize(x, positionedObject->y()));
1063         }
1064     }
1065 }
1066
1067 void RenderBlock::addVisualOverflowFromTheme()
1068 {
1069     if (!style().hasAppearance())
1070         return;
1071
1072     FloatRect inflatedRect = borderBoxRect();
1073     theme().adjustRepaintRect(*this, inflatedRect);
1074     addVisualOverflow(snappedIntRect(LayoutRect(inflatedRect)));
1075
1076     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
1077         flowThread->addRegionsVisualOverflowFromTheme(this);
1078 }
1079
1080 LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const RenderBox& child, LayoutUnit childMarginStart, RenderRegion* region)
1081 {
1082     LayoutUnit startPosition = startOffsetForContent(region);
1083
1084     // Add in our start margin.
1085     LayoutUnit oldPosition = startPosition + childMarginStart;
1086     LayoutUnit newPosition = oldPosition;
1087
1088     LayoutUnit blockOffset = logicalTopForChild(child);
1089     if (region)
1090         blockOffset = std::max(blockOffset, blockOffset + (region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage()));
1091
1092     LayoutUnit startOff = startOffsetForLineInRegion(blockOffset, false, region, logicalHeightForChild(child));
1093
1094     if (style().textAlign() != WEBKIT_CENTER && !child.style().marginStartUsing(&style()).isAuto()) {
1095         if (childMarginStart < 0)
1096             startOff += childMarginStart;
1097         newPosition = std::max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
1098     } else if (startOff != startPosition)
1099         newPosition = startOff + childMarginStart;
1100
1101     return newPosition - oldPosition;
1102 }
1103
1104 void RenderBlock::setLogicalLeftForChild(RenderBox& child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode applyDelta)
1105 {
1106     if (isHorizontalWritingMode()) {
1107         if (applyDelta == ApplyLayoutDelta)
1108             view().addLayoutDelta(LayoutSize(child.x() - logicalLeft, 0));
1109         child.setX(logicalLeft);
1110     } else {
1111         if (applyDelta == ApplyLayoutDelta)
1112             view().addLayoutDelta(LayoutSize(0, child.y() - logicalLeft));
1113         child.setY(logicalLeft);
1114     }
1115 }
1116
1117 void RenderBlock::setLogicalTopForChild(RenderBox& child, LayoutUnit logicalTop, ApplyLayoutDeltaMode applyDelta)
1118 {
1119     if (isHorizontalWritingMode()) {
1120         if (applyDelta == ApplyLayoutDelta)
1121             view().addLayoutDelta(LayoutSize(0, child.y() - logicalTop));
1122         child.setY(logicalTop);
1123     } else {
1124         if (applyDelta == ApplyLayoutDelta)
1125             view().addLayoutDelta(LayoutSize(child.x() - logicalTop, 0));
1126         child.setX(logicalTop);
1127     }
1128 }
1129
1130 void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox& child)
1131 {
1132     // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
1133     // an auto value. Add a method to determine this, so that we can avoid the relayout.
1134     if (relayoutChildren || (child.hasRelativeLogicalHeight() && !isRenderView()))
1135         child.setChildNeedsLayout(MarkOnlyThis);
1136
1137     // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
1138     if (relayoutChildren && child.needsPreferredWidthsRecalculation())
1139         child.setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
1140 }
1141
1142 void RenderBlock::dirtyForLayoutFromPercentageHeightDescendants()
1143 {
1144     if (!gPercentHeightDescendantsMap)
1145         return;
1146
1147     TrackedRendererListHashSet* descendants = gPercentHeightDescendantsMap->get(this);
1148     if (!descendants)
1149         return;
1150
1151     for (auto it = descendants->begin(), end = descendants->end(); it != end; ++it) {
1152         RenderBox* box = *it;
1153         while (box != this) {
1154             if (box->normalChildNeedsLayout())
1155                 break;
1156             box->setChildNeedsLayout(MarkOnlyThis);
1157             
1158             // If the width of an image is affected by the height of a child (e.g., an image with an aspect ratio),
1159             // then we have to dirty preferred widths, since even enclosing blocks can become dirty as a result.
1160             // (A horizontal flexbox that contains an inline image wrapped in an anonymous block for example.)
1161             if (box->hasAspectRatio()) 
1162                 box->setPreferredLogicalWidthsDirty(true);
1163             
1164             box = box->containingBlock();
1165             ASSERT(box);
1166             if (!box)
1167                 break;
1168         }
1169     }
1170 }
1171
1172 void RenderBlock::simplifiedNormalFlowLayout()
1173 {
1174     if (childrenInline()) {
1175         ListHashSet<RootInlineBox*> lineBoxes;
1176         for (InlineWalker walker(*this); !walker.atEnd(); walker.advance()) {
1177             RenderObject& renderer = *walker.current();
1178             if (!renderer.isOutOfFlowPositioned() && (renderer.isReplaced() || renderer.isFloating())) {
1179                 RenderBox& box = downcast<RenderBox>(renderer);
1180                 box.layoutIfNeeded();
1181                 if (box.inlineBoxWrapper())
1182                     lineBoxes.add(&box.inlineBoxWrapper()->root());
1183             } else if (is<RenderText>(renderer) || (is<RenderInline>(renderer) && !walker.atEndOfInline()))
1184                 renderer.clearNeedsLayout();
1185         }
1186
1187         // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
1188         // FIXME: Find a way to invalidate the knownToHaveNoOverflow flag on the InlineBoxes.
1189         GlyphOverflowAndFallbackFontsMap textBoxDataMap;                  
1190         for (auto it = lineBoxes.begin(), end = lineBoxes.end(); it != end; ++it) {
1191             RootInlineBox* box = *it;
1192             box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
1193         }
1194     } else {
1195         for (auto box = firstChildBox(); box; box = box->nextSiblingBox()) {
1196             if (!box->isOutOfFlowPositioned())
1197                 box->layoutIfNeeded();
1198         }
1199     }
1200 }
1201
1202 bool RenderBlock::simplifiedLayout()
1203 {
1204     if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
1205         return false;
1206
1207     LayoutStateMaintainer statePusher(view(), *this, locationOffset(), hasTransform() || hasReflection() || style().isFlippedBlocksWritingMode());
1208     
1209     if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
1210         return false;
1211
1212     // Lay out positioned descendants or objects that just need to recompute overflow.
1213     if (needsSimplifiedNormalFlowLayout())
1214         simplifiedNormalFlowLayout();
1215
1216     // Make sure a forced break is applied after the content if we are a flow thread in a simplified layout.
1217     // This ensures the size information is correctly computed for the last auto-height region receiving content.
1218     if (is<RenderFlowThread>(*this))
1219         downcast<RenderFlowThread>(*this).applyBreakAfterContent(clientLogicalBottom());
1220
1221     // Lay out our positioned objects if our positioned child bit is set.
1222     // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
1223     // child, neither the fixed element nor its container learn of the movement since posChildNeedsLayout() is only marked as far as the 
1224     // relative positioned container. So if we can have fixed pos objects in our positioned objects list check if any of them
1225     // are statically positioned and thus need to move with their absolute ancestors.
1226     bool canContainFixedPosObjects = canContainFixedPositionObjects();
1227     if (posChildNeedsLayout() || canContainFixedPosObjects)
1228         layoutPositionedObjects(false, !posChildNeedsLayout() && canContainFixedPosObjects);
1229
1230     // Recompute our overflow information.
1231     // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
1232     // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
1233     // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
1234     // lowestPosition on every relayout so it's not a regression.
1235     // computeOverflow expects the bottom edge before we clamp our height. Since this information isn't available during
1236     // simplifiedLayout, we cache the value in m_overflow.
1237     LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
1238     computeOverflow(oldClientAfterEdge, true);
1239
1240     statePusher.pop();
1241     
1242     updateLayerTransform();
1243
1244     updateScrollInfoAfterLayout();
1245
1246     clearNeedsLayout();
1247     return true;
1248 }
1249
1250 void RenderBlock::markFixedPositionObjectForLayoutIfNeeded(RenderObject& child)
1251 {
1252     if (child.style().position() != FixedPosition)
1253         return;
1254
1255     bool hasStaticBlockPosition = child.style().hasStaticBlockPosition(isHorizontalWritingMode());
1256     bool hasStaticInlinePosition = child.style().hasStaticInlinePosition(isHorizontalWritingMode());
1257     if (!hasStaticBlockPosition && !hasStaticInlinePosition)
1258         return;
1259
1260     auto o = child.parent();
1261     while (o && !is<RenderView>(*o) && o->style().position() != AbsolutePosition)
1262         o = o->parent();
1263     if (o->style().position() != AbsolutePosition)
1264         return;
1265
1266     auto& box = downcast<RenderBox>(child);
1267     if (hasStaticInlinePosition) {
1268         LogicalExtentComputedValues computedValues;
1269         box.computeLogicalWidthInRegion(computedValues);
1270         LayoutUnit newLeft = computedValues.m_position;
1271         if (newLeft != box.logicalLeft())
1272             box.setChildNeedsLayout(MarkOnlyThis);
1273     } else if (hasStaticBlockPosition) {
1274         LayoutUnit oldTop = box.logicalTop();
1275         box.updateLogicalHeight();
1276         if (box.logicalTop() != oldTop)
1277             box.setChildNeedsLayout(MarkOnlyThis);
1278     }
1279 }
1280
1281 LayoutUnit RenderBlock::marginIntrinsicLogicalWidthForChild(RenderBox& child) const
1282 {
1283     // A margin has three types: fixed, percentage, and auto (variable).
1284     // Auto and percentage margins become 0 when computing min/max width.
1285     // Fixed margins can be added in as is.
1286     Length marginLeft = child.style().marginStartUsing(&style());
1287     Length marginRight = child.style().marginEndUsing(&style());
1288     LayoutUnit margin = 0;
1289     if (marginLeft.isFixed())
1290         margin += marginLeft.value();
1291     if (marginRight.isFixed())
1292         margin += marginRight.value();
1293     return margin;
1294 }
1295
1296 void RenderBlock::layoutPositionedObject(RenderBox& r, bool relayoutChildren, bool fixedPositionObjectsOnly)
1297 {
1298     estimateRegionRangeForBoxChild(r);
1299
1300     // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
1301     // 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. 
1302     // it has static position.
1303     markFixedPositionObjectForLayoutIfNeeded(r);
1304     if (fixedPositionObjectsOnly) {
1305         r.layoutIfNeeded();
1306         return;
1307     }
1308
1309     // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
1310     // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
1311     // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
1312     // positioned explicitly) this should not incur a performance penalty.
1313     if (relayoutChildren || (r.style().hasStaticBlockPosition(isHorizontalWritingMode()) && r.parent() != this))
1314         r.setChildNeedsLayout(MarkOnlyThis);
1315         
1316     // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
1317     if (relayoutChildren && r.needsPreferredWidthsRecalculation())
1318         r.setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
1319     
1320     r.markForPaginationRelayoutIfNeeded();
1321     
1322     // We don't have to do a full layout.  We just have to update our position. Try that first. If we have shrink-to-fit width
1323     // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
1324     if (r.needsPositionedMovementLayoutOnly() && r.tryLayoutDoingPositionedMovementOnly())
1325         r.clearNeedsLayout();
1326         
1327     // If we are paginated or in a line grid, compute a vertical position for our object now.
1328     // If it's wrong we'll lay out again.
1329     LayoutUnit oldLogicalTop = 0;
1330     bool needsBlockDirectionLocationSetBeforeLayout = r.needsLayout() && view().layoutState()->needsBlockDirectionLocationSetBeforeLayout();
1331     if (needsBlockDirectionLocationSetBeforeLayout) {
1332         if (isHorizontalWritingMode() == r.isHorizontalWritingMode())
1333             r.updateLogicalHeight();
1334         else
1335             r.updateLogicalWidth();
1336         oldLogicalTop = logicalTopForChild(r);
1337     }
1338
1339     r.layoutIfNeeded();
1340
1341     // Lay out again if our estimate was wrong.
1342     if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop) {
1343         r.setChildNeedsLayout(MarkOnlyThis);
1344         r.layoutIfNeeded();
1345     }
1346
1347     if (updateRegionRangeForBoxChild(r)) {
1348         r.setNeedsLayout(MarkOnlyThis);
1349         r.layoutIfNeeded();
1350     }
1351 }
1352
1353 void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly)
1354 {
1355     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
1356     if (!positionedDescendants)
1357         return;
1358     
1359     // Do not cache positionedDescendants->end() in a local variable, since |positionedDescendants| can be mutated
1360     // as it is walked. We always need to fetch the new end() value dynamically.
1361     for (auto it = positionedDescendants->begin(); it != positionedDescendants->end(); ++it)
1362         layoutPositionedObject(**it, relayoutChildren, fixedPositionObjectsOnly);
1363 }
1364
1365 void RenderBlock::markPositionedObjectsForLayout()
1366 {
1367     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
1368     if (!positionedDescendants)
1369         return;
1370
1371     for (auto it = positionedDescendants->begin(), end = positionedDescendants->end(); it != end; ++it) {
1372         RenderBox* r = *it;
1373         r->setChildNeedsLayout();
1374     }
1375 }
1376
1377 void RenderBlock::markForPaginationRelayoutIfNeeded()
1378 {
1379     if (needsLayout() || !view().layoutState()->isPaginated())
1380         return;
1381
1382     if (view().layoutState()->pageLogicalHeightChanged() || (view().layoutState()->pageLogicalHeight() && view().layoutState()->pageLogicalOffset(this, logicalTop()) != pageLogicalOffset()))
1383         setChildNeedsLayout(MarkOnlyThis);
1384 }
1385
1386 void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1387 {
1388     RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();
1389     // Check our region range to make sure we need to be painting in this region.
1390     if (namedFlowFragment && !namedFlowFragment->flowThread()->objectShouldFragmentInFlowRegion(this, namedFlowFragment))
1391         return;
1392
1393     LayoutPoint adjustedPaintOffset = paintOffset + location();
1394     PaintPhase phase = paintInfo.phase;
1395
1396     // Check if we need to do anything at all.
1397     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
1398     // paints the root's background.
1399     if (!isRoot()) {
1400         LayoutRect overflowBox = overflowRectForPaintRejection(namedFlowFragment);
1401         flipForWritingMode(overflowBox);
1402         overflowBox.inflate(maximalOutlineSize(phase));
1403         overflowBox.moveBy(adjustedPaintOffset);
1404         if (!overflowBox.intersects(paintInfo.rect)
1405 #if PLATFORM(IOS)
1406             // FIXME: This may be applicable to non-iOS ports.
1407             && (!hasLayer() || !layer()->isComposited())
1408 #endif
1409         )
1410             return;
1411     }
1412
1413     bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset);
1414     paintObject(paintInfo, adjustedPaintOffset);
1415     if (pushedClip)
1416         popContentsClip(paintInfo, phase, adjustedPaintOffset);
1417
1418     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
1419     // z-index.  We paint after we painted the background/border, so that the scrollbars will
1420     // sit above the background/border.
1421     if ((phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && hasOverflowClip() && style().visibility() == VISIBLE && paintInfo.shouldPaintWithinRoot(*this) && !paintInfo.paintRootBackgroundOnly())
1422         layer()->paintOverflowControls(paintInfo.context, roundedIntPoint(adjustedPaintOffset), snappedIntRect(paintInfo.rect));
1423 }
1424
1425 void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1426 {
1427     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
1428     // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
1429     // will do a full repaint.
1430     if (document().didLayoutWithPendingStylesheets() && !isRenderView())
1431         return;
1432
1433     if (childrenInline())
1434         paintInlineChildren(paintInfo, paintOffset);
1435     else {
1436         PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
1437         newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
1438
1439         // We don't paint our own background, but we do let the kids paint their backgrounds.
1440         PaintInfo paintInfoForChild(paintInfo);
1441         paintInfoForChild.phase = newPhase;
1442         paintInfoForChild.updateSubtreePaintRootForChildren(this);
1443
1444         // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
1445         // NSViews. Do not add any more code for this.
1446         bool usePrintRect = !view().printRect().isEmpty();
1447         paintChildren(paintInfo, paintOffset, paintInfoForChild, usePrintRect);
1448     }
1449 }
1450
1451 void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset, PaintInfo& paintInfoForChild, bool usePrintRect)
1452 {
1453     for (auto child = firstChildBox(); child; child = child->nextSiblingBox()) {
1454         if (!paintChild(*child, paintInfo, paintOffset, paintInfoForChild, usePrintRect))
1455             return;
1456     }
1457 }
1458
1459 bool RenderBlock::paintChild(RenderBox& child, PaintInfo& paintInfo, const LayoutPoint& paintOffset, PaintInfo& paintInfoForChild, bool usePrintRect, PaintBlockType paintType)
1460 {
1461     // Check for page-break-before: always, and if it's set, break and bail.
1462     bool checkBeforeAlways = !childrenInline() && (usePrintRect && child.style().pageBreakBefore() == PBALWAYS);
1463     LayoutUnit absoluteChildY = paintOffset.y() + child.y();
1464     if (checkBeforeAlways
1465         && absoluteChildY > paintInfo.rect.y()
1466         && absoluteChildY < paintInfo.rect.maxY()) {
1467         view().setBestTruncatedAt(absoluteChildY, this, true);
1468         return false;
1469     }
1470
1471     if (!child.isFloating() && child.isReplaced() && usePrintRect && child.height() <= view().printRect().height()) {
1472         // Paginate block-level replaced elements.
1473         if (absoluteChildY + child.height() > view().printRect().maxY()) {
1474             if (absoluteChildY < view().truncatedAt())
1475                 view().setBestTruncatedAt(absoluteChildY, &child);
1476             // If we were able to truncate, don't paint.
1477             if (absoluteChildY >= view().truncatedAt())
1478                 return false;
1479         }
1480     }
1481
1482     LayoutPoint childPoint = flipForWritingModeForChild(&child, paintOffset);
1483     if (!child.hasSelfPaintingLayer() && !child.isFloating()) {
1484         if (paintType == PaintAsInlineBlock)
1485             child.paintAsInlineBlock(paintInfoForChild, childPoint);
1486         else
1487             child.paint(paintInfoForChild, childPoint);
1488     }
1489
1490     // Check for page-break-after: always, and if it's set, break and bail.
1491     bool checkAfterAlways = !childrenInline() && (usePrintRect && child.style().pageBreakAfter() == PBALWAYS);
1492     if (checkAfterAlways
1493         && (absoluteChildY + child.height()) > paintInfo.rect.y()
1494         && (absoluteChildY + child.height()) < paintInfo.rect.maxY()) {
1495         view().setBestTruncatedAt(absoluteChildY + child.height() + std::max<LayoutUnit>(0, child.collapsedMarginAfter()), this, true);
1496         return false;
1497     }
1498
1499     return true;
1500 }
1501
1502 void RenderBlock::paintCaret(PaintInfo& paintInfo, const LayoutPoint& paintOffset, CaretType type)
1503 {
1504     // Paint the caret if the FrameSelection says so or if caret browsing is enabled
1505     bool caretBrowsing = frame().settings().caretBrowsingEnabled();
1506     RenderBlock* caretPainter;
1507     bool isContentEditable;
1508     if (type == CursorCaret) {
1509         caretPainter = frame().selection().caretRendererWithoutUpdatingLayout();
1510         isContentEditable = frame().selection().selection().hasEditableStyle();
1511     } else {
1512         caretPainter = frame().page()->dragCaretController().caretRenderer();
1513         isContentEditable = frame().page()->dragCaretController().isContentEditable();
1514     }
1515
1516     if (caretPainter == this && (isContentEditable || caretBrowsing)) {
1517         if (type == CursorCaret)
1518             frame().selection().paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
1519         else
1520             frame().page()->dragCaretController().paintDragCaret(&frame(), paintInfo.context, paintOffset, paintInfo.rect);
1521     }
1522 }
1523
1524 void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1525 {
1526     PaintPhase paintPhase = paintInfo.phase;
1527
1528     // 1. paint background, borders etc
1529     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style().visibility() == VISIBLE) {
1530         if (hasBoxDecorations()) {
1531             bool didClipToRegion = false;
1532             
1533             RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();
1534             if (namedFlowFragment && is<RenderNamedFlowThread>(paintInfo.paintContainer)) {
1535                 // If this box goes beyond the current region, then make sure not to overflow the region.
1536                 // This (overflowing region X altough also fragmented to region X+1) could happen when one of this box's children
1537                 // overflows region X and is an unsplittable element (like an image).
1538                 // The same applies for a box overflowing the top of region X when that box is also fragmented in region X-1.
1539
1540                 paintInfo.context->save();
1541                 didClipToRegion = true;
1542
1543                 paintInfo.context->clip(downcast<RenderNamedFlowThread>(*paintInfo.paintContainer).decorationsClipRectForBoxInNamedFlowFragment(*this, *namedFlowFragment));
1544             }
1545
1546             paintBoxDecorations(paintInfo, paintOffset);
1547             
1548             if (didClipToRegion)
1549                 paintInfo.context->restore();
1550         }
1551     }
1552
1553     if (paintPhase == PaintPhaseMask && style().visibility() == VISIBLE) {
1554         paintMask(paintInfo, paintOffset);
1555         return;
1556     }
1557
1558     if (paintPhase == PaintPhaseClippingMask && style().visibility() == VISIBLE) {
1559         paintClippingMask(paintInfo, paintOffset);
1560         return;
1561     }
1562
1563     // If just painting the root background, then return.
1564     if (paintInfo.paintRootBackgroundOnly())
1565         return;
1566
1567     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
1568     LayoutPoint scrolledOffset = paintOffset;
1569     scrolledOffset.move(-scrolledContentOffset());
1570
1571     // Column rules need to account for scrolling and clipping.
1572     // FIXME: Clipping of column rules does not work. We will need a separate paint phase for column rules I suspect in order to get
1573     // clipping correct (since it has to paint as background but is still considered "contents").
1574     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style().visibility() == VISIBLE)
1575         paintColumnRules(paintInfo, scrolledOffset);
1576
1577     // Done with backgrounds, borders and column rules.
1578     if (paintPhase == PaintPhaseBlockBackground)
1579         return;
1580     
1581     // 2. paint contents
1582     if (paintPhase != PaintPhaseSelfOutline)
1583         paintContents(paintInfo, scrolledOffset);
1584
1585     // 3. paint selection
1586     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
1587     bool isPrinting = document().printing();
1588     if (!isPrinting)
1589         paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks.
1590
1591     // 4. paint floats.
1592     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip)
1593         paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
1594
1595     // 5. paint outline.
1596     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style().visibility() == VISIBLE)
1597         paintOutline(paintInfo, LayoutRect(paintOffset, size()));
1598
1599     // 6. paint continuation outlines.
1600     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
1601         RenderInline* inlineCont = inlineElementContinuation();
1602         if (inlineCont && inlineCont->hasOutline() && inlineCont->style().visibility() == VISIBLE) {
1603             RenderInline* inlineRenderer = downcast<RenderInline>(inlineCont->element()->renderer());
1604             RenderBlock* containingBlock = this->containingBlock();
1605
1606             bool inlineEnclosedInSelfPaintingLayer = false;
1607             for (RenderBoxModelObject* box = inlineRenderer; box != containingBlock; box = &box->parent()->enclosingBoxModelObject()) {
1608                 if (box->hasSelfPaintingLayer()) {
1609                     inlineEnclosedInSelfPaintingLayer = true;
1610                     break;
1611                 }
1612             }
1613
1614             // Do not add continuations for outline painting by our containing block if we are a relative positioned
1615             // 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
1616             // in the same layer. 
1617             if (!inlineEnclosedInSelfPaintingLayer && !hasLayer())
1618                 containingBlock->addContinuationWithOutline(inlineRenderer);
1619             else if (!inlineRenderer->firstLineBox() || (!inlineEnclosedInSelfPaintingLayer && hasLayer()))
1620                 inlineRenderer->paintOutline(paintInfo, paintOffset - locationOffset() + inlineRenderer->containingBlock()->location());
1621         }
1622         paintContinuationOutlines(paintInfo, paintOffset);
1623     }
1624
1625     // 7. paint caret.
1626     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
1627     // then paint the caret.
1628     if (paintPhase == PaintPhaseForeground) {        
1629         paintCaret(paintInfo, paintOffset, CursorCaret);
1630         paintCaret(paintInfo, paintOffset, DragCaret);
1631     }
1632 }
1633
1634 RenderInline* RenderBlock::inlineElementContinuation() const
1635
1636     RenderBoxModelObject* continuation = this->continuation();
1637     return is<RenderInline>(continuation) ? downcast<RenderInline>(continuation) : nullptr;
1638 }
1639
1640 RenderBlock* RenderBlock::blockElementContinuation() const
1641 {
1642     RenderBoxModelObject* currentContinuation = continuation();
1643     if (!currentContinuation || currentContinuation->isInline())
1644         return nullptr;
1645     RenderBlock& nextContinuation = downcast<RenderBlock>(*currentContinuation);
1646     if (nextContinuation.isAnonymousBlock())
1647         return nextContinuation.blockElementContinuation();
1648     return &nextContinuation;
1649 }
1650     
1651 static ContinuationOutlineTableMap* continuationOutlineTable()
1652 {
1653     DEPRECATED_DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
1654     return &table;
1655 }
1656
1657 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
1658 {
1659     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
1660     // way of painting.
1661     ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
1662     
1663     ContinuationOutlineTableMap* table = continuationOutlineTable();
1664     ListHashSet<RenderInline*>* continuations = table->get(this);
1665     if (!continuations) {
1666         continuations = new ListHashSet<RenderInline*>;
1667         table->set(this, std::unique_ptr<ListHashSet<RenderInline*>>(continuations));
1668     }
1669     
1670     continuations->add(flow);
1671 }
1672
1673 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
1674 {
1675     ContinuationOutlineTableMap* table = continuationOutlineTable();
1676     if (table->isEmpty())
1677         return false;
1678         
1679     ListHashSet<RenderInline*>* continuations = table->get(this);
1680     if (!continuations)
1681         return false;
1682
1683     return continuations->contains(flow);
1684 }
1685
1686 void RenderBlock::paintContinuationOutlines(PaintInfo& info, const LayoutPoint& paintOffset)
1687 {
1688     ContinuationOutlineTableMap* table = continuationOutlineTable();
1689     if (table->isEmpty())
1690         return;
1691         
1692     std::unique_ptr<ListHashSet<RenderInline*>> continuations = table->take(this);
1693     if (!continuations)
1694         return;
1695
1696     LayoutPoint accumulatedPaintOffset = paintOffset;
1697     // Paint each continuation outline.
1698     ListHashSet<RenderInline*>::iterator end = continuations->end();
1699     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
1700         // Need to add in the coordinates of the intervening blocks.
1701         RenderInline* flow = *it;
1702         RenderBlock* block = flow->containingBlock();
1703         for ( ; block && block != this; block = block->containingBlock())
1704             accumulatedPaintOffset.moveBy(block->location());
1705         ASSERT(block);   
1706         flow->paintOutline(info, accumulatedPaintOffset);
1707     }
1708 }
1709
1710 bool RenderBlock::shouldPaintSelectionGaps() const
1711 {
1712     return selectionState() != SelectionNone && style().visibility() == VISIBLE && isSelectionRoot();
1713 }
1714
1715 bool RenderBlock::isSelectionRoot() const
1716 {
1717     if (isPseudoElement())
1718         return false;
1719     ASSERT(element() || isAnonymous());
1720         
1721     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
1722     if (isTable())
1723         return false;
1724         
1725     if (isBody() || isRoot() || hasOverflowClip()
1726         || isPositioned() || isFloating()
1727         || isTableCell() || isInlineBlockOrInlineTable()
1728         || hasTransform() || hasReflection() || hasMask() || isWritingModeRoot()
1729         || isRenderFlowThread() || style().columnSpan() == ColumnSpanAll)
1730         return true;
1731     
1732     if (view().selectionUnsplitStart()) {
1733         Node* startElement = view().selectionUnsplitStart()->node();
1734         if (startElement && startElement->rootEditableElement() == element())
1735             return true;
1736     }
1737     
1738     return false;
1739 }
1740
1741 GapRects RenderBlock::selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer)
1742 {
1743     ASSERT(!needsLayout());
1744
1745     if (!shouldPaintSelectionGaps())
1746         return GapRects();
1747
1748     FloatPoint containerPoint = localToContainerPoint(FloatPoint(), repaintContainer, UseTransforms);
1749     LayoutPoint offsetFromRepaintContainer(containerPoint - scrolledContentOffset());
1750
1751     LogicalSelectionOffsetCaches cache(*this);
1752     LayoutUnit lastTop = 0;
1753     LayoutUnit lastLeft = logicalLeftSelectionOffset(*this, lastTop, cache);
1754     LayoutUnit lastRight = logicalRightSelectionOffset(*this, lastTop, cache);
1755     
1756     return selectionGaps(*this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight, cache);
1757 }
1758
1759 void RenderBlock::paintSelection(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
1760 {
1761 #if ENABLE(TEXT_SELECTION)
1762     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
1763         LogicalSelectionOffsetCaches cache(*this);
1764         LayoutUnit lastTop = 0;
1765         LayoutUnit lastLeft = logicalLeftSelectionOffset(*this, lastTop, cache);
1766         LayoutUnit lastRight = logicalRightSelectionOffset(*this, lastTop, cache);
1767         GraphicsContextStateSaver stateSaver(*paintInfo.context);
1768
1769         LayoutRect gapRectsBounds = selectionGaps(*this, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight, cache, &paintInfo);
1770         if (!gapRectsBounds.isEmpty()) {
1771             if (RenderLayer* layer = enclosingLayer()) {
1772                 gapRectsBounds.moveBy(-paintOffset);
1773                 if (!hasLayer()) {
1774                     LayoutRect localBounds(gapRectsBounds);
1775                     flipForWritingMode(localBounds);
1776                     gapRectsBounds = localToContainerQuad(FloatRect(localBounds), &layer->renderer()).enclosingBoundingBox();
1777                     if (layer->renderer().isBox())
1778                         gapRectsBounds.move(layer->renderBox()->scrolledContentOffset());
1779                 }
1780                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
1781             }
1782         }
1783     }
1784 #else
1785     UNUSED_PARAM(paintInfo);
1786     UNUSED_PARAM(paintOffset);
1787 #endif
1788 }
1789
1790 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, TrackedRendererListHashSet* positionedObjects)
1791 {
1792     if (!positionedObjects)
1793         return;
1794     
1795     TrackedRendererListHashSet::const_iterator end = positionedObjects->end();
1796     for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
1797         RenderBox* r = *it;
1798         paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
1799     }
1800 }
1801
1802 LayoutUnit blockDirectionOffset(RenderBlock& rootBlock, const LayoutSize& offsetFromRootBlock)
1803 {
1804     return rootBlock.isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
1805 }
1806
1807 LayoutUnit inlineDirectionOffset(RenderBlock& rootBlock, const LayoutSize& offsetFromRootBlock)
1808 {
1809     return rootBlock.isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
1810 }
1811
1812 LayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPhysicalPosition, const LayoutRect& logicalRect)
1813 {
1814     LayoutRect result;
1815     if (isHorizontalWritingMode())
1816         result = logicalRect;
1817     else
1818         result = LayoutRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
1819     flipForWritingMode(result);
1820     result.moveBy(rootBlockPhysicalPosition);
1821     return result;
1822 }
1823
1824 GapRects RenderBlock::selectionGaps(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
1825     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
1826 {
1827     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
1828     // Clip out floating and positioned objects when painting selection gaps.
1829     if (paintInfo) {
1830         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
1831         LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
1832         rootBlock.flipForWritingMode(flippedBlockRect);
1833         flippedBlockRect.moveBy(rootBlockPhysicalPosition);
1834         clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positionedObjects());
1835         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
1836             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
1837                 clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->positionedObjects()); // FIXME: Not right for flipped writing modes.
1838         clipOutFloatingObjects(rootBlock, paintInfo, rootBlockPhysicalPosition, offsetFromRootBlock);
1839     }
1840
1841     // 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
1842     // fixed).
1843     GapRects result;
1844     if (!isRenderBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
1845         return result;
1846
1847     if (hasTransform() || style().columnSpan() == ColumnSpanAll || isInFlowRenderFlowThread()) {
1848         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
1849         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
1850         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight(), cache);
1851         lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(), cache);
1852         return result;
1853     }
1854     
1855     RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment();
1856     if (paintInfo && namedFlowFragment && is<RenderFlowThread>(*paintInfo->paintContainer)) {
1857         // Make sure the current object is actually flowed into the region being painted.
1858         if (!downcast<RenderFlowThread>(*paintInfo->paintContainer).objectShouldFragmentInFlowRegion(this, namedFlowFragment))
1859             return result;
1860     }
1861
1862     if (childrenInline())
1863         result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, cache, paintInfo);
1864     else
1865         result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, cache, paintInfo);
1866
1867     // Fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
1868     if (&rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd) && !isRubyBase() && !isRubyText()) {
1869         result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
1870             lastLogicalTop, lastLogicalLeft, lastLogicalRight, logicalHeight(), cache, paintInfo));
1871     }
1872
1873     return result;
1874 }
1875
1876 GapRects RenderBlock::inlineSelectionGaps(RenderBlock&, const LayoutPoint&, const LayoutSize&, LayoutUnit&, LayoutUnit&, LayoutUnit&, const LogicalSelectionOffsetCaches&, const PaintInfo*)
1877 {
1878     ASSERT_NOT_REACHED();
1879     return GapRects();
1880 }
1881
1882 GapRects RenderBlock::blockSelectionGaps(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
1883     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
1884 {
1885     GapRects result;
1886
1887     // Jump right to the first block child that contains some selected objects.
1888     RenderBox* curr;
1889     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
1890     
1891     if (!curr)
1892         return result;
1893
1894     LogicalSelectionOffsetCaches childCache(*this, cache);
1895
1896     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
1897         SelectionState childState = curr->selectionState();
1898         if (childState == SelectionBoth || childState == SelectionEnd)
1899             sawSelectionEnd = true;
1900
1901         if (curr->isFloatingOrOutOfFlowPositioned())
1902             continue; // We must be a normal flow object in order to even be considered.
1903
1904         if (curr->isInFlowPositioned() && curr->hasLayer()) {
1905             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
1906             // Just disregard it completely.
1907             LayoutSize relOffset = curr->layer()->offsetForInFlowPosition();
1908             if (relOffset.width() || relOffset.height())
1909                 continue;
1910         }
1911
1912         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
1913         bool fillBlockGaps = (paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone)) && !isRubyBase() && !isRubyText();
1914         if (fillBlockGaps) {
1915             // We need to fill the vertical gap above this object.
1916             if (childState == SelectionEnd || childState == SelectionInside) {
1917                 // Fill the gap above the object.
1918                 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
1919                     lastLogicalTop, lastLogicalLeft, lastLogicalRight, curr->logicalTop(), cache, paintInfo));
1920             }
1921
1922             // 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*
1923             // our object.  We know this if the selection did not end inside our object.
1924             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
1925                 childState = SelectionNone;
1926
1927             // Fill side gaps on this object based off its state.
1928             bool leftGap, rightGap;
1929             getSelectionGapInfo(childState, leftGap, rightGap);
1930
1931             if (leftGap)
1932                 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), cache, paintInfo));
1933             if (rightGap)
1934                 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), cache, paintInfo));
1935
1936             // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
1937             // they can without bumping into floating or positioned objects.  Ideally they will go right up
1938             // to the border of the root selection block.
1939             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
1940             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom(), cache);
1941             lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom(), cache);
1942         } else if (childState != SelectionNone && is<RenderBlock>(*curr)) {
1943             // We must be a block that has some selected object inside it, so recur.
1944             result.unite(downcast<RenderBlock>(*curr).selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
1945                 lastLogicalTop, lastLogicalLeft, lastLogicalRight, childCache, paintInfo));
1946         }
1947     }
1948     return result;
1949 }
1950
1951 LayoutRect RenderBlock::blockSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
1952     LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
1953 {
1954     LayoutUnit logicalTop = lastLogicalTop;
1955     LayoutUnit logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
1956     if (logicalHeight <= 0)
1957         return LayoutRect();
1958
1959     // Get the selection offsets for the bottom of the gap
1960     LayoutUnit logicalLeft = std::max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom, cache));
1961     LayoutUnit logicalRight = std::min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom, cache));
1962     LayoutUnit logicalWidth = logicalRight - logicalLeft;
1963     if (logicalWidth <= 0)
1964         return LayoutRect();
1965
1966     LayoutRect gapRect = rootBlock.logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
1967     if (paintInfo)
1968         paintInfo->context->fillRect(snapRectToDevicePixels(gapRect, document().deviceScaleFactor()), selectionBackgroundColor(), style().colorSpace());
1969     return gapRect;
1970 }
1971
1972 LayoutRect RenderBlock::logicalLeftSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
1973     RenderBoxModelObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
1974 {
1975     LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
1976     LayoutUnit rootBlockLogicalLeft = std::max(logicalLeftSelectionOffset(rootBlock, logicalTop, cache), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight, cache));
1977     LayoutUnit rootBlockLogicalRight = std::min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft,
1978         std::min(logicalRightSelectionOffset(rootBlock, logicalTop, cache), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight, cache)));
1979     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
1980     if (rootBlockLogicalWidth <= 0)
1981         return LayoutRect();
1982
1983     LayoutRect gapRect = rootBlock.logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
1984     if (paintInfo)
1985         paintInfo->context->fillRect(snapRectToDevicePixels(gapRect, document().deviceScaleFactor()), selObj->selectionBackgroundColor(), selObj->style().colorSpace());
1986     return gapRect;
1987 }
1988
1989 LayoutRect RenderBlock::logicalRightSelectionGap(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
1990     RenderBoxModelObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
1991 {
1992     LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
1993     LayoutUnit rootBlockLogicalLeft = std::max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight,
1994         std::max(logicalLeftSelectionOffset(rootBlock, logicalTop, cache), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight, cache)));
1995     LayoutUnit rootBlockLogicalRight = std::min(logicalRightSelectionOffset(rootBlock, logicalTop, cache), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight, cache));
1996     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
1997     if (rootBlockLogicalWidth <= 0)
1998         return LayoutRect();
1999
2000     LayoutRect gapRect = rootBlock.logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
2001     if (paintInfo)
2002         paintInfo->context->fillRect(snapRectToDevicePixels(gapRect, document().deviceScaleFactor()), selObj->selectionBackgroundColor(), selObj->style().colorSpace());
2003     return gapRect;
2004 }
2005
2006 void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
2007 {
2008     bool ltr = style().isLeftToRightDirection();
2009     leftGap = (state == RenderObject::SelectionInside) ||
2010               (state == RenderObject::SelectionEnd && ltr) ||
2011               (state == RenderObject::SelectionStart && !ltr);
2012     rightGap = (state == RenderObject::SelectionInside) ||
2013                (state == RenderObject::SelectionStart && ltr) ||
2014                (state == RenderObject::SelectionEnd && !ltr);
2015 }
2016
2017 LayoutUnit RenderBlock::logicalLeftSelectionOffset(RenderBlock& rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches& cache)
2018 {
2019     LayoutUnit logicalLeft = logicalLeftOffsetForLine(position, false);
2020     if (logicalLeft == logicalLeftOffsetForContent()) {
2021         if (&rootBlock != this) // The border can potentially be further extended by our containingBlock().
2022             return cache.containingBlockInfo(*this).logicalLeftSelectionOffset(rootBlock, position + logicalTop());
2023         return logicalLeft;
2024     }
2025
2026     RenderBlock* cb = this;
2027     const LogicalSelectionOffsetCaches* currentCache = &cache;
2028     while (cb != &rootBlock) {
2029         logicalLeft += cb->logicalLeft();
2030
2031         ASSERT(currentCache);
2032         auto info = currentCache->containingBlockInfo(*cb);
2033         cb = info.block();
2034         currentCache = info.cache();
2035     }
2036     return logicalLeft;
2037 }
2038
2039 LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock& rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches& cache)
2040 {
2041     LayoutUnit logicalRight = logicalRightOffsetForLine(position, false);
2042     if (logicalRight == logicalRightOffsetForContent()) {
2043         if (&rootBlock != this) // The border can potentially be further extended by our containingBlock().
2044             return cache.containingBlockInfo(*this).logicalRightSelectionOffset(rootBlock, position + logicalTop());
2045         return logicalRight;
2046     }
2047
2048     RenderBlock* cb = this;
2049     const LogicalSelectionOffsetCaches* currentCache = &cache;
2050     while (cb != &rootBlock) {
2051         logicalRight += cb->logicalLeft();
2052
2053         ASSERT(currentCache);
2054         auto info = currentCache->containingBlockInfo(*cb);
2055         cb = info.block();
2056         currentCache = info.cache();
2057     }
2058     return logicalRight;
2059 }
2060
2061 RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
2062 {
2063     if (isSelectionRoot())
2064         return nullptr;
2065
2066     const RenderElement* object = this;
2067     RenderObject* sibling;
2068     do {
2069         sibling = object->previousSibling();
2070         while (sibling && (!is<RenderBlock>(*sibling) || downcast<RenderBlock>(*sibling).isSelectionRoot()))
2071             sibling = sibling->previousSibling();
2072
2073         offset -= LayoutSize(downcast<RenderBlock>(*object).logicalLeft(), downcast<RenderBlock>(*object).logicalTop());
2074         object = object->parent();
2075     } while (!sibling && is<RenderBlock>(object) && !downcast<RenderBlock>(*object).isSelectionRoot());
2076
2077     if (!sibling)
2078         return nullptr;
2079
2080     RenderBlock* beforeBlock = downcast<RenderBlock>(sibling);
2081
2082     offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
2083
2084     RenderObject* child = beforeBlock->lastChild();
2085     while (is<RenderBlock>(child)) {
2086         beforeBlock = downcast<RenderBlock>(child);
2087         offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
2088         child = beforeBlock->lastChild();
2089     }
2090     return beforeBlock;
2091 }
2092
2093 void RenderBlock::insertIntoTrackedRendererMaps(RenderBox& descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap, bool forceNewEntry)
2094 {
2095     if (!descendantsMap) {
2096         descendantsMap = new TrackedDescendantsMap;
2097         containerMap = new TrackedContainerMap;
2098     }
2099     
2100     TrackedRendererListHashSet* descendantSet = descendantsMap->get(this);
2101     if (!descendantSet) {
2102         descendantSet = new TrackedRendererListHashSet;
2103         descendantsMap->set(this, std::unique_ptr<TrackedRendererListHashSet>(descendantSet));
2104     }
2105     
2106     if (forceNewEntry) {
2107         descendantSet->remove(&descendant);
2108         containerMap->remove(&descendant);
2109     }
2110     
2111     bool added = descendantSet->add(&descendant).isNewEntry;
2112     if (!added) {
2113         ASSERT(containerMap->get(&descendant));
2114         ASSERT(containerMap->get(&descendant)->contains(this));
2115         return;
2116     }
2117     
2118     HashSet<RenderBlock*>* containerSet = containerMap->get(&descendant);
2119     if (!containerSet) {
2120         containerSet = new HashSet<RenderBlock*>;
2121         containerMap->set(&descendant, std::unique_ptr<HashSet<RenderBlock*>>(containerSet));
2122     }    
2123     ASSERT(!containerSet->contains(this));
2124     containerSet->add(this);
2125 }
2126
2127 void RenderBlock::removeFromTrackedRendererMaps(RenderBox& descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
2128 {
2129     if (!descendantsMap)
2130         return;
2131     
2132     std::unique_ptr<HashSet<RenderBlock*>> containerSet = containerMap->take(&descendant);
2133     if (!containerSet)
2134         return;
2135     
2136     for (auto it = containerSet->begin(), end = containerSet->end(); it != end; ++it) {
2137         RenderBlock* container = *it;
2138
2139         // FIXME: Disabling this assert temporarily until we fix the layout
2140         // bugs associated with positioned objects not properly cleared from
2141         // their ancestor chain before being moved. See webkit bug 93766.
2142         // ASSERT(descendant->isDescendantOf(container));
2143
2144         TrackedDescendantsMap::iterator descendantsMapIterator = descendantsMap->find(container);
2145         ASSERT(descendantsMapIterator != descendantsMap->end());
2146         if (descendantsMapIterator == descendantsMap->end())
2147             continue;
2148         TrackedRendererListHashSet* descendantSet = descendantsMapIterator->value.get();
2149         ASSERT(descendantSet->contains(&descendant));
2150         descendantSet->remove(&descendant);
2151         if (descendantSet->isEmpty())
2152             descendantsMap->remove(descendantsMapIterator);
2153     }
2154 }
2155
2156 TrackedRendererListHashSet* RenderBlock::positionedObjects() const
2157 {
2158     if (gPositionedDescendantsMap)
2159         return gPositionedDescendantsMap->get(this);
2160     return nullptr;
2161 }
2162
2163 void RenderBlock::insertPositionedObject(RenderBox& o)
2164 {
2165     ASSERT(!isAnonymousBlock());
2166
2167     if (o.isRenderFlowThread())
2168         return;
2169     
2170     insertIntoTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap, isRenderView());
2171 }
2172
2173 void RenderBlock::removePositionedObject(RenderBox& o)
2174 {
2175     removeFromTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
2176 }
2177
2178 void RenderBlock::removePositionedObjects(RenderBlock* o, ContainingBlockState containingBlockState)
2179 {
2180     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
2181     if (!positionedDescendants)
2182         return;
2183     
2184     Vector<RenderBox*, 16> deadObjects;
2185
2186     for (auto it = positionedDescendants->begin(), end = positionedDescendants->end(); it != end; ++it) {
2187         RenderBox* r = *it;
2188         if (!o || r->isDescendantOf(o)) {
2189             if (containingBlockState == NewContainingBlock)
2190                 r->setChildNeedsLayout(MarkOnlyThis);
2191             
2192             // It is parent blocks job to add positioned child to positioned objects list of its containing block
2193             // Parent layout needs to be invalidated to ensure this happens.
2194             RenderElement* p = r->parent();
2195             while (p && !p->isRenderBlock())
2196                 p = p->parent();
2197             if (p)
2198                 p->setChildNeedsLayout();
2199             
2200             deadObjects.append(r);
2201         }
2202     }
2203     
2204     for (unsigned i = 0; i < deadObjects.size(); i++)
2205         removePositionedObject(*deadObjects.at(i));
2206 }
2207
2208 void RenderBlock::addPercentHeightDescendant(RenderBox& descendant)
2209 {
2210     insertIntoTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
2211 }
2212
2213 void RenderBlock::removePercentHeightDescendant(RenderBox& descendant)
2214 {
2215     removeFromTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
2216 }
2217
2218 TrackedRendererListHashSet* RenderBlock::percentHeightDescendants() const
2219 {
2220     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
2221 }
2222
2223 bool RenderBlock::hasPercentHeightContainerMap()
2224 {
2225     return gPercentHeightContainerMap;
2226 }
2227
2228 bool RenderBlock::hasPercentHeightDescendant(RenderBox& descendant)
2229 {
2230     // We don't null check gPercentHeightContainerMap since the caller
2231     // already ensures this and we need to call this function on every
2232     // descendant in clearPercentHeightDescendantsFrom().
2233     ASSERT(gPercentHeightContainerMap);
2234     return gPercentHeightContainerMap->contains(&descendant);
2235 }
2236
2237 void RenderBlock::removePercentHeightDescendantIfNeeded(RenderBox& descendant)
2238 {
2239     // We query the map directly, rather than looking at style's
2240     // logicalHeight()/logicalMinHeight()/logicalMaxHeight() since those
2241     // can change with writing mode/directional changes.
2242     if (!hasPercentHeightContainerMap())
2243         return;
2244
2245     if (!hasPercentHeightDescendant(descendant))
2246         return;
2247
2248     removePercentHeightDescendant(descendant);
2249 }
2250
2251 void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox& parent)
2252 {
2253     ASSERT(gPercentHeightContainerMap);
2254     for (RenderObject* child = parent.firstChild(); child; child = child->nextInPreOrder(&parent)) {
2255         if (!is<RenderBox>(*child))
2256             continue;
2257  
2258         auto& box = downcast<RenderBox>(*child);
2259         if (!hasPercentHeightDescendant(box))
2260             continue;
2261
2262         removePercentHeightDescendant(box);
2263     }
2264 }
2265
2266 LayoutUnit RenderBlock::textIndentOffset() const
2267 {
2268     LayoutUnit cw = 0;
2269     if (style().textIndent().isPercentOrCalculated())
2270         cw = containingBlock()->availableLogicalWidth();
2271     return minimumValueForLength(style().textIndent(), cw);
2272 }
2273
2274 LayoutUnit RenderBlock::logicalLeftOffsetForContent(RenderRegion* region) const
2275 {
2276     LayoutUnit logicalLeftOffset = style().isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
2277     if (!region)
2278         return logicalLeftOffset;
2279     LayoutRect boxRect = borderBoxRectInRegion(region);
2280     return logicalLeftOffset + (isHorizontalWritingMode() ? boxRect.x() : boxRect.y());
2281 }
2282
2283 LayoutUnit RenderBlock::logicalRightOffsetForContent(RenderRegion* region) const
2284 {
2285     LayoutUnit logicalRightOffset = style().isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
2286     logicalRightOffset += availableLogicalWidth();
2287     if (!region)
2288         return logicalRightOffset;
2289     LayoutRect boxRect = borderBoxRectInRegion(region);
2290     return logicalRightOffset - (logicalWidth() - (isHorizontalWritingMode() ? boxRect.maxX() : boxRect.maxY()));
2291 }
2292
2293 LayoutUnit RenderBlock::adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
2294 {
2295     LayoutUnit left = offsetFromFloats;
2296
2297     if (applyTextIndent && style().isLeftToRightDirection())
2298         left += textIndentOffset();
2299
2300     if (style().lineAlign() == LineAlignNone)
2301         return left;
2302     
2303     // Push in our left offset so that it is aligned with the character grid.
2304     LayoutState* layoutState = view().layoutState();
2305     if (!layoutState)
2306         return left;
2307
2308     RenderBlock* lineGrid = layoutState->lineGrid();
2309     if (!lineGrid || lineGrid->style().writingMode() != style().writingMode())
2310         return left;
2311
2312     // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge?
2313     float maxCharWidth = lineGrid->style().fontCascade().primaryFont().maxCharWidth();
2314     if (!maxCharWidth)
2315         return left;
2316
2317     LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height();
2318     LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height();
2319     
2320     // Push in to the nearest character width (truncated so that we pixel snap left).
2321     // FIXME: Should be patched when subpixel layout lands, since this calculation doesn't have to pixel snap
2322     // any more (https://bugs.webkit.org/show_bug.cgi?id=79946).
2323     // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945).
2324     // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942).
2325     // FIXME: This doesn't work when the inline position of the object isn't set ahead of time.
2326     // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout.
2327     // (https://bugs.webkit.org/show_bug.cgi?id=79944)
2328     float remainder = fmodf(maxCharWidth - fmodf(left + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth);
2329     left += remainder;
2330     return left;
2331 }
2332
2333 LayoutUnit RenderBlock::adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
2334 {
2335     LayoutUnit right = offsetFromFloats;
2336     
2337     if (applyTextIndent && !style().isLeftToRightDirection())
2338         right -= textIndentOffset();
2339     
2340     if (style().lineAlign() == LineAlignNone)
2341         return right;
2342     
2343     // Push in our right offset so that it is aligned with the character grid.
2344     LayoutState* layoutState = view().layoutState();
2345     if (!layoutState)
2346         return right;
2347
2348     RenderBlock* lineGrid = layoutState->lineGrid();
2349     if (!lineGrid || lineGrid->style().writingMode() != style().writingMode())
2350         return right;
2351
2352     // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge?
2353     float maxCharWidth = lineGrid->style().fontCascade().primaryFont().maxCharWidth();
2354     if (!maxCharWidth)
2355         return right;
2356
2357     LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height();
2358     LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height();
2359     
2360     // Push in to the nearest character width (truncated so that we pixel snap right).
2361     // FIXME: Should be patched when subpixel layout lands, since this calculation doesn't have to pixel snap
2362     // any more (https://bugs.webkit.org/show_bug.cgi?id=79946).
2363     // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945).
2364     // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942).
2365     // FIXME: This doesn't work when the inline position of the object isn't set ahead of time.
2366     // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout.
2367     // (https://bugs.webkit.org/show_bug.cgi?id=79944)
2368     float remainder = fmodf(fmodf(right + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth);
2369     right -= ceilf(remainder);
2370     return right;
2371 }
2372
2373 bool RenderBlock::avoidsFloats() const
2374 {
2375     // Floats can't intrude into our box if we have a non-auto column count or width.
2376     return RenderBox::avoidsFloats() || style().hasFlowFrom();
2377 }
2378
2379 bool RenderBlock::isPointInOverflowControl(HitTestResult& result, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset)
2380 {
2381     if (!scrollsOverflow())
2382         return false;
2383
2384     return layer()->hitTestOverflowControls(result, roundedIntPoint(locationInContainer - toLayoutSize(accumulatedOffset)));
2385 }
2386
2387 Node* RenderBlock::nodeForHitTest() const
2388 {
2389     // If we are in the margins of block elements that are part of a
2390     // continuation we're actually still inside the enclosing element
2391     // that was split. Use the appropriate inner node.
2392     if (isRenderView())
2393         return &document();
2394     return isAnonymousBlockContinuation() ? continuation()->element() : element();
2395 }
2396
2397 bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
2398 {
2399     LayoutPoint adjustedLocation(accumulatedOffset + location());
2400     LayoutSize localOffset = toLayoutSize(adjustedLocation);
2401
2402     RenderFlowThread* flowThread = flowThreadContainingBlock();
2403     RenderNamedFlowFragment* namedFlowFragment = flowThread ? downcast<RenderNamedFlowFragment>(flowThread->currentRegion()) : nullptr;
2404     // If we are now searching inside a region, make sure this element
2405     // is being fragmented into this region.
2406     if (namedFlowFragment && !flowThread->objectShouldFragmentInFlowRegion(this, namedFlowFragment))
2407         return false;
2408
2409     if (!isRenderView()) {
2410         // Check if we need to do anything at all.
2411         LayoutRect overflowBox = visualOverflowRect();
2412         flipForWritingMode(overflowBox);
2413         overflowBox.moveBy(adjustedLocation);
2414         if (!locationInContainer.intersects(overflowBox))
2415             return false;
2416     }
2417
2418     if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, locationInContainer.point(), adjustedLocation)) {
2419         updateHitTestResult(result, locationInContainer.point() - localOffset);
2420         // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
2421         if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer))
2422            return true;
2423     }
2424
2425     if (style().clipPath()) {
2426         switch (style().clipPath()->type()) {
2427         case ClipPathOperation::Shape: {
2428             auto& clipPath = downcast<ShapeClipPathOperation>(*style().clipPath());
2429
2430             LayoutRect referenceBoxRect;
2431             switch (clipPath.referenceBox()) {
2432             case CSSBoxType::MarginBox:
2433                 referenceBoxRect = marginBoxRect();
2434                 break;
2435             case CSSBoxType::BorderBox:
2436                 referenceBoxRect = borderBoxRect();
2437                 break;
2438             case CSSBoxType::PaddingBox:
2439                 referenceBoxRect = paddingBoxRect();
2440                 break;
2441             case CSSBoxType::ContentBox:
2442                 referenceBoxRect = contentBoxRect();
2443                 break;
2444             case CSSBoxType::BoxMissing:
2445             case CSSBoxType::Fill:
2446             case CSSBoxType::Stroke:
2447             case CSSBoxType::ViewBox:
2448                 referenceBoxRect = borderBoxRect();
2449             }
2450             if (!clipPath.pathForReferenceRect(referenceBoxRect).contains(locationInContainer.point() - localOffset, clipPath.windRule()))
2451                 return false;
2452             break;
2453         }
2454         // FIXME: handle Reference/Box
2455         case ClipPathOperation::Reference:
2456         case ClipPathOperation::Box:
2457             break;
2458         }
2459     }
2460
2461     // If we have clipping, then we can't have any spillout.
2462     bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
2463     bool useClip = (hasControlClip() || useOverflowClip);
2464     bool checkChildren = !useClip || (hasControlClip() ? locationInContainer.intersects(controlClipRect(adjustedLocation)) : locationInContainer.intersects(overflowClipRect(adjustedLocation, namedFlowFragment, IncludeOverlayScrollbarSize)));
2465     if (checkChildren) {
2466         // Hit test descendants first.
2467         LayoutSize scrolledOffset(localOffset - scrolledContentOffset());
2468
2469         if (hitTestContents(request, result, locationInContainer, toLayoutPoint(scrolledOffset), hitTestAction)) {
2470             updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
2471             return true;
2472         }
2473         if (hitTestAction == HitTestFloat && hitTestFloats(request, result, locationInContainer, toLayoutPoint(scrolledOffset)))
2474             return true;
2475     }
2476
2477     // Check if the point is outside radii.
2478     if (!isRenderView() && style().hasBorderRadius()) {
2479         LayoutRect borderRect = borderBoxRect();
2480         borderRect.moveBy(adjustedLocation);
2481         RoundedRect border = style().getRoundedBorderFor(borderRect);
2482         if (!locationInContainer.intersects(border))
2483             return false;
2484     }
2485
2486     // Now hit test our background
2487     if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
2488         LayoutRect boundsRect(adjustedLocation, size());
2489         if (visibleToHitTesting() && locationInContainer.intersects(boundsRect)) {
2490             updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
2491             if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer, boundsRect))
2492                 return true;
2493         }
2494     }
2495
2496     return false;
2497 }
2498
2499 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
2500 {
2501     if (childrenInline() && !isTable())
2502         return hitTestInlineChildren(request, result, locationInContainer, accumulatedOffset, hitTestAction);
2503
2504     // Hit test our children.
2505     HitTestAction childHitTest = hitTestAction;
2506     if (hitTestAction == HitTestChildBlockBackgrounds)
2507         childHitTest = HitTestChildBlockBackground;
2508     for (auto child = lastChildBox(); child; child = child->previousSiblingBox()) {
2509         LayoutPoint childPoint = flipForWritingModeForChild(child, accumulatedOffset);
2510         if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, locationInContainer, childPoint, childHitTest))
2511             return true;
2512     }
2513
2514     return false;
2515 }
2516
2517 static inline bool isEditingBoundary(RenderElement* ancestor, RenderObject& child)
2518 {
2519     ASSERT(!ancestor || ancestor->nonPseudoElement());
2520     ASSERT(child.nonPseudoNode());
2521     return !ancestor || !ancestor->parent() || (ancestor->hasLayer() && ancestor->parent()->isRenderView())
2522         || ancestor->nonPseudoElement()->hasEditableStyle() == child.nonPseudoNode()->hasEditableStyle();
2523 }
2524
2525 // FIXME: This function should go on RenderObject as an instance method. Then
2526 // all cases in which positionForPoint recurs could call this instead to
2527 // prevent crossing editable boundaries. This would require many tests.
2528 VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock& parent, RenderBox& child, const LayoutPoint& pointInParentCoordinates)
2529 {
2530     LayoutPoint childLocation = child.location();
2531     if (child.isInFlowPositioned())
2532         childLocation += child.offsetForInFlowPosition();
2533
2534     // FIXME: This is wrong if the child's writing-mode is different from the parent's.
2535     LayoutPoint pointInChildCoordinates(toLayoutPoint(pointInParentCoordinates - childLocation));
2536
2537     // If this is an anonymous renderer, we just recur normally
2538     Element* childElement= child.nonPseudoElement();
2539     if (!childElement)
2540         return child.positionForPoint(pointInChildCoordinates, nullptr);
2541
2542     // Otherwise, first make sure that the editability of the parent and child agree.
2543     // If they don't agree, then we return a visible position just before or after the child
2544     RenderElement* ancestor = &parent;
2545     while (ancestor && !ancestor->nonPseudoElement())
2546         ancestor = ancestor->parent();
2547
2548     // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
2549     if (isEditingBoundary(ancestor, child))
2550         return child.positionForPoint(pointInChildCoordinates, nullptr);
2551     
2552 #if PLATFORM(IOS)
2553     // On iOS we want to constrain VisiblePositions to the editable region closest to the input position, so
2554     // we will allow descent from non-editable to editable content.
2555     // FIXME: This constraining must be done at a higher level once we implement contentEditable. For now, if something
2556     // is editable, the whole document will be.
2557     if (childElement->isContentEditable() && !ancestor->element()->isContentEditable())
2558         return child.positionForPoint(pointInChildCoordinates, nullptr);
2559 #endif
2560
2561     // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
2562     LayoutUnit childMiddle = parent.logicalWidthForChild(child) / 2;
2563     LayoutUnit logicalLeft = parent.isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
2564     if (logicalLeft < childMiddle)
2565         return ancestor->createVisiblePosition(childElement->computeNodeIndex(), DOWNSTREAM);
2566     return ancestor->createVisiblePosition(childElement->computeNodeIndex() + 1, UPSTREAM);
2567 }
2568
2569 VisiblePosition RenderBlock::positionForPointWithInlineChildren(const LayoutPoint&, const RenderRegion*)
2570 {
2571     ASSERT_NOT_REACHED();
2572     return VisiblePosition();
2573 }
2574
2575 static inline bool isChildHitTestCandidate(const RenderBox& box)
2576 {
2577     return box.height() && box.style().visibility() == VISIBLE && !box.isFloatingOrOutOfFlowPositioned() && !box.isInFlowRenderFlowThread();
2578 }
2579
2580 // Valid candidates in a FlowThread must be rendered by the region.
2581 static inline bool isChildHitTestCandidate(const RenderBox& box, const RenderRegion* region, const LayoutPoint& point)
2582 {
2583     if (!isChildHitTestCandidate(box))
2584         return false;
2585     if (!region)
2586         return true;
2587     const RenderBlock& block = is<RenderBlock>(box) ? downcast<RenderBlock>(box) : *box.containingBlock();
2588     return block.regionAtBlockOffset(point.y()) == region;
2589 }
2590
2591 VisiblePosition RenderBlock::positionForPoint(const LayoutPoint& point, const RenderRegion* region)
2592 {
2593     if (isTable())
2594         return RenderBox::positionForPoint(point, region);
2595
2596     if (isReplaced()) {
2597         // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
2598         LayoutUnit pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
2599         LayoutUnit pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
2600
2601         if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
2602             return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
2603         if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth()))
2604             return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
2605     } 
2606
2607     LayoutPoint pointInContents = point;
2608     offsetForContents(pointInContents);
2609     LayoutPoint pointInLogicalContents(pointInContents);
2610     if (!isHorizontalWritingMode())
2611         pointInLogicalContents = pointInLogicalContents.transposedPoint();
2612
2613     if (childrenInline())
2614         return positionForPointWithInlineChildren(pointInLogicalContents, region);
2615
2616     RenderBox* lastCandidateBox = lastChildBox();
2617
2618     if (!region)
2619         region = regionAtBlockOffset(pointInLogicalContents.y());
2620
2621     while (lastCandidateBox && !isChildHitTestCandidate(*lastCandidateBox, region, pointInLogicalContents))
2622         lastCandidateBox = lastCandidateBox->previousSiblingBox();
2623
2624     bool blocksAreFlipped = style().isFlippedBlocksWritingMode();
2625     if (lastCandidateBox) {
2626         if (pointInLogicalContents.y() > logicalTopForChild(*lastCandidateBox)
2627             || (!blocksAreFlipped && pointInLogicalContents.y() == logicalTopForChild(*lastCandidateBox)))
2628             return positionForPointRespectingEditingBoundaries(*this, *lastCandidateBox, pointInContents);
2629
2630         for (auto childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
2631             if (!isChildHitTestCandidate(*childBox, region, pointInLogicalContents))
2632                 continue;
2633             LayoutUnit childLogicalBottom = logicalTopForChild(*childBox) + logicalHeightForChild(*childBox);
2634             // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
2635             if (isChildHitTestCandidate(*childBox, region, pointInLogicalContents) && (pointInLogicalContents.y() < childLogicalBottom
2636                 || (blocksAreFlipped && pointInLogicalContents.y() == childLogicalBottom)))
2637                 return positionForPointRespectingEditingBoundaries(*this, *childBox, pointInContents);
2638         }
2639     }
2640
2641     // We only get here if there are no hit test candidate children below the click.
2642     return RenderBox::positionForPoint(point, region);
2643 }
2644
2645 void RenderBlock::offsetForContents(LayoutPoint& offset) const
2646 {
2647     offset = flipForWritingMode(offset);
2648     offset += scrolledContentOffset();
2649     offset = flipForWritingMode(offset);
2650 }
2651
2652 void RenderBlock::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
2653 {
2654     ASSERT(!childrenInline());
2655     
2656     computeBlockPreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
2657
2658     maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth);
2659
2660     int scrollbarWidth = intrinsicScrollbarLogicalWidth();
2661     maxLogicalWidth += scrollbarWidth;
2662     minLogicalWidth += scrollbarWidth;
2663 }
2664
2665 void RenderBlock::computePreferredLogicalWidths()
2666 {
2667     ASSERT(preferredLogicalWidthsDirty());
2668
2669     updateFirstLetter();
2670
2671     m_minPreferredLogicalWidth = 0;
2672     m_maxPreferredLogicalWidth = 0;
2673
2674     const RenderStyle& styleToUse = style();
2675     if (!isTableCell() && styleToUse.logicalWidth().isFixed() && styleToUse.logicalWidth().value() >= 0
2676         && !(isDeprecatedFlexItem() && !styleToUse.logicalWidth().intValue()))
2677         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalWidth().value());
2678     else
2679         computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
2680     
2681     if (styleToUse.logicalMinWidth().isFixed() && styleToUse.logicalMinWidth().value() > 0) {
2682         m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
2683         m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMinWidth().value()));
2684     }
2685     
2686     if (styleToUse.logicalMaxWidth().isFixed()) {
2687         m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
2688         m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.logicalMaxWidth().value()));
2689     }
2690     
2691     // Table layout uses integers, ceil the preferred widths to ensure that they can contain the contents.
2692     if (isTableCell()) {
2693         m_minPreferredLogicalWidth = m_minPreferredLogicalWidth.ceil();
2694         m_maxPreferredLogicalWidth = m_maxPreferredLogicalWidth.ceil();
2695     }
2696
2697     LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
2698     m_minPreferredLogicalWidth += borderAndPadding;
2699     m_maxPreferredLogicalWidth += borderAndPadding;
2700
2701     setPreferredLogicalWidthsDirty(false);
2702 }
2703
2704 void RenderBlock::computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
2705 {
2706     const RenderStyle& styleToUse = style();
2707     bool nowrap = styleToUse.whiteSpace() == NOWRAP;
2708
2709     RenderObject* child = firstChild();
2710     RenderBlock* containingBlock = this->containingBlock();
2711     LayoutUnit floatLeftWidth = 0, floatRightWidth = 0;
2712     while (child) {
2713         // Positioned children don't affect the min/max width
2714         if (child->isOutOfFlowPositioned()) {
2715             child = child->nextSibling();
2716             continue;
2717         }
2718
2719         const RenderStyle& childStyle = child->style();
2720         if (child->isFloating() || (is<RenderBox>(*child) && downcast<RenderBox>(*child).avoidsFloats())) {
2721             LayoutUnit floatTotalWidth = floatLeftWidth + floatRightWidth;
2722             if (childStyle.clear() & CLEFT) {
2723                 maxLogicalWidth = std::max(floatTotalWidth, maxLogicalWidth);
2724                 floatLeftWidth = 0;
2725             }
2726             if (childStyle.clear() & CRIGHT) {
2727                 maxLogicalWidth = std::max(floatTotalWidth, maxLogicalWidth);
2728                 floatRightWidth = 0;
2729             }
2730         }
2731
2732         // A margin basically has three types: fixed, percentage, and auto (variable).
2733         // Auto and percentage margins simply become 0 when computing min/max width.
2734         // Fixed margins can be added in as is.
2735         Length startMarginLength = childStyle.marginStartUsing(&styleToUse);
2736         Length endMarginLength = childStyle.marginEndUsing(&styleToUse);
2737         LayoutUnit margin = 0;
2738         LayoutUnit marginStart = 0;
2739         LayoutUnit marginEnd = 0;
2740         if (startMarginLength.isFixed())
2741             marginStart += startMarginLength.value();
2742         if (endMarginLength.isFixed())
2743             marginEnd += endMarginLength.value();
2744         margin = marginStart + marginEnd;
2745
2746         LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
2747         if (is<RenderBox>(*child) && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
2748             auto& childBox = downcast<RenderBox>(*child);
2749             LogicalExtentComputedValues computedValues;
2750             childBox.computeLogicalHeight(childBox.borderAndPaddingLogicalHeight(), 0, computedValues);
2751             childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
2752         } else {
2753             childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
2754             childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
2755         }
2756
2757         LayoutUnit w = childMinPreferredLogicalWidth + margin;
2758         minLogicalWidth = std::max(w, minLogicalWidth);
2759         
2760         // IE ignores tables for calculation of nowrap. Makes some sense.
2761         if (nowrap && !child->isTable())
2762             maxLogicalWidth = std::max(w, maxLogicalWidth);
2763
2764         w = childMaxPreferredLogicalWidth + margin;
2765
2766         if (!child->isFloating()) {
2767             if (is<RenderBox>(*child) && downcast<RenderBox>(*child).avoidsFloats()) {
2768                 // Determine a left and right max value based off whether or not the floats can fit in the
2769                 // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
2770                 // is smaller than the float width.
2771                 bool ltr = containingBlock ? containingBlock->style().isLeftToRightDirection() : styleToUse.isLeftToRightDirection();
2772                 LayoutUnit marginLogicalLeft = ltr ? marginStart : marginEnd;
2773                 LayoutUnit marginLogicalRight = ltr ? marginEnd : marginStart;
2774                 LayoutUnit maxLeft = marginLogicalLeft > 0 ? std::max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
2775                 LayoutUnit maxRight = marginLogicalRight > 0 ? std::max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
2776                 w = childMaxPreferredLogicalWidth + maxLeft + maxRight;
2777                 w = std::max(w, floatLeftWidth + floatRightWidth);
2778             }
2779             else
2780                 maxLogicalWidth = std::max(floatLeftWidth + floatRightWidth, maxLogicalWidth);
2781             floatLeftWidth = floatRightWidth = 0;
2782         }
2783         
2784         if (child->isFloating()) {
2785             if (childStyle.floating() == LeftFloat)
2786                 floatLeftWidth += w;
2787             else
2788                 floatRightWidth += w;
2789         } else
2790             maxLogicalWidth = std::max(w, maxLogicalWidth);
2791         
2792         child = child->nextSibling();
2793     }
2794
2795     // Always make sure these values are non-negative.
2796     minLogicalWidth = std::max<LayoutUnit>(0, minLogicalWidth);
2797     maxLogicalWidth = std::max<LayoutUnit>(0, maxLogicalWidth);
2798
2799     maxLogicalWidth = std::max(floatLeftWidth + floatRightWidth, maxLogicalWidth);
2800 }
2801
2802 bool RenderBlock::hasLineIfEmpty() const
2803 {
2804     if (!element())
2805         return false;
2806     
2807     if (element()->isRootEditableElement())
2808         return true;
2809     
2810     return false;
2811 }
2812
2813 LayoutUnit RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
2814 {
2815     // Anonymous inline blocks don't include margins or any real line height.
2816     if (isAnonymousInlineBlock() && linePositionMode == PositionOnContainingLine)
2817         return direction == HorizontalLine ? height() : width();
2818     
2819     // Inline blocks are replaced elements. Otherwise, just pass off to
2820     // the base class.  If we're being queried as though we're the root line
2821     // box, then the fact that we're an inline-block is irrelevant, and we behave
2822     // just like a block.
2823     if (isReplaced() && linePositionMode == PositionOnContainingLine)
2824         return RenderBox::lineHeight(firstLine, direction, linePositionMode);
2825
2826     if (firstLine && document().styleSheetCollection().usesFirstLineRules()) {
2827         RenderStyle& s = firstLine ? firstLineStyle() : style();
2828         if (&s != &style())
2829             return s.computedLineHeight();
2830     }
2831     
2832     return style().computedLineHeight();
2833 }
2834
2835 int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
2836 {
2837     // Inline blocks are replaced elements. Otherwise, just pass off to
2838     // the base class.  If we're being queried as though we're the root line
2839     // box, then the fact that we're an inline-block is irrelevant, and we behave
2840     // just like a block.
2841     if (isReplaced() && linePositionMode == PositionOnContainingLine) {
2842         if (isAnonymousInlineBlock())
2843             return direction == HorizontalLine ? height() : width();
2844         
2845         // For "leaf" theme objects, let the theme decide what the baseline position is.
2846         // FIXME: Might be better to have a custom CSS property instead, so that if the theme
2847         // is turned off, checkboxes/radios will still have decent baselines.
2848         // FIXME: Need to patch form controls to deal with vertical lines.
2849         if (style().hasAppearance() && !theme().isControlContainer(style().appearance()))
2850             return theme().baselinePosition(*this);
2851             
2852         // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
2853         // the normal flow.  We make an exception for marquees, since their baselines are meaningless
2854         // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
2855         // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
2856         // vertically (e.g., an overflow:hidden block that has had scrollTop moved).
2857         bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
2858             : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
2859         
2860         Optional<int> baselinePos = ignoreBaseline ? Optional<int>() : inlineBlockBaseline(direction);
2861         
2862         if (isDeprecatedFlexibleBox()) {
2863             // Historically, we did this check for all baselines. But we can't
2864             // remove this code from deprecated flexbox, because it effectively
2865             // breaks -webkit-line-clamp, which is used in the wild -- we would
2866             // calculate the baseline as if -webkit-line-clamp wasn't used.
2867             // For simplicity, we use this for all uses of deprecated flexbox.
2868             LayoutUnit bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
2869             if (baselinePos && baselinePos.value() > bottomOfContent)
2870                 baselinePos = Optional<int>();
2871         }
2872         if (baselinePos)
2873             return direction == HorizontalLine ? marginTop() + baselinePos.value() : marginRight() + baselinePos.value();
2874
2875         return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
2876     }
2877
2878     const RenderStyle& style = firstLine ? firstLineStyle() : this->style();
2879     const FontMetrics& fontMetrics = style.fontMetrics();
2880     return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
2881 }
2882
2883 LayoutUnit RenderBlock::minLineHeightForReplacedRenderer(bool isFirstLine, LayoutUnit replacedHeight) const
2884 {
2885     if (!document().inNoQuirksMode() && replacedHeight)
2886         return replacedHeight;
2887
2888     const RenderStyle& style = isFirstLine ? firstLineStyle() : this->style();
2889     if (!(style.lineBoxContain() & LineBoxContainBlock))
2890         return 0;
2891
2892     return std::max<LayoutUnit>(replacedHeight, lineHeight(isFirstLine, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
2893 }
2894
2895 Optional<int> RenderBlock::firstLineBaseline() const
2896 {
2897     if (isWritingModeRoot() && !isRubyRun())
2898         return Optional<int>();
2899
2900     for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
2901         if (!curr->isFloatingOrOutOfFlowPositioned()) {
2902             if (Optional<int> result = curr->firstLineBaseline())
2903                 return Optional<int>(curr->logicalTop() + result.value()); // Translate to our coordinate space.
2904         }
2905     }
2906
2907     return Optional<int>();
2908 }
2909
2910 Optional<int> RenderBlock::inlineBlockBaseline(LineDirectionMode lineDirection) const
2911 {
2912     if (isWritingModeRoot() && !isRubyRun())
2913         return Optional<int>();
2914
2915     bool haveNormalFlowChild = false;
2916     for (auto box = lastChildBox(); box; box = box->previousSiblingBox()) {
2917         if (box->isFloatingOrOutOfFlowPositioned())
2918             continue;
2919         haveNormalFlowChild = true;
2920         if (Optional<int> result = box->inlineBlockBaseline(lineDirection))
2921             return Optional<int>(box->logicalTop() + result.value()); // Translate to our coordinate space.
2922     }
2923
2924     if (!haveNormalFlowChild && hasLineIfEmpty()) {
2925         auto& fontMetrics = firstLineStyle().fontMetrics();
2926         return Optional<int>(fontMetrics.ascent()
2927             + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
2928             + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight()));
2929     }
2930
2931     return Optional<int>();
2932 }
2933
2934 static inline bool isRenderBlockFlowOrRenderButton(RenderElement& renderElement)
2935 {
2936     // We include isRenderButton in this check because buttons are implemented
2937     // using flex box but should still support first-line|first-letter.
2938     // The flex box and specs require that flex box and grid do not support
2939     // first-line|first-letter, though.
2940     // FIXME: Remove when buttons are implemented with align-items instead of
2941     // flex box.
2942     return renderElement.isRenderBlockFlow() || renderElement.isRenderButton();
2943 }
2944
2945 RenderBlock* RenderBlock::firstLineBlock() const
2946 {
2947     RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
2948     bool hasPseudo = false;
2949     while (true) {
2950         hasPseudo = firstLineBlock->style().hasPseudoStyle(FIRST_LINE);
2951         if (hasPseudo)
2952             break;
2953         RenderElement* parentBlock = firstLineBlock->parent();
2954         if (firstLineBlock->isReplaced() || firstLineBlock->isFloating()
2955             || !parentBlock || parentBlock->firstChild() != firstLineBlock || !isRenderBlockFlowOrRenderButton(*parentBlock))
2956             break;
2957         firstLineBlock = downcast<RenderBlock>(parentBlock);
2958     } 
2959     
2960     if (!hasPseudo)
2961         return nullptr;
2962     
2963     return firstLineBlock;
2964 }
2965
2966 static RenderStyle& styleForFirstLetter(RenderElement* firstLetterBlock, RenderObject* firstLetterContainer)
2967 {
2968     RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, &firstLetterContainer->firstLineStyle());
2969     
2970     // If we have an initial letter drop that is >= 1, then we need to force floating to be on.
2971     if (pseudoStyle->initialLetterDrop() >= 1 && !pseudoStyle->isFloating())
2972         pseudoStyle->setFloating(pseudoStyle->isLeftToRightDirection() ? LeftFloat : RightFloat);
2973
2974     // We have to compute the correct font-size for the first-letter if it has an initial letter height set.
2975     RenderObject* paragraph = firstLetterContainer->isRenderBlockFlow() ? firstLetterContainer : firstLetterContainer->containingBlock();
2976     if (pseudoStyle->initialLetterHeight() >= 1 && pseudoStyle->fontMetrics().hasCapHeight() && paragraph->style().fontMetrics().hasCapHeight()) {
2977         // FIXME: For ideographic baselines, we want to go from line edge to line edge. This is equivalent to (N-1)*line-height + the font height.
2978         // We don't yet support ideographic baselines.
2979         // For an N-line first-letter and for alphabetic baselines, the cap-height of the first letter needs to equal (N-1)*line-height of paragraph lines + cap-height of the paragraph
2980         // Mathematically we can't rely on font-size, since font().height() doesn't necessarily match. For reliability, the best approach is simply to
2981         // compare the final measured cap-heights of the two fonts in order to get to the closest possible value.
2982         pseudoStyle->setLineBoxContain(LineBoxContainInitialLetter);
2983         int lineHeight = paragraph->style().computedLineHeight();
2984         
2985         // Set the font to be one line too big and then ratchet back to get to a precise fit. We can't just set the desired font size based off font height metrics
2986         // because many fonts bake ascent into the font metrics. Therefore we have to look at actual measured cap height values in order to know when we have a good fit.
2987         FontDescription newFontDescription = pseudoStyle->fontDescription();
2988         float capRatio = pseudoStyle->fontMetrics().floatCapHeight() / pseudoStyle->fontSize();
2989         float startingFontSize = ((pseudoStyle->initialLetterHeight() - 1) * lineHeight + paragraph->style().fontMetrics().capHeight()) / capRatio;
2990         newFontDescription.setSpecifiedSize(startingFontSize);
2991         newFontDescription.setComputedSize(startingFontSize);
2992         pseudoStyle->setFontDescription(newFontDescription);
2993         pseudoStyle->fontCascade().update(pseudoStyle->fontCascade().fontSelector());
2994         
2995         int desiredCapHeight = (pseudoStyle->initialLetterHeight() - 1) * lineHeight + paragraph->style().fontMetrics().capHeight();
2996         int actualCapHeight = pseudoStyle->fontMetrics().capHeight();
2997         while (actualCapHeight > desiredCapHeight) {
2998             FontDescription newFontDescription = pseudoStyle->fontDescription();
2999             newFontDescription.setSpecifiedSize(newFontDescription.specifiedSize() - 1);
3000             newFontDescription.setComputedSize(newFontDescription.computedSize() -1);
3001             pseudoStyle->setFontDescription(newFontDescription);
3002             pseudoStyle->fontCascade().update(pseudoStyle->fontCascade().fontSelector());
3003             actualCapHeight = pseudoStyle->fontMetrics().capHeight();
3004         }
3005     }
3006     
3007     // Force inline display (except for floating first-letters).
3008     pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
3009     // CSS2 says first-letter can't be positioned.
3010     pseudoStyle->setPosition(StaticPosition);
3011     return *pseudoStyle;
3012 }
3013
3014 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
3015 // "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
3016 // "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
3017 static inline bool isPunctuationForFirstLetter(UChar c)
3018 {
3019     return U_GET_GC_MASK(c) & (U_GC_PS_MASK | U_GC_PE_MASK | U_GC_PI_MASK | U_GC_PF_MASK | U_GC_PO_MASK);
3020 }
3021
3022 static inline bool shouldSkipForFirstLetter(UChar c)
3023 {
3024     return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
3025 }
3026
3027 static inline RenderBlock* findFirstLetterBlock(RenderBlock* start)
3028 {
3029     RenderBlock* firstLetterBlock = start;
3030     while (true) {
3031         bool canHaveFirstLetterRenderer = firstLetterBlock->style().hasPseudoStyle(FIRST_LETTER)
3032             && firstLetterBlock->canHaveGeneratedChildren()
3033             && isRenderBlockFlowOrRenderButton(*firstLetterBlock);
3034         if (canHaveFirstLetterRenderer)
3035             return firstLetterBlock;
3036
3037         RenderElement* parentBlock = firstLetterBlock->parent();
3038         if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock
3039             || !isRenderBlockFlowOrRenderButton(*parentBlock))
3040             return nullptr;
3041         firstLetterBlock = downcast<RenderBlock>(parentBlock);
3042     } 
3043
3044     return nullptr;
3045 }
3046
3047 void RenderBlock::updateFirstLetterStyle(RenderElement* firstLetterBlock, RenderObject* currentChild)
3048 {
3049     RenderElement* firstLetter = currentChild->parent();
3050     RenderElement* firstLetterContainer = firstLetter->parent();
3051     RenderStyle& pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
3052     ASSERT(firstLetter->isFloating() || firstLetter->isInline());
3053
3054     if (Style::determineChange(firstLetter->style(), pseudoStyle) == Style::Detach) {
3055         // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
3056         RenderBoxModelObject* newFirstLetter;
3057         if (pseudoStyle.display() == INLINE)
3058             newFirstLetter = new RenderInline(document(), pseudoStyle);
3059         else
3060             newFirstLetter = new RenderBlockFlow(document(), pseudoStyle);
3061         newFirstLetter->initializeStyle();
3062
3063         // Move the first letter into the new renderer.
3064         LayoutStateDisabler layoutStateDisabler(view());
3065         while (RenderObject* child = firstLetter->firstChild()) {
3066             if (is<RenderText>(*child))
3067                 downcast<RenderText>(*child).removeAndDestroyTextBoxes();
3068             firstLetter->removeChild(*child);
3069             newFirstLetter->addChild(child, nullptr);
3070         }
3071
3072         RenderObject* nextSibling = firstLetter->nextSibling();
3073         if (RenderTextFragment* remainingText = downcast<RenderBoxModelObject>(*firstLetter).firstLetterRemainingText()) {
3074             ASSERT(remainingText->isAnonymous() || remainingText->textNode()->renderer() == remainingText);
3075             // Replace the old renderer with the new one.
3076             remainingText->setFirstLetter(*newFirstLetter);
3077             newFirstLetter->setFirstLetterRemainingText(remainingText);
3078         }
3079         // To prevent removal of single anonymous block in RenderBlock::removeChild and causing
3080         // |nextSibling| to go stale, we remove the old first letter using removeChildNode first.
3081         firstLetterContainer->removeChildInternal(*firstLetter, NotifyChildren);
3082         firstLetter->destroy();
3083         firstLetter = newFirstLetter;
3084         firstLetterContainer->addChild(firstLetter, nextSibling);
3085     } else
3086         firstLetter->setStyle(pseudoStyle);
3087 }
3088
3089 void RenderBlock::createFirstLetterRenderer(RenderElement* firstLetterBlock, RenderText* currentTextChild)
3090 {
3091     RenderElement* firstLetterContainer = currentTextChild->parent();
3092     RenderStyle& pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
3093     RenderBoxModelObject* firstLetter = nullptr;
3094     if (pseudoStyle.display() == INLINE)
3095         firstLetter = new RenderInline(document(), pseudoStyle);
3096     else
3097         firstLetter = new RenderBlockFlow(document(), pseudoStyle);
3098     firstLetter->initializeStyle();
3099     firstLetterContainer->addChild(firstLetter, currentTextChild);
3100
3101     // The original string is going to be either a generated content string or a DOM node's
3102     // string.  We want the original string before it got transformed in case first-letter has
3103     // no text-transform or a different text-transform applied to it.
3104     String oldText = currentTextChild->originalText();
3105     ASSERT(!oldText.isNull());
3106
3107     if (!oldText.isEmpty()) {
3108         unsigned length = 0;
3109
3110         // Account for leading spaces and punctuation.
3111         while (length < oldText.length() && shouldSkipForFirstLetter(oldText[length]))
3112             length++;
3113
3114         // Account for first grapheme cluster.
3115         length += numCharactersInGraphemeClusters(StringView(oldText).substring(length), 1);
3116         
3117         // Keep looking for whitespace and allowed punctuation, but avoid
3118         // accumulating just whitespace into the :first-letter.
3119         for (unsigned scanLength = length; scanLength < oldText.length(); ++scanLength) {
3120             UChar c = oldText[scanLength];
3121             
3122             if (!shouldSkipForFirstLetter(c))
3123                 break;
3124
3125             if (isPunctuationForFirstLetter(c))
3126                 length = scanLength + 1;
3127          }
3128          
3129         // Construct a text fragment for the text after the first letter.
3130         // This text fragment might be empty.
3131         RenderTextFragment* remainingText;
3132         if (currentTextChild->textNode())
3133             remainingText = new RenderTextFragment(*currentTextChild->textNode(), oldText, length, oldText.length() - length);
3134         else
3135             remainingText = new RenderTextFragment(document(), oldText, length, oldText.length() - length);
3136
3137         if (remainingText->textNode())
3138             remainingText->textNode()->setRenderer(remainingText);
3139
3140         firstLetterContainer->addChild(remainingText, currentTextChild);
3141         firstLetterContainer->removeChild(*currentTextChild);
3142         remainingText->setFirstLetter(*firstLetter);
3143         firstLetter->setFirstLetterRemainingText(remainingText);
3144         
3145         // construct text fragment for the first letter
3146         RenderTextFragment* letter;
3147         if (remainingText->textNode())
3148             letter = new RenderTextFragment(*remainingText->textNode(), oldText, 0, length);
3149         else
3150             letter = new RenderTextFragment(document(), oldText, 0, length);
3151
3152         firstLetter->addChild(letter);
3153
3154         currentTextChild->destroy();
3155     }
3156 }
3157     
3158 void RenderBlock::getFirstLetter(RenderObject*& firstLetter, RenderElement*& firstLetterContainer, RenderObject* skipObject)
3159 {
3160     firstLetter = nullptr;
3161     firstLetterContainer = nullptr;
3162
3163     if (!document().styleSheetCollection().usesFirstLetterRules())
3164         return;
3165
3166     // Don't recur
3167     if (style().styleType() == FIRST_LETTER)
3168         return;
3169     
3170     // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
3171     // an efficient way to check for that situation though before implementing anything.
3172     firstLetterContainer = findFirstLetterBlock(this);
3173     if (!firstLetterContainer)
3174         return;
3175     
3176     // Drill into inlines looking for our first text descendant.
3177     firstLetter = firstLetterContainer->firstChild();
3178     while (firstLetter) {
3179         if (is<RenderText>(*firstLetter)) {
3180             if (firstLetter == skipObject) {
3181                 firstLetter = firstLetter->nextSibling();
3182                 continue;
3183             }
3184             
3185             break;
3186         }
3187
3188         RenderElement& current = downcast<RenderElement>(*firstLetter);
3189         if (is<RenderListMarker>(current))
3190             firstLetter = current.nextSibling();
3191         else if (current.isFloatingOrOutOfFlowPositioned()) {
3192             if (current.style().styleType() == FIRST_LETTER) {
3193                 firstLetter = current.firstChild();
3194                 break;
3195             }
3196             firstLetter = current.nextSibling();
3197         } else if (current.isReplaced() || is<RenderButton>(current) || is<RenderMenuList>(current))
3198             break;
3199         else if (current.isFlexibleBoxIncludingDeprecated()
3200 #if ENABLE(CSS_GRID_LAYOUT)
3201             || current.isRenderGrid()
3202 #endif
3203             )
3204             firstLetter = current.nextSibling();
3205         else if (current.style().hasPseudoStyle(FIRST_LETTER) && current.canHaveGeneratedChildren())  {
3206             // We found a lower-level node with first-letter, which supersedes the higher-level style
3207             firstLetterContainer = &current;
3208             firstLetter = current.firstChild();
3209         } else
3210             firstLetter = current.firstChild();
3211     }
3212     
3213     if (!firstLetter)
3214         firstLetterContainer = nullptr;
3215 }
3216
3217 void RenderBlock::updateFirstLetter()
3218 {
3219     RenderObject* firstLetterObj;
3220     RenderElement* firstLetterContainer;
3221     // FIXME: The first letter might be composed of a variety of code units, and therefore might
3222     // be contained within multiple RenderElements.
3223     getFirstLetter(firstLetterObj, firstLetterContainer);
3224
3225     if (!firstLetterObj || !firstLetterContainer)
3226         return;
3227
3228     // If the child already has style, then it has already been created, so we just want
3229     // to update it.
3230     if (firstLetterObj->parent()->style().styleType() == FIRST_LETTER) {
3231         updateFirstLetterStyle(firstLetterContainer, firstLetterObj);
3232         return;
3233     }
3234
3235     if (!is<RenderText>(*firstLetterObj))
3236         return;
3237
3238     // Our layout state is not valid for the repaints we are going to trigger by
3239     // adding and removing children of firstLetterContainer.
3240     LayoutStateDisabler layoutStateDisabler(view());
3241
3242     createFirstLetterRenderer(firstLetterContainer, downcast<RenderText>(firstLetterObj));
3243 }
3244
3245 RenderFlowThread* RenderBlock::cachedFlowThreadContainingBlock() const
3246 {
3247     RenderBlockRareData* rareData = getBlockRareData(this);
3248
3249     if (!rareData || !rareData->m_flowThreadContainingBlock)
3250         return nullptr;
3251
3252     return rareData->m_flowThreadContainingBlock.value();
3253 }
3254
3255 bool RenderBlock::cachedFlowThreadContainingBlockNeedsUpdate() const
3256 {
3257     RenderBlockRareData* rareData = getBlockRareData(this);
3258
3259     if (!rareData || !rareData->m_flowThreadContainingBlock)
3260         return true;
3261
3262     return false;
3263 }
3264
3265 void RenderBlock::setCachedFlowThreadContainingBlockNeedsUpdate()
3266 {
3267     RenderBlockRareData& rareData = ensureBlockRareData(this);
3268     rareData.m_flowThreadContainingBlock = Nullopt;
3269 }
3270
3271 RenderFlowThread* RenderBlock::updateCachedFlowThreadContainingBlock(RenderFlowThread* flowThread) const
3272 {
3273     RenderBlockRareData& rareData = ensureBlockRareData(this);
3274     rareData.m_flowThreadContainingBlock = flowThread;
3275
3276     return flowThread;
3277 }
3278
3279 RenderFlowThread* RenderBlock::locateFlowThreadContainingBlock() const
3280 {
3281     RenderBlockRareData* rareData = getBlockRareData(this);
3282     if (!rareData || !rareData->m_flowThreadContainingBlock)
3283         return updateCachedFlowThreadContainingBlock(RenderBox::locateFlowThreadContainingBlock());
3284
3285     ASSERT(rareData->m_flowThreadContainingBlock.value() == RenderBox::locateFlowThreadContainingBlock());
3286     return rareData->m_flowThreadContainingBlock.value();
3287 }
3288
3289 LayoutUnit RenderBlock::paginationStrut() const
3290 {
3291     RenderBlockRareData* rareData = getBlockRareData(this);
3292     return rareData ? rareData->m_paginationStrut : LayoutUnit();
3293 }
3294
3295 LayoutUnit RenderBlock::pageLogicalOffset() const
3296 {
3297     RenderBlockRareData* rareData = getBlockRareData(this);
3298     return rareData ? rareData->m_pageLogicalOffset : LayoutUnit();
3299 }
3300
3301 void RenderBlock::setPaginationStrut(LayoutUnit strut)
3302 {
3303     RenderBlockRareData* rareData = getBlockRareData(this);
3304     if (!rareData) {
3305         if (!strut)
3306             return;
3307         rareData = &ensureBlockRareData(this);
3308     }
3309     rareData->m_paginationStrut = strut;
3310 }
3311
3312 void RenderBlock::setPageLogicalOffset(LayoutUnit logicalOffset)
3313 {
3314     RenderBlockRareData* rareData = getBlockRareData(this);
3315     if (!rareData) {
3316         if (!logicalOffset)
3317             return;
3318         rareData = &ensureBlockRareData(this);
3319     }
3320     rareData->m_pageLogicalOffset = logicalOffset;
3321 }
3322
3323 void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
3324 {
3325     // For blocks inside inlines, we include margins so that we run right up to the inline boxes
3326     // above and below us (thus getting merged with them to form a single irregular shape).
3327     if (isAnonymousBlockContinuation()) {
3328         // FIXME: This is wrong for block-flows that are horizontal.
3329         // https://bugs.webkit.org/show_bug.cgi?id=46781
3330         rects.append(snappedIntRect(accumulatedOffset.x(), accumulatedOffset.y() - collapsedMarginBefore(),
3331                                 width(), height() + collapsedMarginBefore() + collapsedMarginAfter()));
3332         continuation()->absoluteRects(rects, accumulatedOffset - toLayoutSize(location() +
3333                 inlineElementContinuation()->containingBlock()->location()));
3334     } else
3335         rects.append(snappedIntRect(accumulatedOffset, size()));
3336 }
3337
3338 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
3339 {
3340     // For blocks inside inlines, we include margins so that we run right up to the inline boxes
3341     // above and below us (thus getting merged with them to form a single irregular shape).
3342     FloatRect localRect = isAnonymousBlockContinuation() 
3343         ? FloatRect(0, -collapsedMarginBefore(), width(), height() + collapsedMarginBefore() + collapsedMarginAfter())
3344         : FloatRect(0, 0, width(), height());
3345     
3346     // FIXME: This is wrong for block-flows that are horizontal.
3347     // https://bugs.webkit.org/show_bug.cgi?id=46781
3348     RenderFlowThread* flowThread = flowThreadContainingBlock();
3349     if (!flowThread || !flowThread->absoluteQuadsForBox(quads, wasFixed, this, localRect.y(), localRect.maxY()))
3350         quads.append(localToAbsoluteQuad(localRect, UseTransforms, wasFixed));
3351
3352     if (isAnonymousBlockContinuation())
3353         continuation()->absoluteQuads(quads, wasFixed);
3354 }
3355
3356 LayoutRect RenderBlock::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
3357 {
3358     LayoutRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
3359     if (isAnonymousBlockContinuation())
3360         r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
3361     return r;
3362 }
3363
3364 RenderElement* RenderBlock::hoverAncestor() const
3365 {
3366     return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
3367 }
3368
3369 void RenderBlock::updateDragState(bool dragOn)
3370 {
3371     RenderBox::updateDragState(dragOn);
3372     if (RenderBoxModelObject* continuation = this->continuation())
3373         continuation->updateDragState(dragOn);
3374 }
3375
3376 const RenderStyle& RenderBlock::outlineStyleForRepaint() const
3377 {
3378     return isAnonymousBlockContinuation() ? continuation()->style() : style();
3379 }
3380
3381 void RenderBlock::childBecameNonInline(RenderElement&)
3382 {
3383     makeChildrenNonInline();
3384     if (isAnonymousBlock() && is<RenderBlock>(parent()))
3385         downcast<RenderBlock>(*parent()).removeLeftoverAnonymousBlock(this);
3386     // |this| may be dead here
3387 }
3388
3389 void RenderBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
3390 {
3391     if (result.innerNode())
3392         return;
3393
3394     if (Node* n = nodeForHitTest()) {
3395         result.setInnerNode(n);
3396         if (!result.innerNonSharedNode())
3397             result.setInnerNonSharedNode(n);
3398         result.setLocalPoint(point);
3399     }
3400 }
3401
3402 LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
3403 {
3404     // Do the normal calculation in most cases.
3405     if (firstChild())
3406         return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
3407
3408     LayoutRect caretRect = localCaretRectForEmptyElement(width(), textIndentOffset());
3409
3410     // FIXME: Does this need to adjust for vertical orientation?
3411     if (extraWidthToEndOfLine)
3412         *extraWidthToEndOfLine = width() - caretRect.maxX();
3413
3414     return caretRect;
3415 }
3416
3417 void RenderBlock::addFocusRingRectsForInlineChildren(Vector<IntRect>&, const LayoutPoint&, const RenderLayerModelObject*)
3418 {
3419     ASSERT_NOT_REACHED();
3420 }
3421
3422 void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
3423 {
3424     // For blocks inside inlines, we include margins so that we run right up to the inline boxes
3425     // above and below us (thus getting merged with them to form a single irregular shape).
3426     if (inlineElementContinuation()) {
3427         // FIXME: This check really isn't accurate. 
3428         bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
3429         // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
3430         // FIXME: This is wrong for block-flows that are horizontal.
3431         // https://bugs.webkit.org/show_bug.cgi?id=46781
3432         bool prevInlineHasLineBox = downcast<RenderInline>(*inlineElementContinuation()->element()->renderer()).firstLineBox();
3433         float topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : LayoutUnit();
3434         float bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : LayoutUnit();
3435         LayoutRect rect(additionalOffset.x(), additionalOffset.y() - topMargin, width(), height() + topMargin + bottomMargin);
3436         if (!rect.isEmpty())
3437             rects.append(snappedIntRect(rect));
3438     } else if (width() && height())
3439         rects.append(snappedIntRect(additionalOffset, size()));
3440
3441     if (!hasOverflowClip() && !hasControlClip()) {
3442         if (childrenInline())
3443             addFocusRingRectsForInlineChildren(rects, additionalOffset, paintContainer);
3444     
3445         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
3446             if (!is<RenderText>(*child) && !is<RenderListMarker>(*child) && is<RenderBox>(*child)) {
3447                 auto& box = downcast<RenderBox>(*child);
3448                 FloatPoint pos;
3449                 // FIXME: This doesn't work correctly with transforms.
3450                 if (box.layer())
3451                     pos = child->localToContainerPoint(FloatPoint(), paintContainer);
3452                 else
3453                     pos = FloatPoint(additionalOffset.x() + box.x(), additionalOffset.y() + box.y());
3454                 box.addFocusRingRects(rects, flooredLayoutPoint(pos), paintContainer);
3455             }
3456         }
3457     }
3458
3459     if (inlineElementContinuation())
3460         inlineElementContinuation()->addFocusRingRects(rects, flooredLayoutPoint(LayoutPoint(additionalOffset + inlineElementContinuation()->containingBlock()->location() - location())), paintContainer);
3461 }
3462
3463 RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const
3464 {
3465     return createAnonymousWithParentRendererAndDisplay(parent, style().display());
3466 }
3467
3468 LayoutUnit RenderBlock::offsetFromLogicalTopOfFirstPage() const
3469 {
3470     LayoutState* layoutState = view().layoutState();
3471     if (layoutState && !layoutState->isPaginated())
3472         return 0;
3473
3474     RenderFlowThread* flowThread = flowThreadContainingBlock();
3475     if (flowThread)
3476         return flowThread->offsetFromLogicalTopOfFirstRegion(this);
3477
3478     if (layoutState) {
3479         ASSERT(layoutState->m_renderer == this);
3480
3481         LayoutSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
3482         return isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
3483     }
3484     
3485     ASSERT_NOT_REACHED();
3486     return 0;
3487 }
3488
3489 RenderRegion* RenderBlock::regionAtBlockOffset(LayoutUnit blockOffset) const
3490 {
3491     RenderFlowThread* flowThread = flowThreadContainingBlock();
3492     if (!flowThread || !flowThread->hasValidRegionInfo())
3493         return 0;
3494
3495     return flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstPage() + blockOffset, true);
3496 }
3497
3498 static bool canComputeRegionRangeForBox(const RenderBlock* parentBlock, const RenderBox& childBox, const RenderFlowThread* flowThreadContainingBlock)
3499 {
3500     ASSERT(parentBlock);
3501     ASSERT(!childBox.isRenderNamedFlowThread());
3502
3503     if (!flowThreadContainingBlock)
3504         return false;
3505
3506     if (!flowThreadContainingBlock->hasRegions())
3507         return false;
3508
3509     if (!childBox.canHaveOutsideRegionRange())
3510         return false;
3511
3512     return flowThreadContainingBlock->hasCachedRegionRangeForBox(parentBlock);
3513 }
3514
3515 bool RenderBlock::childBoxIsUnsplittableForFragmentation(const RenderBox& child) const
3516 {
3517     RenderFlowThread* flowThread = flowThreadContainingBlock();
3518     bool checkColumnBreaks = flowThread && flowThread->shouldCheckColumnBreaks();
3519     bool checkPageBreaks = !checkColumnBreaks && view().layoutState()->m_pageLogicalHeight;
3520     bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
3521     return child.isUnsplittableForPagination() || (checkColumnBreaks && child.style().columnBreakInside() == PBAVOID)
3522         || (checkPageBreaks && child.style().pageBreakInside() == PBAVOID)
3523         || (checkRegionBreaks && child.style().regionBreakInside() == PBAVOID);
3524 }
3525
3526 void RenderBlock::computeRegionRangeForBoxChild(const RenderBox& box) const
3527 {
3528     RenderFlowThread* flowThread = flowThreadContainingBlock();
3529     ASSERT(canComputeRegionRangeForBox(this, box, flowThread));
3530
3531     RenderRegion* startRegion;
3532     RenderRegion* endRegion;
3533     LayoutUnit offsetFromLogicalTopOfFirstRegion = box.offsetFromLogicalTopOfFirstPage();
3534     if (childBoxIsUnsplittableForFragmentation(box))
3535         startRegion = endRegion = flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstRegion, true);
3536     else {
3537         startRegion = flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstRegion, true);
3538         endRegion = flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstRegion + logicalHeightForChild(box), true);
3539     }
3540
3541     flowThread->setRegionRangeForBox(&box, startRegion, endRegion);
3542 }
3543
3544 void RenderBlock::estimateRegionRangeForBoxChild(const RenderBox& box) const
3545 {
3546     RenderFlowThread* flowThread = flowThreadContainingBlock();
3547     if (!canComputeRegionRangeForBox(this, box, flowThread))
3548         return;
3549
3550     if (childBoxIsUnsplittableForFragmentation(box)) {
3551         computeRegionRangeForBoxChild(box);
3552         return;
3553     }
3554
3555     LogicalExtentComputedValues estimatedValues;
3556     box.computeLogicalHeight(RenderFlowThread::maxLogicalHeight(), logicalTopForChild(box), estimatedValues);
3557
3558     LayoutUnit offsetFromLogicalTopOfFirstRegion = box.offsetFromLogicalTopOfFirstPage();
3559     RenderRegion* startRegion = flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstRegion, true);
3560     RenderRegion* endRegion = flowThread->regionAtBlockOffset(this, offsetFromLogicalTopOfFirstRegion + estimatedValues.m_extent, true);
3561
3562     flowThread->setRegionRangeForBox(&box, startRegion, endRegion);
3563 }
3564
3565 bool RenderBlock::updateRegionRangeForBoxChild(const RenderBox& box) const
3566 {
3567     RenderFlowThread* flowThread = flowThreadContainingBlock();
3568     if (!canComputeRegionRangeForBox(this, box, flowThread))
3569         return false;
3570
3571     RenderRegion* startRegion = nullptr;
3572     RenderRegion* endRegion = nullptr;
3573     flowThread->getRegionRangeForBox(&box, startRegion, endRegion);
3574
3575     computeRegionRangeForBoxChild(box);
3576
3577     RenderRegion* newStartRegion = nullptr;
3578     RenderRegion* newEndRegion = nullptr;
3579     flowThread->getRegionRangeForBox(&box, newStartRegion, newEndRegion);
3580
3581
3582     // Changing the start region means we shift everything and a relayout is needed.
3583     if (newStartRegion != startRegion)
3584         return true;
3585
3586     // The region range of the box has changed. Some boxes (e.g floats) may have been positioned assuming
3587     // a different range.
3588     if (box.needsLayoutAfterRegionRangeChange() && newEndRegion != endRegion)
3589         return true;
3590
3591     return false;
3592 }
3593
3594 LayoutUnit RenderBlock::collapsedMarginBeforeForChild(const RenderBox& child) const
3595 {
3596     // If the child has the same directionality as we do, then we can just return its
3597     // collapsed margin.
3598     if (!child.isWritingModeRoot())
3599         return child.collapsedMarginBefore();
3600     
3601     // The child has a different directionality.  If the child is parallel, then it's just
3602     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
3603     if (child.isHorizontalWritingMode() == isHorizontalWritingMode())
3604         return child.collapsedMarginAfter();
3605     
3606     // The child is perpendicular to us, which means its margins don't collapse but are on the
3607     // "logical left/right" sides of the child box.  We can just return the raw margin in this case.  
3608     return marginBeforeForChild(child);
3609 }
3610
3611 LayoutUnit RenderBlock::collapsedMarginAfterForChild(const RenderBox& child) const
3612 {
3613     // If the child has the same directionality as we do, then we can just return its
3614     // collapsed margin.
3615     if (!child.isWritingModeRoot())
3616         return child.collapsedMarginAfter();
3617     
3618     // The child has a different directionality.  If the child is parallel, then it's just
3619     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
3620     if (child.isHorizontalWritingMode() == isHorizontalWritingMode())
3621         return child.collapsedMarginBefore();
3622     
3623     // The child is perpendicular to us, which means its margins don't collapse but are on the
3624     // "logical left/right" side of the child box.  We can just return the raw margin in this case.  
3625     return marginAfterForChild(child);
3626 }
3627
3628 bool RenderBlock::hasMarginBeforeQuirk(const RenderBox& child) const
3629 {
3630     // If the child has the same directionality as we do, then we can just return its
3631     // margin quirk.
3632     if (!child.isWritingModeRoot())
3633         return is<RenderBlock>(child) ? downcast<RenderBlock>(child).hasMarginBeforeQuirk() : child.style().hasMarginBeforeQuirk();
3634     
3635     // The child has a different directionality. If the child is parallel, then it's just
3636     // flipped relative to us. We can use the opposite edge.
3637     if (child.isHorizontalWritingMode() == isHorizontalWritingMode())
3638         return is<RenderBlock>(child) ? downcast<RenderBlock>(child).hasMarginAfterQuirk() : child.style().hasMarginAfterQuirk();
3639     
3640     // The child is perpendicular to us and box sides are never quirky in html.css, and we don't really care about
3641     // whether or not authors specified quirky ems, since they're an implementation detail.
3642     return false;
3643 }
3644
3645 bool RenderBlock::hasMarginAfterQuirk(const RenderBox& child) const
3646 {
3647     // If the child has the same directionality as we do, then we can just return its
3648     // margin quirk.
3649     if (!child.isWritingModeRoot())
3650         return is<RenderBlock>(child) ? downcast<RenderBlock>(child).hasMarginAfterQuirk() : child.style().hasMarginAfterQuirk();
3651     
3652     // The child has a different directionality. If the child is parallel, then it's just
3653     // flipped relative to us. We can use the opposite edge.
3654     if (child.isHorizontalWritingMode() == isHorizontalWritingMode())
3655         return is<RenderBlock>(child) ? downcast<RenderBlock>(child).hasMarginBeforeQuirk() : child.style().hasMarginBeforeQuirk();
3656     
3657     // The child is perpendicular to us and box sides are never quirky in html.css, and we don't really care about
3658     // whether or not authors specified quirky ems, since they're an implementation detail.
3659     return false;
3660 }
3661
3662 const char* RenderBlock::renderName() const
3663 {
3664     if (isBody())
3665         return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
3666
3667     if (isFloating())
3668         return "RenderBlock (floating)";
3669     if (isOutOfFlowPositioned())
3670         return "RenderBlock (positioned)";
3671     if (isAnonymousBlock())
3672         return "RenderBlock (anonymous)";
3673     if (isAnonymousInlineBlock())
3674         return "RenderBlock (anonymous inline-block)";
3675     // FIXME: Temporary hack while the new generated content system is being implemented.
3676     if (isPseudoElement())
3677         return "RenderBlock (generated)";
3678     if (isAnonymous())
3679         return "RenderBlock (generated)";
3680     if (isRelPositioned())
3681         return "RenderBlock (relative positioned)";
3682     if (isStickyPositioned())
3683         return "RenderBlock (sticky positioned)";
3684     return "RenderBlock";
3685 }
3686
3687 TextRun RenderBlock::constructTextRun(RenderObject* context, const FontCascade& font, StringView stringView, const RenderStyle& style, ExpansionBehavior expansion, TextRunFlags flags)
3688 {
3689     TextDirection textDirection = LTR;
3690     bool directionalOverride = style.rtlOrdering() == VisualOrder;
3691     if (flags != DefaultTextRunFlags) {
3692         if (flags & RespectDirection)
3693             textDirection = style.direction();
3694         if (flags & RespectDirectionOverride)
3695             directionalOverride |= isOverride(style.unicodeBidi());
3696     }
3697     TextRun run(stringView, 0, 0, expansion, textDirection, directionalOverride);
3698     if (font.primaryFont().isSVGFont()) {
3699         ASSERT(context); // FIXME: Thread a RenderObject& to this point so we don't have to dereference anything.
3700         run.setRenderingContext(SVGTextRunRenderingContext::create(*context));
3701     }
3702
3703     return run;
3704 }
3705
3706 TextRun RenderBlock::constructTextRun(RenderObject* context, const FontCascade& font, const String& string, const RenderStyle& style, ExpansionBehavior expansion, TextRunFlags flags)
3707 {
3708     return constructTextRun(context, font, StringView(string), style, expansion, flags);
3709 }
3710
3711 TextRun RenderBlock::constructTextRun(RenderObject* context, const FontCascade& font, const RenderText* text, const RenderStyle& style, ExpansionBehavior expansion)
3712 {
3713     return constructTextRun(context, font, text->stringView(), style, expansion);
3714 }
3715
3716 TextRun RenderBlock::constructTextRun(RenderObject* context, const FontCascade& font, const RenderText* text, unsigned offset, unsigned length, const RenderStyle& style, ExpansionBehavior expansion)
3717 {
3718     unsigned stop = offset + length;
3719     ASSERT(stop <= text->textLength());
3720     return constructTextRun(context, font, text->stringView(offset, stop), style, expansion);
3721 }
3722
3723 TextRun RenderBlock::constructTextRun(RenderObject* context, const FontCascade& font, const LChar* characters, int length, const RenderStyle& style, ExpansionBehavior expansion)
3724 {
3725     return constructTextRun(context, font, StringView(characters, length), style, expansion);
3726 }
3727
3728 TextRun RenderBlock::constructTextRun(RenderObject* context, const FontCascade& font, const UChar* characters, int length, const RenderStyle& style, ExpansionBehavior expansion)
3729 {
3730     return constructTextRun(context, font, StringView(characters, length), style, expansion);
3731 }
3732
3733 RenderBlock* RenderBlock::createAnonymousWithParentRendererAndDisplay(const RenderObject* parent, EDisplay display)
3734 {
3735     // FIXME: Do we need to convert all our inline displays to block-type in the anonymous logic ?
3736     RenderBlock* newBox;
3737     if (display == FLEX || display == INLINE_FLEX)
3738         newBox = new RenderFlexibleBox(parent->document(), RenderStyle::createAnonymousStyleWithDisplay(&parent->style(), FLEX));
3739     else
3740         newBox = new RenderBlockFlow(parent->document(), RenderStyle::createAnonymousStyleWithDisplay(&parent->style(), BLOCK));
3741
3742     newBox->initializeStyle();
3743     return newBox;
3744 }
3745
3746 #ifndef NDEBUG
3747 void RenderBlock::checkPositionedObjectsNeedLayout()
3748 {
3749     if (!gPositionedDescendantsMap)
3750         return;
3751
3752     TrackedRendererListHashSet* positionedDescendantSet = positionedObjects();
3753     if (!positionedDescendantSet)
3754         return;
3755
3756     for (auto it = positionedDescendantSet->begin(), end = positionedDescendantSet->end(); it != end; ++it) {
3757         RenderBox* currBox = *it;
3758         ASSERT(!currBox->needsLayout());
3759     }
3760 }
3761
3762 #endif
3763
3764 } // namespace WebCore