46c4bb7c5de21bf12a89045bc4d396bba78a5329
[WebKit-https.git] / Source / WebCore / rendering / RenderObject.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  *           (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011, 2013 Apple Inc. All rights reserved.
7  * Copyright (C) 2009 Google Inc. All rights reserved.
8  * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  *
25  */
26
27 #include "config.h"
28 #include "RenderObject.h"
29
30 #include "AXObjectCache.h"
31 #include "AnimationController.h"
32 #include "EventHandler.h"
33 #include "FloatQuad.h"
34 #include "FlowThreadController.h"
35 #include "FrameSelection.h"
36 #include "FrameView.h"
37 #include "GeometryUtilities.h"
38 #include "GraphicsContext.h"
39 #include "HTMLElement.h"
40 #include "HTMLNames.h"
41 #include "HTMLTableCellElement.h"
42 #include "HTMLTableElement.h"
43 #include "HitTestResult.h"
44 #include "LogicalSelectionOffsetCaches.h"
45 #include "MainFrame.h"
46 #include "Page.h"
47 #include "PseudoElement.h"
48 #include "RenderChildIterator.h"
49 #include "RenderCounter.h"
50 #include "RenderFlowThread.h"
51 #include "RenderGeometryMap.h"
52 #include "RenderInline.h"
53 #include "RenderIterator.h"
54 #include "RenderLayer.h"
55 #include "RenderLayerBacking.h"
56 #include "RenderMultiColumnFlowThread.h"
57 #include "RenderNamedFlowFragment.h"
58 #include "RenderNamedFlowThread.h" 
59 #include "RenderRuby.h"
60 #include "RenderSVGBlock.h"
61 #include "RenderSVGInline.h"
62 #include "RenderSVGModelObject.h"
63 #include "RenderSVGResourceContainer.h"
64 #include "RenderSVGRoot.h"
65 #include "RenderScrollbarPart.h"
66 #include "RenderTableRow.h"
67 #include "RenderTheme.h"
68 #include "RenderView.h"
69 #include "RenderWidget.h"
70 #include "SVGRenderSupport.h"
71 #include "StyleResolver.h"
72 #include "TransformState.h"
73 #include "htmlediting.h"
74 #include <algorithm>
75 #include <stdio.h>
76 #include <wtf/RefCountedLeakCounter.h>
77
78 #if PLATFORM(IOS)
79 #include "SelectionRect.h"
80 #endif
81
82 namespace WebCore {
83
84 using namespace HTMLNames;
85
86 #ifndef NDEBUG
87
88 RenderObject::SetLayoutNeededForbiddenScope::SetLayoutNeededForbiddenScope(RenderObject* renderObject, bool isForbidden)
89     : m_renderObject(renderObject)
90     , m_preexistingForbidden(m_renderObject->isSetNeedsLayoutForbidden())
91 {
92     m_renderObject->setNeedsLayoutIsForbidden(isForbidden);
93 }
94
95 RenderObject::SetLayoutNeededForbiddenScope::~SetLayoutNeededForbiddenScope()
96 {
97     m_renderObject->setNeedsLayoutIsForbidden(m_preexistingForbidden);
98 }
99 #endif
100
101 struct SameSizeAsRenderObject {
102     virtual ~SameSizeAsRenderObject() { } // Allocate vtable pointer.
103     void* pointers[4];
104 #ifndef NDEBUG
105     unsigned m_debugBitfields : 2;
106 #endif
107     unsigned m_bitfields;
108 };
109
110 COMPILE_ASSERT(sizeof(RenderObject) == sizeof(SameSizeAsRenderObject), RenderObject_should_stay_small);
111
112 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, renderObjectCounter, ("RenderObject"));
113
114 RenderObject::RenderObject(Node& node)
115     : CachedImageClient()
116     , m_node(node)
117     , m_parent(nullptr)
118     , m_previous(nullptr)
119     , m_next(nullptr)
120 #ifndef NDEBUG
121     , m_hasAXObject(false)
122     , m_setNeedsLayoutForbidden(false)
123 #endif
124     , m_bitfields(node)
125 {
126     if (RenderView* renderView = node.document().renderView())
127         renderView->didCreateRenderer();
128 #ifndef NDEBUG
129     renderObjectCounter.increment();
130 #endif
131 }
132
133 RenderObject::~RenderObject()
134 {
135     view().didDestroyRenderer();
136 #ifndef NDEBUG
137     ASSERT(!m_hasAXObject);
138     renderObjectCounter.decrement();
139 #endif
140     ASSERT(!hasRareData());
141 }
142
143 RenderTheme& RenderObject::theme() const
144 {
145     return page().theme();
146 }
147
148 bool RenderObject::isDescendantOf(const RenderObject* ancestor) const
149 {
150     for (const RenderObject* renderer = this; renderer; renderer = renderer->m_parent) {
151         if (renderer == ancestor)
152             return true;
153     }
154     return false;
155 }
156
157 bool RenderObject::isLegend() const
158 {
159     return node() && node()->hasTagName(legendTag);
160 }
161
162 bool RenderObject::isHTMLMarquee() const
163 {
164     return node() && node()->renderer() == this && node()->hasTagName(marqueeTag);
165 }
166
167 void RenderObject::setFlowThreadStateIncludingDescendants(FlowThreadState state)
168 {
169     setFlowThreadState(state);
170
171     if (!is<RenderElement>(*this))
172         return;
173
174     for (auto& child : childrenOfType<RenderObject>(downcast<RenderElement>(*this))) {
175         // If the child is a fragmentation context it already updated the descendants flag accordingly.
176         if (child.isRenderFlowThread())
177             continue;
178         ASSERT(state != child.flowThreadState());
179         child.setFlowThreadStateIncludingDescendants(state);
180     }
181 }
182
183 RenderObject::FlowThreadState RenderObject::computedFlowThreadState(const RenderObject& renderer)
184 {
185     if (!renderer.parent())
186         return renderer.flowThreadState();
187
188     auto inheritedFlowState = RenderObject::NotInsideFlowThread;
189     if (is<RenderText>(renderer))
190         inheritedFlowState = renderer.parent()->flowThreadState();
191     else if (is<RenderSVGBlock>(renderer) || is<RenderSVGInline>(renderer) || is<RenderSVGModelObject>(renderer)) {
192         // containingBlock() skips svg boundary (SVG root is a RenderReplaced).
193         if (auto* svgRoot = SVGRenderSupport::findTreeRootObject(downcast<RenderElement>(renderer)))
194             inheritedFlowState = svgRoot->flowThreadState();
195     } else if (auto* containingBlock = renderer.containingBlock())
196         inheritedFlowState = containingBlock->flowThreadState();
197     else {
198         // Splitting lines or doing continuation, so just keep the current state.
199         inheritedFlowState = renderer.flowThreadState();
200     }
201     return inheritedFlowState;
202 }
203
204 void RenderObject::initializeFlowThreadStateOnInsertion()
205 {
206     ASSERT(parent());
207
208     // A RenderFlowThread is always considered to be inside itself, so it never has to change its state in response to parent changes.
209     if (isRenderFlowThread())
210         return;
211
212     auto computedState = computedFlowThreadState(*this);
213     if (flowThreadState() == computedState)
214         return;
215
216     setFlowThreadStateIncludingDescendants(computedState);
217 }
218
219 void RenderObject::resetFlowThreadStateOnRemoval()
220 {
221     if (flowThreadState() == NotInsideFlowThread)
222         return;
223
224     if (!documentBeingDestroyed() && is<RenderElement>(*this)) {
225         downcast<RenderElement>(*this).removeFromRenderFlowThread();
226         return;
227     }
228
229     // A RenderFlowThread is always considered to be inside itself, so it never has to change its state in response to parent changes.
230     if (isRenderFlowThread())
231         return;
232
233     setFlowThreadStateIncludingDescendants(NotInsideFlowThread);
234 }
235
236 void RenderObject::setParent(RenderElement* parent)
237 {
238     m_parent = parent;
239 }
240
241 void RenderObject::removeFromParent()
242 {
243     if (parent())
244         parent()->removeChild(*this);
245 }
246
247 RenderObject* RenderObject::nextInPreOrder() const
248 {
249     if (RenderObject* o = firstChildSlow())
250         return o;
251
252     return nextInPreOrderAfterChildren();
253 }
254
255 RenderObject* RenderObject::nextInPreOrderAfterChildren() const
256 {
257     RenderObject* o;
258     if (!(o = nextSibling())) {
259         o = parent();
260         while (o && !o->nextSibling())
261             o = o->parent();
262         if (o)
263             o = o->nextSibling();
264     }
265
266     return o;
267 }
268
269 RenderObject* RenderObject::nextInPreOrder(const RenderObject* stayWithin) const
270 {
271     if (RenderObject* o = firstChildSlow())
272         return o;
273
274     return nextInPreOrderAfterChildren(stayWithin);
275 }
276
277 RenderObject* RenderObject::nextInPreOrderAfterChildren(const RenderObject* stayWithin) const
278 {
279     if (this == stayWithin)
280         return nullptr;
281
282     const RenderObject* current = this;
283     RenderObject* next;
284     while (!(next = current->nextSibling())) {
285         current = current->parent();
286         if (!current || current == stayWithin)
287             return nullptr;
288     }
289     return next;
290 }
291
292 RenderObject* RenderObject::previousInPreOrder() const
293 {
294     if (RenderObject* o = previousSibling()) {
295         while (RenderObject* last = o->lastChildSlow())
296             o = last;
297         return o;
298     }
299
300     return parent();
301 }
302
303 RenderObject* RenderObject::previousInPreOrder(const RenderObject* stayWithin) const
304 {
305     if (this == stayWithin)
306         return nullptr;
307
308     return previousInPreOrder();
309 }
310
311 RenderObject* RenderObject::childAt(unsigned index) const
312 {
313     RenderObject* child = firstChildSlow();
314     for (unsigned i = 0; child && i < index; i++)
315         child = child->nextSibling();
316     return child;
317 }
318
319 RenderObject* RenderObject::firstLeafChild() const
320 {
321     RenderObject* r = firstChildSlow();
322     while (r) {
323         RenderObject* n = nullptr;
324         n = r->firstChildSlow();
325         if (!n)
326             break;
327         r = n;
328     }
329     return r;
330 }
331
332 RenderObject* RenderObject::lastLeafChild() const
333 {
334     RenderObject* r = lastChildSlow();
335     while (r) {
336         RenderObject* n = nullptr;
337         n = r->lastChildSlow();
338         if (!n)
339             break;
340         r = n;
341     }
342     return r;
343 }
344
345 #if ENABLE(TEXT_AUTOSIZING)
346
347 // Non-recursive version of the DFS search.
348 RenderObject* RenderObject::traverseNext(const RenderObject* stayWithin, HeightTypeTraverseNextInclusionFunction inclusionFunction, int& currentDepth, int& newFixedDepth) const
349 {
350     BlockContentHeightType overflowType;
351
352     // Check for suitable children.
353     for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling()) {
354         overflowType = inclusionFunction(*child);
355         if (overflowType != FixedHeight) {
356             currentDepth++;
357             if (overflowType == OverflowHeight)
358                 newFixedDepth = currentDepth;
359             ASSERT(!stayWithin || child->isDescendantOf(stayWithin));
360             return child;
361         }
362     }
363
364     if (this == stayWithin)
365         return nullptr;
366
367     // Now we traverse other nodes if they exist, otherwise
368     // we go to the parent node and try doing the same.
369     const RenderObject* n = this;
370     while (n) {
371         while (n && !n->nextSibling() && (!stayWithin || n->parent() != stayWithin)) {
372             n = n->parent();
373             currentDepth--;
374         }
375         if (!n)
376             return nullptr;
377         for (RenderObject* sibling = n->nextSibling(); sibling; sibling = sibling->nextSibling()) {
378             overflowType = inclusionFunction(*sibling);
379             if (overflowType != FixedHeight) {
380                 if (overflowType == OverflowHeight)
381                     newFixedDepth = currentDepth;
382                 ASSERT(!stayWithin || !n->nextSibling() || n->nextSibling()->isDescendantOf(stayWithin));
383                 return sibling;
384             }
385         }
386         if (!stayWithin || n->parent() != stayWithin) {
387             n = n->parent();
388             currentDepth--;
389         } else
390             return nullptr;
391     }
392     return nullptr;
393 }
394
395 #endif // ENABLE(TEXT_AUTOSIZING)
396
397 RenderLayer* RenderObject::enclosingLayer() const
398 {
399     for (auto& renderer : lineageOfType<RenderLayerModelObject>(*this)) {
400         if (renderer.hasLayer())
401             return renderer.layer();
402     }
403     return nullptr;
404 }
405
406 bool RenderObject::scrollRectToVisible(SelectionRevealMode revealMode, const LayoutRect& absoluteRect, bool insideFixed, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
407 {
408     if (revealMode == SelectionRevealMode::DoNotReveal)
409         return false;
410
411     RenderLayer* enclosingLayer = this->enclosingLayer();
412     if (!enclosingLayer)
413         return false;
414
415     enclosingLayer->scrollRectToVisible(revealMode, absoluteRect, insideFixed, alignX, alignY);
416     return true;
417 }
418
419 RenderBox& RenderObject::enclosingBox() const
420 {
421     return *lineageOfType<RenderBox>(const_cast<RenderObject&>(*this)).first();
422 }
423
424 RenderBoxModelObject& RenderObject::enclosingBoxModelObject() const
425 {
426     return *lineageOfType<RenderBoxModelObject>(const_cast<RenderObject&>(*this)).first();
427 }
428
429 bool RenderObject::fixedPositionedWithNamedFlowContainingBlock() const
430 {
431     return ((flowThreadState() == RenderObject::InsideOutOfFlowThread)
432         && (style().position() == FixedPosition)
433         && (containingBlock()->isOutOfFlowRenderFlowThread()));
434 }
435
436 static bool hasFixedPosInNamedFlowContainingBlock(const RenderObject* renderer)
437 {
438     ASSERT(renderer->flowThreadState() != RenderObject::NotInsideFlowThread);
439
440     RenderObject* curr = const_cast<RenderObject*>(renderer);
441     while (curr && !is<RenderView>(*curr)) {
442         if (curr->fixedPositionedWithNamedFlowContainingBlock())
443             return true;
444         curr = curr->containingBlock();
445     }
446
447     return false;
448 }
449
450 RenderBlock* RenderObject::firstLineBlock() const
451 {
452     return nullptr;
453 }
454
455 static inline bool objectIsRelayoutBoundary(const RenderElement* object)
456 {
457     // FIXME: In future it may be possible to broaden these conditions in order to improve performance.
458     if (object->isRenderView())
459         return true;
460
461     if (object->isTextControl())
462         return true;
463
464     if (object->isSVGRoot())
465         return true;
466
467     if (!object->hasOverflowClip())
468         return false;
469
470     if (object->style().width().isIntrinsicOrAuto() || object->style().height().isIntrinsicOrAuto() || object->style().height().isPercentOrCalculated())
471         return false;
472
473     // Table parts can't be relayout roots since the table is responsible for layouting all the parts.
474     if (object->isTablePart())
475         return false;
476
477     return true;
478 }
479
480 void RenderObject::clearNeedsLayout()
481 {
482     m_bitfields.setNeedsLayout(false);
483     setEverHadLayout(true);
484     setPosChildNeedsLayoutBit(false);
485     setNeedsSimplifiedNormalFlowLayoutBit(false);
486     setNormalChildNeedsLayoutBit(false);
487     setNeedsPositionedMovementLayoutBit(false);
488     if (is<RenderElement>(*this))
489         downcast<RenderElement>(*this).setAncestorLineBoxDirty(false);
490 #ifndef NDEBUG
491     checkBlockPositionedObjectsNeedLayout();
492 #endif
493 }
494
495 static void scheduleRelayoutForSubtree(RenderElement& renderer)
496 {
497     if (is<RenderView>(renderer)) {
498         downcast<RenderView>(renderer).frameView().scheduleRelayout();
499         return;
500     }
501
502     if (renderer.isRooted())
503         renderer.view().frameView().scheduleRelayoutOfSubtree(renderer);
504 }
505
506 void RenderObject::markContainingBlocksForLayout(ScheduleRelayout scheduleRelayout, RenderElement* newRoot)
507 {
508     ASSERT(scheduleRelayout == ScheduleRelayout::No || !newRoot);
509     ASSERT(!isSetNeedsLayoutForbidden());
510
511     auto ancestor = container();
512
513     bool simplifiedNormalFlowLayout = needsSimplifiedNormalFlowLayout() && !selfNeedsLayout() && !normalChildNeedsLayout();
514     bool hasOutOfFlowPosition = !isText() && style().hasOutOfFlowPosition();
515
516     while (ancestor) {
517 #ifndef NDEBUG
518         // FIXME: Remove this once we remove the special cases for counters, quotes and mathml
519         // calling setNeedsLayout during preferred width computation.
520         SetLayoutNeededForbiddenScope layoutForbiddenScope(ancestor, isSetNeedsLayoutForbidden());
521 #endif
522         // Don't mark the outermost object of an unrooted subtree. That object will be
523         // marked when the subtree is added to the document.
524         auto container = ancestor->container();
525         if (!container && !ancestor->isRenderView())
526             return;
527         if (hasOutOfFlowPosition) {
528             bool willSkipRelativelyPositionedInlines = !ancestor->isRenderBlock() || ancestor->isAnonymousBlock();
529             // Skip relatively positioned inlines and anonymous blocks to get to the enclosing RenderBlock.
530             while (ancestor && (!ancestor->isRenderBlock() || ancestor->isAnonymousBlock()))
531                 ancestor = ancestor->container();
532             if (!ancestor || ancestor->posChildNeedsLayout())
533                 return;
534             if (willSkipRelativelyPositionedInlines)
535                 container = ancestor->container();
536             ancestor->setPosChildNeedsLayoutBit(true);
537             simplifiedNormalFlowLayout = true;
538         } else if (simplifiedNormalFlowLayout) {
539             if (ancestor->needsSimplifiedNormalFlowLayout())
540                 return;
541             ancestor->setNeedsSimplifiedNormalFlowLayoutBit(true);
542         } else {
543             if (ancestor->normalChildNeedsLayout())
544                 return;
545             ancestor->setNormalChildNeedsLayoutBit(true);
546         }
547         ASSERT(!ancestor->isSetNeedsLayoutForbidden());
548
549         if (ancestor == newRoot)
550             return;
551
552         if (scheduleRelayout == ScheduleRelayout::Yes && objectIsRelayoutBoundary(ancestor))
553             break;
554
555         hasOutOfFlowPosition = ancestor->style().hasOutOfFlowPosition();
556         ancestor = container;
557     }
558
559     if (scheduleRelayout == ScheduleRelayout::Yes && ancestor)
560         scheduleRelayoutForSubtree(*ancestor);
561 }
562
563 #ifndef NDEBUG
564 void RenderObject::checkBlockPositionedObjectsNeedLayout()
565 {
566     ASSERT(!needsLayout());
567
568     if (is<RenderBlock>(*this))
569         downcast<RenderBlock>(*this).checkPositionedObjectsNeedLayout();
570 }
571 #endif
572
573 void RenderObject::setPreferredLogicalWidthsDirty(bool shouldBeDirty, MarkingBehavior markParents)
574 {
575     bool alreadyDirty = preferredLogicalWidthsDirty();
576     m_bitfields.setPreferredLogicalWidthsDirty(shouldBeDirty);
577     if (shouldBeDirty && !alreadyDirty && markParents == MarkContainingBlockChain && (isText() || !style().hasOutOfFlowPosition()))
578         invalidateContainerPreferredLogicalWidths();
579 }
580
581 void RenderObject::invalidateContainerPreferredLogicalWidths()
582 {
583     // In order to avoid pathological behavior when inlines are deeply nested, we do include them
584     // in the chain that we mark dirty (even though they're kind of irrelevant).
585     auto o = isTableCell() ? containingBlock() : container();
586     while (o && !o->preferredLogicalWidthsDirty()) {
587         // Don't invalidate the outermost object of an unrooted subtree. That object will be 
588         // invalidated when the subtree is added to the document.
589         auto container = o->isTableCell() ? o->containingBlock() : o->container();
590         if (!container && !o->isRenderView())
591             break;
592
593         o->m_bitfields.setPreferredLogicalWidthsDirty(true);
594         if (o->style().hasOutOfFlowPosition())
595             // A positioned object has no effect on the min/max width of its containing block ever.
596             // We can optimize this case and not go up any further.
597             break;
598         o = container;
599     }
600 }
601
602 void RenderObject::setLayerNeedsFullRepaint()
603 {
604     ASSERT(hasLayer());
605     downcast<RenderLayerModelObject>(*this).layer()->setRepaintStatus(NeedsFullRepaint);
606 }
607
608 void RenderObject::setLayerNeedsFullRepaintForPositionedMovementLayout()
609 {
610     ASSERT(hasLayer());
611     downcast<RenderLayerModelObject>(*this).layer()->setRepaintStatus(NeedsFullRepaintForPositionedMovementLayout);
612 }
613
614 RenderBlock* RenderObject::containingBlock() const
615 {
616     auto containingBlockForRenderer = [](const RenderElement& renderer)
617     {
618         auto& style = renderer.style();
619         if (style.position() == AbsolutePosition)
620             return renderer.containingBlockForAbsolutePosition();
621         if (style.position() == FixedPosition)
622             return renderer.containingBlockForFixedPosition();
623         return renderer.containingBlockForObjectInFlow();
624     };
625
626     if (is<RenderText>(*this))
627         return containingBlockForObjectInFlow();
628
629     if (!parent() && is<RenderScrollbarPart>(*this)) {
630         if (auto* scrollbarPart = downcast<RenderScrollbarPart>(*this).rendererOwningScrollbar())
631             return containingBlockForRenderer(*scrollbarPart);
632         return nullptr;
633     }
634     return containingBlockForRenderer(downcast<RenderElement>(*this));
635 }
636
637 RenderBlock* RenderObject::containingBlockForObjectInFlow() const
638 {
639     auto* renderer = parent();
640     while (renderer && ((renderer->isInline() && !renderer->isReplaced()) || !renderer->isRenderBlock()))
641         renderer = renderer->parent();
642     return downcast<RenderBlock>(renderer);
643 }
644
645 void RenderObject::addPDFURLRect(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
646 {
647     Vector<LayoutRect> focusRingRects;
648     addFocusRingRects(focusRingRects, paintOffset, paintInfo.paintContainer);
649     LayoutRect urlRect = unionRect(focusRingRects);
650
651     if (urlRect.isEmpty())
652         return;
653     Node* node = this->node();
654     if (!is<Element>(node) || !node->isLink())
655         return;
656     Element& element = downcast<Element>(*node);
657     const AtomicString& href = element.getAttribute(hrefAttr);
658     if (href.isNull())
659         return;
660
661     if (paintInfo.context().supportsInternalLinks()) {
662         String outAnchorName;
663         Element* linkTarget = element.findAnchorElementForLink(outAnchorName);
664         if (linkTarget) {
665             paintInfo.context().setDestinationForRect(outAnchorName, urlRect);
666             return;
667         }
668     }
669
670     paintInfo.context().setURLForRect(node->document().completeURL(href), urlRect);
671
672 }
673
674 #if PLATFORM(IOS)
675 // This function is similar in spirit to RenderText::absoluteRectsForRange, but returns rectangles
676 // which are annotated with additional state which helps iOS draw selections in its unique way.
677 // No annotations are added in this class.
678 // FIXME: Move to RenderText with absoluteRectsForRange()?
679 void RenderObject::collectSelectionRects(Vector<SelectionRect>& rects, unsigned start, unsigned end)
680 {
681     Vector<FloatQuad> quads;
682
683     if (!firstChildSlow()) {
684         // FIXME: WebKit's position for an empty span after a BR is incorrect, so we can't trust 
685         // quads for them. We don't need selection rects for those anyway though, since they 
686         // are just empty containers. See <https://bugs.webkit.org/show_bug.cgi?id=49358>.
687         RenderObject* previous = previousSibling();
688         Node* node = this->node();
689         if (!previous || !previous->isBR() || !node || !node->isContainerNode() || !isInline()) {
690             // For inline elements we don't use absoluteQuads, since it takes into account continuations and leads to wrong results.
691             absoluteQuadsForSelection(quads);
692         }
693     } else {
694         unsigned offset = start;
695         for (RenderObject* child = childAt(start); child && offset < end; child = child->nextSibling(), ++offset)
696             child->absoluteQuads(quads);
697     }
698
699     unsigned numberOfQuads = quads.size();
700     for (unsigned i = 0; i < numberOfQuads; ++i)
701         rects.append(SelectionRect(quads[i].enclosingBoundingBox(), isHorizontalWritingMode(), view().pageNumberForBlockProgressionOffset(quads[i].enclosingBoundingBox().x())));
702 }
703 #endif
704
705 IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms, bool* wasFixed) const
706 {
707     if (useTransforms) {
708         Vector<FloatQuad> quads;
709         absoluteQuads(quads, wasFixed);
710
711         size_t n = quads.size();
712         if (!n)
713             return IntRect();
714     
715         IntRect result = quads[0].enclosingBoundingBox();
716         for (size_t i = 1; i < n; ++i)
717             result.unite(quads[i].enclosingBoundingBox());
718         return result;
719     }
720
721     FloatPoint absPos = localToAbsolute(FloatPoint(), 0 /* ignore transforms */, wasFixed);
722     Vector<IntRect> rects;
723     absoluteRects(rects, flooredLayoutPoint(absPos));
724
725     size_t n = rects.size();
726     if (!n)
727         return IntRect();
728
729     LayoutRect result = rects[0];
730     for (size_t i = 1; i < n; ++i)
731         result.unite(rects[i]);
732     return snappedIntRect(result);
733 }
734
735 void RenderObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
736 {
737     Vector<LayoutRect> rects;
738     // FIXME: addFocusRingRects() needs to be passed this transform-unaware
739     // localToAbsolute() offset here because RenderInline::addFocusRingRects()
740     // implicitly assumes that. This doesn't work correctly with transformed
741     // descendants.
742     FloatPoint absolutePoint = localToAbsolute();
743     addFocusRingRects(rects, flooredLayoutPoint(absolutePoint));
744     float deviceScaleFactor = document().deviceScaleFactor();
745     for (auto rect : rects) {
746         rect.moveBy(LayoutPoint(-absolutePoint));
747         quads.append(localToAbsoluteQuad(FloatQuad(snapRectToDevicePixels(rect, deviceScaleFactor))));
748     }
749 }
750
751 FloatRect RenderObject::absoluteBoundingBoxRectForRange(const Range* range)
752 {
753     if (!range)
754         return FloatRect();
755
756     range->ownerDocument().updateLayout();
757
758     Vector<FloatQuad> quads;
759     range->absoluteTextQuads(quads);
760
761     if (quads.isEmpty())
762         return FloatRect();
763
764     FloatRect result = quads[0].boundingBox();
765     for (size_t i = 1; i < quads.size(); ++i)
766         result.uniteEvenIfEmpty(quads[i].boundingBox());
767
768     return result;
769 }
770
771 void RenderObject::addAbsoluteRectForLayer(LayoutRect& result)
772 {
773     if (hasLayer())
774         result.unite(absoluteBoundingBoxRectIgnoringTransforms());
775
776     if (!is<RenderElement>(*this))
777         return;
778
779     for (auto& child : childrenOfType<RenderObject>(downcast<RenderElement>(*this)))
780         child.addAbsoluteRectForLayer(result);
781 }
782
783 // FIXME: change this to use the subtreePaint terminology
784 LayoutRect RenderObject::paintingRootRect(LayoutRect& topLevelRect)
785 {
786     LayoutRect result = absoluteBoundingBoxRectIgnoringTransforms();
787     topLevelRect = result;
788     if (is<RenderElement>(*this)) {
789         for (auto& child : childrenOfType<RenderObject>(downcast<RenderElement>(*this)))
790             child.addAbsoluteRectForLayer(result);
791     }
792     return result;
793 }
794
795 RenderLayerModelObject* RenderObject::containerForRepaint() const
796 {
797     RenderLayerModelObject* repaintContainer = nullptr;
798
799     if (view().usesCompositing()) {
800         if (RenderLayer* parentLayer = enclosingLayer()) {
801             RenderLayer* compLayer = parentLayer->enclosingCompositingLayerForRepaint();
802             if (compLayer)
803                 repaintContainer = &compLayer->renderer();
804         }
805     }
806     if (view().hasSoftwareFilters()) {
807         if (RenderLayer* parentLayer = enclosingLayer()) {
808             RenderLayer* enclosingFilterLayer = parentLayer->enclosingFilterLayer();
809             if (enclosingFilterLayer)
810                 return &enclosingFilterLayer->renderer();
811         }
812     }
813
814     // If we have a flow thread, then we need to do individual repaints within the RenderRegions instead.
815     // Return the flow thread as a repaint container in order to create a chokepoint that allows us to change
816     // repainting to do individual region repaints.
817     RenderFlowThread* parentRenderFlowThread = flowThreadContainingBlock();
818     if (parentRenderFlowThread) {
819         // If the element has a fixed positioned element with named flow as CB along the CB chain
820         // then the repaint container is not the flow thread.
821         if (hasFixedPosInNamedFlowContainingBlock(this))
822             return repaintContainer;
823         // If we have already found a repaint container then we will repaint into that container only if it is part of the same
824         // flow thread. Otherwise we will need to catch the repaint call and send it to the flow thread.
825         RenderFlowThread* repaintContainerFlowThread = repaintContainer ? repaintContainer->flowThreadContainingBlock() : nullptr;
826         if (!repaintContainerFlowThread || repaintContainerFlowThread != parentRenderFlowThread)
827             repaintContainer = parentRenderFlowThread;
828     }
829     return repaintContainer;
830 }
831
832 void RenderObject::propagateRepaintToParentWithOutlineAutoIfNeeded(const RenderLayerModelObject& repaintContainer, const LayoutRect& repaintRect) const
833 {
834     if (!hasOutlineAutoAncestor())
835         return;
836
837     // FIXME: We should really propagate only when the the child renderer sticks out.
838     bool repaintRectNeedsConverting = false;
839     // Issue repaint on the renderer with outline: auto.
840     for (const auto* renderer = this; renderer; renderer = renderer->parent()) {
841         bool rendererHasOutlineAutoAncestor = renderer->hasOutlineAutoAncestor();
842         ASSERT(rendererHasOutlineAutoAncestor
843             || renderer->outlineStyleForRepaint().outlineStyleIsAuto()
844             || (is<RenderElement>(*renderer) && downcast<RenderElement>(*renderer).hasContinuation()));
845         if (renderer == &repaintContainer && rendererHasOutlineAutoAncestor)
846             repaintRectNeedsConverting = true;
847         if (rendererHasOutlineAutoAncestor)
848             continue;
849         // Issue repaint on the correct repaint container.
850         LayoutRect adjustedRepaintRect = repaintRect;
851         adjustedRepaintRect.inflate(renderer->outlineStyleForRepaint().outlineSize());
852         if (!repaintRectNeedsConverting)
853             repaintContainer.repaintRectangle(adjustedRepaintRect);
854         else if (is<RenderLayerModelObject>(renderer)) {
855             const auto& rendererWithOutline = downcast<RenderLayerModelObject>(*renderer);
856             adjustedRepaintRect = LayoutRect(repaintContainer.localToContainerQuad(FloatRect(adjustedRepaintRect), &rendererWithOutline).boundingBox());
857             rendererWithOutline.repaintRectangle(adjustedRepaintRect);
858         }
859         return;
860     }
861     ASSERT_NOT_REACHED();
862 }
863
864 void RenderObject::repaintUsingContainer(const RenderLayerModelObject* repaintContainer, const LayoutRect& r, bool shouldClipToLayer) const
865 {
866     if (r.isEmpty())
867         return;
868
869     if (!repaintContainer)
870         repaintContainer = &view();
871
872     if (is<RenderFlowThread>(*repaintContainer)) {
873         downcast<RenderFlowThread>(*repaintContainer).repaintRectangleInRegions(r);
874         return;
875     }
876
877     propagateRepaintToParentWithOutlineAutoIfNeeded(*repaintContainer, r);
878
879     if (repaintContainer->hasFilter() && repaintContainer->layer() && repaintContainer->layer()->requiresFullLayerImageForFilters()) {
880         repaintContainer->layer()->setFilterBackendNeedsRepaintingInRect(r);
881         return;
882     }
883
884     if (repaintContainer->isRenderView()) {
885         RenderView& view = this->view();
886         ASSERT(repaintContainer == &view);
887         bool viewHasCompositedLayer = view.isComposited();
888         if (!viewHasCompositedLayer || view.layer()->backing()->paintsIntoWindow()) {
889             LayoutRect rect = r;
890             if (viewHasCompositedLayer && view.layer()->transform())
891                 rect = LayoutRect(view.layer()->transform()->mapRect(snapRectToDevicePixels(rect, document().deviceScaleFactor())));
892             view.repaintViewRectangle(rect);
893             return;
894         }
895     }
896
897     if (view().usesCompositing()) {
898         ASSERT(repaintContainer->isComposited());
899         repaintContainer->layer()->setBackingNeedsRepaintInRect(r, shouldClipToLayer ? GraphicsLayer::ClipToLayer : GraphicsLayer::DoNotClipToLayer);
900     }
901 }
902
903 void RenderObject::repaint() const
904 {
905     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
906     if (!isRooted())
907         return;
908
909     const RenderView& view = this->view();
910     if (view.printing())
911         return;
912
913     RenderLayerModelObject* repaintContainer = containerForRepaint();
914     repaintUsingContainer(repaintContainer, clippedOverflowRectForRepaint(repaintContainer));
915 }
916
917 void RenderObject::repaintRectangle(const LayoutRect& r, bool shouldClipToLayer) const
918 {
919     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
920     if (!isRooted())
921         return;
922
923     const RenderView& view = this->view();
924     if (view.printing())
925         return;
926
927     LayoutRect dirtyRect(r);
928     // FIXME: layoutDelta needs to be applied in parts before/after transforms and
929     // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
930     dirtyRect.move(view.layoutDelta());
931
932     RenderLayerModelObject* repaintContainer = containerForRepaint();
933     repaintUsingContainer(repaintContainer, computeRectForRepaint(dirtyRect, repaintContainer), shouldClipToLayer);
934 }
935
936 void RenderObject::repaintSlowRepaintObject() const
937 {
938     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
939     if (!isRooted())
940         return;
941
942     const RenderView& view = this->view();
943     if (view.printing())
944         return;
945
946     const RenderLayerModelObject* repaintContainer = containerForRepaint();
947
948     bool shouldClipToLayer = true;
949     IntRect repaintRect;
950     // If this is the root background, we need to check if there is an extended background rect. If
951     // there is, then we should not allow painting to clip to the layer size.
952     if (isDocumentElementRenderer() || isBody()) {
953         shouldClipToLayer = !view.frameView().hasExtendedBackgroundRectForPainting();
954         repaintRect = snappedIntRect(view.backgroundRect());
955     } else
956         repaintRect = snappedIntRect(clippedOverflowRectForRepaint(repaintContainer));
957
958     repaintUsingContainer(repaintContainer, repaintRect, shouldClipToLayer);
959 }
960
961 IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
962 {
963     return snappedIntRect(absoluteClippedOverflowRect());
964 }
965     
966 LayoutRect RenderObject::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
967 {
968     LayoutRect r(clippedOverflowRectForRepaint(repaintContainer));
969     r.inflate(outlineWidth);
970     return r;
971 }
972
973 LayoutRect RenderObject::clippedOverflowRectForRepaint(const RenderLayerModelObject*) const
974 {
975     ASSERT_NOT_REACHED();
976     return LayoutRect();
977 }
978
979 LayoutRect RenderObject::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const
980 {
981     if (repaintContainer == this)
982         return rect;
983
984     auto* parent = this->parent();
985     if (!parent)
986         return rect;
987
988     LayoutRect adjustedRect = rect;
989     if (parent->hasOverflowClip()) {
990         downcast<RenderBox>(*parent).applyCachedClipAndScrollPositionForRepaint(adjustedRect);
991         if (adjustedRect.isEmpty())
992             return adjustedRect;
993     }
994     return parent->computeRectForRepaint(adjustedRect, repaintContainer, context);
995 }
996
997 FloatRect RenderObject::computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject*, bool) const
998 {
999     ASSERT_NOT_REACHED();
1000     return FloatRect();
1001 }
1002
1003 #if ENABLE(TREE_DEBUGGING)
1004
1005 static void showRenderTreeLegend()
1006 {
1007     fprintf(stderr, "\n(B)lock/(I)nline/I(N)line-block, (A)bsolute/Fi(X)ed/(R)elative/Stic(K)y, (F)loating, (O)verflow clip, Anon(Y)mous, (G)enerated, has(L)ayer, (C)omposited, (+)Dirty style, (+)Dirty layout\n");
1008 }
1009
1010 void RenderObject::showNodeTreeForThis() const
1011 {
1012     if (!node())
1013         return;
1014     node()->showTreeForThis();
1015 }
1016
1017 void RenderObject::showRenderTreeForThis() const
1018 {
1019     const WebCore::RenderObject* root = this;
1020     while (root->parent())
1021         root = root->parent();
1022     showRenderTreeLegend();
1023     root->showRenderSubTreeAndMark(this, 1);
1024 }
1025
1026 void RenderObject::showLineTreeForThis() const
1027 {
1028     if (!is<RenderBlockFlow>(*this))
1029         return;
1030     showRenderTreeLegend();
1031     showRenderObject(false, 1);
1032     downcast<RenderBlockFlow>(*this).showLineTreeAndMark(nullptr, 2);
1033 }
1034
1035 static const RenderFlowThread* flowThreadContainingBlockFromRenderer(const RenderObject* renderer)
1036 {
1037     if (!renderer)
1038         return nullptr;
1039
1040     if (renderer->flowThreadState() == RenderObject::NotInsideFlowThread)
1041         return nullptr;
1042
1043     if (is<RenderFlowThread>(*renderer))
1044         return downcast<RenderFlowThread>(renderer);
1045
1046     if (is<RenderBlock>(*renderer))
1047         return downcast<RenderBlock>(*renderer).cachedFlowThreadContainingBlock();
1048
1049     return nullptr;
1050 }
1051
1052 void RenderObject::showRegionsInformation() const
1053 {
1054     const RenderFlowThread* ftcb = flowThreadContainingBlockFromRenderer(this);
1055
1056     if (!ftcb) {
1057         // Only the boxes have region range information.
1058         // Try to get the flow thread containing block information
1059         // from the containing block of this box.
1060         if (is<RenderBox>(*this))
1061             ftcb = flowThreadContainingBlockFromRenderer(containingBlock());
1062     }
1063
1064     if (!ftcb)
1065         return;
1066
1067     RenderRegion* startRegion = nullptr;
1068     RenderRegion* endRegion = nullptr;
1069     ftcb->getRegionRangeForBox(downcast<RenderBox>(this), startRegion, endRegion);
1070     fprintf(stderr, " [Rs:%p Re:%p]", startRegion, endRegion);
1071 }
1072
1073 void RenderObject::showRenderObject(bool mark, int depth) const
1074 {
1075     if (isInlineBlockOrInlineTable())
1076         fputc('N', stderr);
1077     else if (isInline())
1078         fputc('I', stderr);
1079     else
1080         fputc('B', stderr);
1081     
1082     if (isPositioned()) {
1083         if (isRelPositioned())
1084             fputc('R', stderr);
1085         else if (isStickyPositioned())
1086             fputc('K', stderr);
1087         else if (isOutOfFlowPositioned()) {
1088             if (style().position() == AbsolutePosition)
1089                 fputc('A', stderr);
1090             else
1091                 fputc('X', stderr);
1092         }
1093     } else
1094         fputc('-', stderr);
1095
1096     if (isFloating())
1097         fputc('F', stderr);
1098     else
1099         fputc('-', stderr);
1100
1101     if (hasOverflowClip())
1102         fputc('O', stderr);
1103     else
1104         fputc('-', stderr);
1105
1106     if (isAnonymous())
1107         fputc('Y', stderr);
1108     else
1109         fputc('-', stderr);
1110
1111     if (isPseudoElement() || isAnonymous())
1112         fputc('G', stderr);
1113     else
1114         fputc('-', stderr);
1115
1116     if (hasLayer())
1117         fputc('L', stderr);
1118     else
1119         fputc('-', stderr);
1120
1121     if (isComposited())
1122         fputc('C', stderr);
1123     else
1124         fputc('-', stderr);
1125
1126     fputc(' ', stderr);
1127
1128     if (node() && node()->needsStyleRecalc())
1129         fputc('+', stderr);
1130     else
1131         fputc('-', stderr);
1132
1133     if (needsLayout())
1134         fputc('+', stderr);
1135     else
1136         fputc('-', stderr);
1137
1138     int printedCharacters = 0;
1139     if (mark) {
1140         fprintf(stderr, "*");
1141         ++printedCharacters;
1142     }
1143
1144     while (++printedCharacters <= depth * 2)
1145         fputc(' ', stderr);
1146
1147     if (node())
1148         fprintf(stderr, "%s ", node()->nodeName().utf8().data());
1149
1150     String name = renderName();
1151     // FIXME: Renderer's name should not include property value listing.
1152     int pos = name.find('(');
1153     if (pos > 0)
1154         fprintf(stderr, "%s", name.left(pos - 1).utf8().data());
1155     else
1156         fprintf(stderr, "%s", name.utf8().data());
1157
1158     if (is<RenderBox>(*this)) {
1159         auto& renderBox = downcast<RenderBox>(*this);
1160         FloatRect boxRect = renderBox.frameRect();
1161         if (renderBox.isInFlowPositioned())
1162             boxRect.move(renderBox.offsetForInFlowPosition());
1163         fprintf(stderr, "  (%.2f, %.2f) (%.2f, %.2f)", boxRect.x(), boxRect.y(), boxRect.width(), boxRect.height());
1164     } else if (is<RenderInline>(*this) && isInFlowPositioned()) {
1165         FloatSize inlineOffset = downcast<RenderInline>(*this).offsetForInFlowPosition();
1166         fprintf(stderr, "  (%.2f, %.2f)", inlineOffset.width(), inlineOffset.height());
1167     }
1168
1169     fprintf(stderr, " renderer->(%p)", this);
1170     if (node()) {
1171         fprintf(stderr, " node->(%p)", node());
1172         if (node()->isTextNode()) {
1173             String value = node()->nodeValue();
1174             fprintf(stderr, " length->(%u)", value.length());
1175
1176             value.replaceWithLiteral('\\', "\\\\");
1177             value.replaceWithLiteral('\n', "\\n");
1178             
1179             const int maxPrintedLength = 80;
1180             if (value.length() > maxPrintedLength) {
1181                 String substring = value.substring(0, maxPrintedLength);
1182                 fprintf(stderr, " \"%s\"...", substring.utf8().data());
1183             } else
1184                 fprintf(stderr, " \"%s\"", value.utf8().data());
1185         }
1186     }
1187     if (is<RenderBoxModelObject>(*this)) {
1188         auto& renderer = downcast<RenderBoxModelObject>(*this);
1189         if (renderer.hasContinuation())
1190             fprintf(stderr, " continuation->(%p)", renderer.continuation());
1191     }
1192     showRegionsInformation();
1193     if (needsLayout()) {
1194         fprintf(stderr, " layout->");
1195         if (selfNeedsLayout())
1196             fprintf(stderr, "[self]");
1197         if (normalChildNeedsLayout())
1198             fprintf(stderr, "[normal child]");
1199         if (posChildNeedsLayout())
1200             fprintf(stderr, "[positioned child]");
1201         if (needsSimplifiedNormalFlowLayout())
1202             fprintf(stderr, "[simplified]");
1203         if (needsPositionedMovementLayout())
1204             fprintf(stderr, "[positioned movement]");
1205     }
1206     fprintf(stderr, "\n");
1207 }
1208
1209 void RenderObject::showRenderSubTreeAndMark(const RenderObject* markedObject, int depth) const
1210 {
1211     showRenderObject(markedObject == this, depth);
1212     if (is<RenderBlockFlow>(*this))
1213         downcast<RenderBlockFlow>(*this).showLineTreeAndMark(nullptr, depth + 1);
1214
1215     for (const RenderObject* child = firstChildSlow(); child; child = child->nextSibling())
1216         child->showRenderSubTreeAndMark(markedObject, depth + 1);
1217 }
1218
1219 #endif // NDEBUG
1220
1221 SelectionSubtreeRoot& RenderObject::selectionRoot() const
1222 {
1223     RenderFlowThread* flowThread = flowThreadContainingBlock();
1224     if (!flowThread)
1225         return view();
1226
1227     if (is<RenderNamedFlowThread>(*flowThread))
1228         return downcast<RenderNamedFlowThread>(*flowThread);
1229     if (is<RenderMultiColumnFlowThread>(*flowThread)) {
1230         if (!flowThread->containingBlock())
1231             return view();
1232         return flowThread->containingBlock()->selectionRoot();
1233     }
1234     ASSERT_NOT_REACHED();
1235     return view();
1236 }
1237
1238 void RenderObject::selectionStartEnd(unsigned& spos, unsigned& epos) const
1239 {
1240     selectionRoot().selectionData().selectionStartEndPositions(spos, epos);
1241 }
1242
1243 FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, MapCoordinatesFlags mode, bool* wasFixed) const
1244 {
1245     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
1246     mapLocalToContainer(nullptr, transformState, mode | ApplyContainerFlip, wasFixed);
1247     transformState.flatten();
1248     
1249     return transformState.lastPlanarPoint();
1250 }
1251
1252 FloatPoint RenderObject::absoluteToLocal(const FloatPoint& containerPoint, MapCoordinatesFlags mode) const
1253 {
1254     TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint);
1255     mapAbsoluteToLocalPoint(mode, transformState);
1256     transformState.flatten();
1257     
1258     return transformState.lastPlanarPoint();
1259 }
1260
1261 FloatQuad RenderObject::absoluteToLocalQuad(const FloatQuad& quad, MapCoordinatesFlags mode) const
1262 {
1263     TransformState transformState(TransformState::UnapplyInverseTransformDirection, quad.boundingBox().center(), quad);
1264     mapAbsoluteToLocalPoint(mode, transformState);
1265     transformState.flatten();
1266     return transformState.lastPlanarQuad();
1267 }
1268
1269 void RenderObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
1270 {
1271     if (repaintContainer == this)
1272         return;
1273
1274     auto* parent = this->parent();
1275     if (!parent)
1276         return;
1277
1278     // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
1279     LayoutPoint centerPoint(transformState.mappedPoint());
1280     if (mode & ApplyContainerFlip && is<RenderBox>(*parent)) {
1281         if (parent->style().isFlippedBlocksWritingMode())
1282             transformState.move(downcast<RenderBox>(parent)->flipForWritingMode(LayoutPoint(transformState.mappedPoint())) - centerPoint);
1283         mode &= ~ApplyContainerFlip;
1284     }
1285
1286     if (is<RenderBox>(*parent))
1287         transformState.move(-toLayoutSize(downcast<RenderBox>(*parent).scrollPosition()));
1288
1289     parent->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed);
1290 }
1291
1292 const RenderObject* RenderObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
1293 {
1294     ASSERT_UNUSED(ancestorToStopAt, ancestorToStopAt != this);
1295
1296     auto* container = parent();
1297     if (!container)
1298         return nullptr;
1299
1300     // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
1301     LayoutSize offset;
1302     if (is<RenderBox>(*container))
1303         offset = -toLayoutSize(downcast<RenderBox>(*container).scrollPosition());
1304
1305     geometryMap.push(this, offset, false);
1306     
1307     return container;
1308 }
1309
1310 void RenderObject::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
1311 {
1312     if (auto* parent = this->parent()) {
1313         parent->mapAbsoluteToLocalPoint(mode, transformState);
1314         if (is<RenderBox>(*parent))
1315             transformState.move(toLayoutSize(downcast<RenderBox>(*parent).scrollPosition()));
1316     }
1317 }
1318
1319 bool RenderObject::shouldUseTransformFromContainer(const RenderObject* containerObject) const
1320 {
1321 #if ENABLE(3D_TRANSFORMS)
1322     return hasTransform() || (containerObject && containerObject->style().hasPerspective());
1323 #else
1324     UNUSED_PARAM(containerObject);
1325     return hasTransform();
1326 #endif
1327 }
1328
1329 void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const LayoutSize& offsetInContainer, TransformationMatrix& transform) const
1330 {
1331     transform.makeIdentity();
1332     transform.translate(offsetInContainer.width(), offsetInContainer.height());
1333     RenderLayer* layer;
1334     if (hasLayer() && (layer = downcast<RenderLayerModelObject>(*this).layer()) && layer->transform())
1335         transform.multiply(layer->currentTransform());
1336     
1337 #if ENABLE(3D_TRANSFORMS)
1338     if (containerObject && containerObject->hasLayer() && containerObject->style().hasPerspective()) {
1339         // Perpsective on the container affects us, so we have to factor it in here.
1340         ASSERT(containerObject->hasLayer());
1341         FloatPoint perspectiveOrigin = downcast<RenderLayerModelObject>(*containerObject).layer()->perspectiveOrigin();
1342
1343         TransformationMatrix perspectiveMatrix;
1344         perspectiveMatrix.applyPerspective(containerObject->style().perspective());
1345         
1346         transform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0);
1347         transform = perspectiveMatrix * transform;
1348         transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0);
1349     }
1350 #else
1351     UNUSED_PARAM(containerObject);
1352 #endif
1353 }
1354
1355 FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const
1356 {
1357     // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
1358     // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
1359     TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), localQuad);
1360     mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip, wasFixed);
1361     transformState.flatten();
1362     
1363     return transformState.lastPlanarQuad();
1364 }
1365
1366 FloatPoint RenderObject::localToContainerPoint(const FloatPoint& localPoint, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const
1367 {
1368     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
1369     mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip, wasFixed);
1370     transformState.flatten();
1371
1372     return transformState.lastPlanarPoint();
1373 }
1374
1375 LayoutSize RenderObject::offsetFromContainer(RenderElement& container, const LayoutPoint&, bool* offsetDependsOnPoint) const
1376 {
1377     ASSERT(&container == this->container());
1378
1379     LayoutSize offset;
1380     if (is<RenderBox>(container))
1381         offset -= toLayoutSize(downcast<RenderBox>(container).scrollPosition());
1382
1383     if (offsetDependsOnPoint)
1384         *offsetDependsOnPoint = is<RenderFlowThread>(container);
1385
1386     return offset;
1387 }
1388
1389 LayoutSize RenderObject::offsetFromAncestorContainer(RenderElement& container) const
1390 {
1391     LayoutSize offset;
1392     LayoutPoint referencePoint;
1393     const RenderObject* currContainer = this;
1394     do {
1395         RenderElement* nextContainer = currContainer->container();
1396         ASSERT(nextContainer);  // This means we reached the top without finding container.
1397         if (!nextContainer)
1398             break;
1399         ASSERT(!currContainer->hasTransform());
1400         LayoutSize currentOffset = currContainer->offsetFromContainer(*nextContainer, referencePoint);
1401         offset += currentOffset;
1402         referencePoint.move(currentOffset);
1403         currContainer = nextContainer;
1404     } while (currContainer != &container);
1405
1406     return offset;
1407 }
1408
1409 LayoutRect RenderObject::localCaretRect(InlineBox*, unsigned, LayoutUnit* extraWidthToEndOfLine)
1410 {
1411     if (extraWidthToEndOfLine)
1412         *extraWidthToEndOfLine = 0;
1413
1414     return LayoutRect();
1415 }
1416
1417 bool RenderObject::isRooted() const
1418 {
1419     return isDescendantOf(&view());
1420 }
1421
1422 static inline RenderElement* containerForElement(const RenderObject& renderer, const RenderLayerModelObject* repaintContainer, bool* repaintContainerSkipped)
1423 {
1424     // This method is extremely similar to containingBlock(), but with a few notable
1425     // exceptions.
1426     // (1) For normal flow elements, it just returns the parent.
1427     // (2) For absolute positioned elements, it will return a relative positioned inline, while
1428     // containingBlock() skips to the non-anonymous containing block.
1429     // This does mean that computePositionedLogicalWidth and computePositionedLogicalHeight have to use container().
1430     EPosition pos = renderer.style().position();
1431     auto* parent = renderer.parent();
1432     if (is<RenderText>(renderer) || (pos != FixedPosition && pos != AbsolutePosition))
1433         return parent;
1434     for (; parent && (pos == AbsolutePosition ? !parent->canContainAbsolutelyPositionedObjects() : !parent->canContainFixedPositionObjects()); parent = parent->parent()) {
1435         if (repaintContainerSkipped && repaintContainer == parent)
1436             *repaintContainerSkipped = true;
1437     }
1438     return parent;
1439 }
1440
1441 RenderElement* RenderObject::container() const
1442 {
1443     return containerForElement(*this, nullptr, nullptr);
1444 }
1445
1446 RenderElement* RenderObject::container(const RenderLayerModelObject* repaintContainer, bool& repaintContainerSkipped) const
1447 {
1448     repaintContainerSkipped = false;
1449     return containerForElement(*this, repaintContainer, &repaintContainerSkipped);
1450 }
1451
1452 bool RenderObject::isSelectionBorder() const
1453 {
1454     SelectionState st = selectionState();
1455     return st == SelectionStart
1456         || st == SelectionEnd
1457         || st == SelectionBoth
1458         || view().selectionUnsplitStart() == this
1459         || view().selectionUnsplitEnd() == this;
1460 }
1461
1462 void RenderObject::willBeDestroyed()
1463 {
1464     // For accessibility management, notify the parent of the imminent change to its child set.
1465     // We do it now, before remove(), while the parent pointer is still available.
1466     if (AXObjectCache* cache = document().existingAXObjectCache())
1467         cache->childrenChanged(this->parent());
1468
1469     removeFromParent();
1470
1471     ASSERT(documentBeingDestroyed() || !is<RenderElement>(*this) || !view().frameView().hasSlowRepaintObject(downcast<RenderElement>(*this)));
1472
1473     // The remove() call above may invoke axObjectCache()->childrenChanged() on the parent, which may require the AX render
1474     // object for this renderer. So we remove the AX render object now, after the renderer is removed.
1475     if (AXObjectCache* cache = document().existingAXObjectCache())
1476         cache->remove(this);
1477
1478     // FIXME: Would like to do this in RenderBoxModelObject, but the timing is so complicated that this can't easily
1479     // be moved into RenderBoxModelObject::destroy.
1480     if (hasLayer()) {
1481         setHasLayer(false);
1482         downcast<RenderLayerModelObject>(*this).destroyLayer();
1483     }
1484
1485     removeRareData();
1486 }
1487
1488 void RenderObject::insertedIntoTree()
1489 {
1490     // FIXME: We should ASSERT(isRooted()) here but generated content makes some out-of-order insertion.
1491
1492     if (!isFloating() && parent()->childrenInline())
1493         parent()->dirtyLinesFromChangedChild(*this);
1494
1495     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
1496         flowThread->flowThreadDescendantInserted(*this);
1497 }
1498
1499 void RenderObject::willBeRemovedFromTree()
1500 {
1501     // FIXME: We should ASSERT(isRooted()) but we have some out-of-order removals which would need to be fixed first.
1502     // Update cached boundaries in SVG renderers, if a child is removed.
1503     parent()->setNeedsBoundariesUpdate();
1504 }
1505
1506 void RenderObject::destroyAndCleanupAnonymousWrappers()
1507 {
1508     // If the tree is destroyed, there is no need for a clean-up phase.
1509     if (documentBeingDestroyed()) {
1510         destroy();
1511         return;
1512     }
1513
1514     auto* destroyRoot = this;
1515     auto* destroyRootParent = destroyRoot->parent();
1516     while (destroyRootParent && destroyRootParent->isAnonymous()) {
1517         if (!destroyRootParent->isTableCell() && !destroyRootParent->isTableRow()
1518             && !destroyRootParent->isTableCaption() && !destroyRootParent->isTableSection() && !destroyRootParent->isTable())
1519             break;
1520         // single child?
1521         if (!(destroyRootParent->firstChild() == destroyRoot && destroyRootParent->lastChild() == destroyRoot))
1522             break;
1523         destroyRoot = destroyRootParent;
1524         destroyRootParent = destroyRootParent->parent();
1525     }
1526
1527     if (is<RenderTableRow>(*destroyRoot)) {
1528         downcast<RenderTableRow>(*destroyRoot).destroyAndCollapseAnonymousSiblingRows();
1529         return;
1530     }
1531
1532     destroyRoot->destroy();
1533     // WARNING: |this| is deleted here.
1534 }
1535
1536 void RenderObject::destroy()
1537 {
1538     m_bitfields.setBeingDestroyed(true);
1539
1540 #if PLATFORM(IOS)
1541     if (hasLayer())
1542         downcast<RenderBoxModelObject>(*this).layer()->willBeDestroyed();
1543 #endif
1544
1545     willBeDestroyed();
1546     if (is<RenderWidget>(*this)) {
1547         downcast<RenderWidget>(*this).deref();
1548         return;
1549     }
1550     delete this;
1551 }
1552
1553 VisiblePosition RenderObject::positionForPoint(const LayoutPoint&, const RenderRegion*)
1554 {
1555     return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
1556 }
1557
1558 void RenderObject::updateDragState(bool dragOn)
1559 {
1560     bool valueChanged = (dragOn != isDragging());
1561     setIsDragging(dragOn);
1562
1563     if (!is<RenderElement>(*this))
1564         return;
1565     auto& renderElement = downcast<RenderElement>(*this);
1566
1567     if (valueChanged && renderElement.element() && (style().affectedByDrag() || renderElement.element()->childrenAffectedByDrag()))
1568         renderElement.element()->invalidateStyleForSubtree();
1569
1570     for (auto& child : childrenOfType<RenderObject>(renderElement))
1571         child.updateDragState(dragOn);
1572 }
1573
1574 bool RenderObject::isComposited() const
1575 {
1576     return hasLayer() && downcast<RenderLayerModelObject>(*this).layer()->isComposited();
1577 }
1578
1579 bool RenderObject::isAnonymousInlineBlock() const
1580 {
1581     return isAnonymous() && style().display() == INLINE_BLOCK && style().styleType() == NOPSEUDO && isRenderBlockFlow() && !isRubyRun() && !isRubyBase() && !isRuby(parent());
1582 }
1583
1584 bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter hitTestFilter)
1585 {
1586     bool inside = false;
1587     if (hitTestFilter != HitTestSelf) {
1588         // First test the foreground layer (lines and inlines).
1589         inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestForeground);
1590
1591         // Test floats next.
1592         if (!inside)
1593             inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestFloat);
1594
1595         // Finally test to see if the mouse is in the background (within a child block's background).
1596         if (!inside)
1597             inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestChildBlockBackgrounds);
1598     }
1599
1600     // See if the mouse is inside us but not any of our descendants
1601     if (hitTestFilter != HitTestDescendants && !inside)
1602         inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestBlockBackground);
1603
1604     return inside;
1605 }
1606
1607 void RenderObject::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
1608 {
1609     if (result.innerNode())
1610         return;
1611
1612     Node* node = this->node();
1613
1614     // If we hit the anonymous renderers inside generated content we should
1615     // actually hit the generated content so walk up to the PseudoElement.
1616     if (!node && parent() && parent()->isBeforeOrAfterContent()) {
1617         for (auto* renderer = parent(); renderer && !node; renderer = renderer->parent())
1618             node = renderer->element();
1619     }
1620
1621     if (node) {
1622         result.setInnerNode(node);
1623         if (!result.innerNonSharedNode())
1624             result.setInnerNonSharedNode(node);
1625         result.setLocalPoint(point);
1626     }
1627 }
1628
1629 bool RenderObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& /*locationInContainer*/, const LayoutPoint& /*accumulatedOffset*/, HitTestAction)
1630 {
1631     return false;
1632 }
1633
1634 int RenderObject::innerLineHeight() const
1635 {
1636     return style().computedLineHeight();
1637 }
1638
1639 #if ENABLE(DASHBOARD_SUPPORT)
1640 void RenderObject::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
1641 {
1642     // Convert the style regions to absolute coordinates.
1643     if (style().visibility() != VISIBLE || !is<RenderBox>(*this))
1644         return;
1645     
1646     auto& box = downcast<RenderBox>(*this);
1647     FloatPoint absPos = localToAbsolute();
1648
1649     const Vector<StyleDashboardRegion>& styleRegions = style().dashboardRegions();
1650     for (const auto& styleRegion : styleRegions) {
1651         LayoutUnit w = box.width();
1652         LayoutUnit h = box.height();
1653
1654         AnnotatedRegionValue region;
1655         region.label = styleRegion.label;
1656         region.bounds = LayoutRect(styleRegion.offset.left().value(),
1657                                    styleRegion.offset.top().value(),
1658                                    w - styleRegion.offset.left().value() - styleRegion.offset.right().value(),
1659                                    h - styleRegion.offset.top().value() - styleRegion.offset.bottom().value());
1660         region.type = styleRegion.type;
1661
1662         region.clip = computeAbsoluteRepaintRect(region.bounds);
1663         if (region.clip.height() < 0) {
1664             region.clip.setHeight(0);
1665             region.clip.setWidth(0);
1666         }
1667
1668         region.bounds.setX(absPos.x() + styleRegion.offset.left().value());
1669         region.bounds.setY(absPos.y() + styleRegion.offset.top().value());
1670
1671         regions.append(region);
1672     }
1673 }
1674
1675 void RenderObject::collectAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
1676 {
1677     // RenderTexts don't have their own style, they just use their parent's style,
1678     // so we don't want to include them.
1679     if (is<RenderText>(*this))
1680         return;
1681
1682     addAnnotatedRegions(regions);
1683     for (RenderObject* current = downcast<RenderElement>(*this).firstChild(); current; current = current->nextSibling())
1684         current->collectAnnotatedRegions(regions);
1685 }
1686 #endif
1687
1688 int RenderObject::caretMinOffset() const
1689 {
1690     return 0;
1691 }
1692
1693 int RenderObject::caretMaxOffset() const
1694 {
1695     if (isReplaced())
1696         return node() ? std::max(1U, node()->countChildNodes()) : 1;
1697     if (isHR())
1698         return 1;
1699     return 0;
1700 }
1701
1702 int RenderObject::previousOffset(int current) const
1703 {
1704     return current - 1;
1705 }
1706
1707 int RenderObject::previousOffsetForBackwardDeletion(int current) const
1708 {
1709     return current - 1;
1710 }
1711
1712 int RenderObject::nextOffset(int current) const
1713 {
1714     return current + 1;
1715 }
1716
1717 void RenderObject::adjustRectForOutlineAndShadow(LayoutRect& rect) const
1718 {
1719     LayoutUnit outlineSize = outlineStyleForRepaint().outlineSize();
1720     if (const ShadowData* boxShadow = style().boxShadow()) {
1721         boxShadow->adjustRectForShadow(rect, outlineSize);
1722         return;
1723     }
1724     rect.inflate(outlineSize);
1725 }
1726
1727 void RenderObject::imageChanged(CachedImage* image, const IntRect* rect)
1728 {
1729     imageChanged(static_cast<WrappedImagePtr>(image), rect);
1730 }
1731
1732 RenderBoxModelObject* RenderObject::offsetParent() const
1733 {
1734     // If any of the following holds true return null and stop this algorithm:
1735     // A is the root element.
1736     // A is the HTML body element.
1737     // The computed value of the position property for element A is fixed.
1738     if (isDocumentElementRenderer() || isBody() || (isOutOfFlowPositioned() && style().position() == FixedPosition))
1739         return nullptr;
1740
1741     // If A is an area HTML element which has a map HTML element somewhere in the ancestor
1742     // chain return the nearest ancestor map HTML element and stop this algorithm.
1743     // FIXME: Implement!
1744     
1745     // Return the nearest ancestor element of A for which at least one of the following is
1746     // true and stop this algorithm if such an ancestor is found:
1747     //     * The computed value of the position property is not static.
1748     //     * It is the HTML body element.
1749     //     * The computed value of the position property of A is static and the ancestor
1750     //       is one of the following HTML elements: td, th, or table.
1751     //     * Our own extension: if there is a difference in the effective zoom
1752
1753     bool skipTables = isPositioned();
1754     float currZoom = style().effectiveZoom();
1755     auto current = parent();
1756     while (current && (!current->element() || (!current->isPositioned() && !current->isBody())) && !is<RenderNamedFlowThread>(*current)) {
1757         Element* element = current->element();
1758         if (!skipTables && element && (is<HTMLTableElement>(*element) || is<HTMLTableCellElement>(*element)))
1759             break;
1760  
1761         float newZoom = current->style().effectiveZoom();
1762         if (currZoom != newZoom)
1763             break;
1764         currZoom = newZoom;
1765         current = current->parent();
1766     }
1767     
1768     // CSS regions specification says that region flows should return the body element as their offsetParent.
1769     if (is<RenderNamedFlowThread>(current)) {
1770         auto* body = document().bodyOrFrameset();
1771         current = body ? body->renderer() : nullptr;
1772     }
1773     
1774     return is<RenderBoxModelObject>(current) ? downcast<RenderBoxModelObject>(current) : nullptr;
1775 }
1776
1777 VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity) const
1778 {
1779     // If this is a non-anonymous renderer in an editable area, then it's simple.
1780     if (Node* node = nonPseudoNode()) {
1781         if (!node->hasEditableStyle()) {
1782             // If it can be found, we prefer a visually equivalent position that is editable. 
1783             Position position = createLegacyEditingPosition(node, offset);
1784             Position candidate = position.downstream(CanCrossEditingBoundary);
1785             if (candidate.deprecatedNode()->hasEditableStyle())
1786                 return VisiblePosition(candidate, affinity);
1787             candidate = position.upstream(CanCrossEditingBoundary);
1788             if (candidate.deprecatedNode()->hasEditableStyle())
1789                 return VisiblePosition(candidate, affinity);
1790         }
1791         // FIXME: Eliminate legacy editing positions
1792         return VisiblePosition(createLegacyEditingPosition(node, offset), affinity);
1793     }
1794
1795     // We don't want to cross the boundary between editable and non-editable
1796     // regions of the document, but that is either impossible or at least
1797     // extremely unlikely in any normal case because we stop as soon as we
1798     // find a single non-anonymous renderer.
1799
1800     // Find a nearby non-anonymous renderer.
1801     const RenderObject* child = this;
1802     while (const auto parent = child->parent()) {
1803         // Find non-anonymous content after.
1804         const RenderObject* renderer = child;
1805         while ((renderer = renderer->nextInPreOrder(parent))) {
1806             if (Node* node = renderer->nonPseudoNode())
1807                 return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
1808         }
1809
1810         // Find non-anonymous content before.
1811         renderer = child;
1812         while ((renderer = renderer->previousInPreOrder())) {
1813             if (renderer == parent)
1814                 break;
1815             if (Node* node = renderer->nonPseudoNode())
1816                 return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
1817         }
1818
1819         // Use the parent itself unless it too is anonymous.
1820         if (Element* element = parent->nonPseudoElement())
1821             return VisiblePosition(firstPositionInOrBeforeNode(element), DOWNSTREAM);
1822
1823         // Repeat at the next level up.
1824         child = parent;
1825     }
1826
1827     // Everything was anonymous. Give up.
1828     return VisiblePosition();
1829 }
1830
1831 VisiblePosition RenderObject::createVisiblePosition(const Position& position) const
1832 {
1833     if (position.isNotNull())
1834         return VisiblePosition(position);
1835
1836     ASSERT(!node());
1837     return createVisiblePosition(0, DOWNSTREAM);
1838 }
1839
1840 CursorDirective RenderObject::getCursor(const LayoutPoint&, Cursor&) const
1841 {
1842     return SetCursorBasedOnStyle;
1843 }
1844
1845 bool RenderObject::canUpdateSelectionOnRootLineBoxes()
1846 {
1847     if (needsLayout())
1848         return false;
1849
1850     RenderBlock* containingBlock = this->containingBlock();
1851     return containingBlock ? !containingBlock->needsLayout() : true;
1852 }
1853
1854 // We only create "generated" child renderers like one for first-letter if:
1855 // - the firstLetterBlock can have children in the DOM and
1856 // - the block doesn't have any special assumption on its text children.
1857 // This correctly prevents form controls from having such renderers.
1858 bool RenderObject::canHaveGeneratedChildren() const
1859 {
1860     return canHaveChildren();
1861 }
1862
1863 Node* RenderObject::generatingPseudoHostElement() const
1864 {
1865     return downcast<PseudoElement>(*node()).hostElement();
1866 }
1867
1868 void RenderObject::setNeedsBoundariesUpdate()
1869 {
1870     if (auto renderer = parent())
1871         renderer->setNeedsBoundariesUpdate();
1872 }
1873
1874 FloatRect RenderObject::objectBoundingBox() const
1875 {
1876     ASSERT_NOT_REACHED();
1877     return FloatRect();
1878 }
1879
1880 FloatRect RenderObject::strokeBoundingBox() const
1881 {
1882     ASSERT_NOT_REACHED();
1883     return FloatRect();
1884 }
1885
1886 // Returns the smallest rectangle enclosing all of the painted content
1887 // respecting clipping, masking, filters, opacity, stroke-width and markers
1888 FloatRect RenderObject::repaintRectInLocalCoordinates() const
1889 {
1890     ASSERT_NOT_REACHED();
1891     return FloatRect();
1892 }
1893
1894 AffineTransform RenderObject::localTransform() const
1895 {
1896     static const AffineTransform identity;
1897     return identity;
1898 }
1899
1900 const AffineTransform& RenderObject::localToParentTransform() const
1901 {
1902     static const AffineTransform identity;
1903     return identity;
1904 }
1905
1906 bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction)
1907 {
1908     ASSERT_NOT_REACHED();
1909     return false;
1910 }
1911
1912 RenderNamedFlowFragment* RenderObject::currentRenderNamedFlowFragment() const
1913 {
1914     RenderFlowThread* flowThread = flowThreadContainingBlock();
1915     if (!is<RenderNamedFlowThread>(flowThread))
1916         return nullptr;
1917
1918     // FIXME: Once regions are fully integrated with the compositing system we should uncomment this assert.
1919     // This assert needs to be disabled because it's possible to ask for the ancestor clipping rectangle of
1920     // a layer without knowing the containing region in advance.
1921     // ASSERT(flowThread->currentRegion() && flowThread->currentRegion()->isRenderNamedFlowFragment());
1922
1923     return downcast<RenderNamedFlowFragment>(flowThread->currentRegion());
1924 }
1925
1926 RenderFlowThread* RenderObject::locateFlowThreadContainingBlock() const
1927 {
1928     RenderBlock* containingBlock = this->containingBlock();
1929     return containingBlock ? containingBlock->flowThreadContainingBlock() : nullptr;
1930 }
1931
1932 void RenderObject::calculateBorderStyleColor(const EBorderStyle& style, const BoxSide& side, Color& color)
1933 {
1934     ASSERT(style == INSET || style == OUTSET);
1935     // This values were derived empirically.
1936     const RGBA32 baseDarkColor = 0xFF202020;
1937     const RGBA32 baseLightColor = 0xFFEBEBEB;
1938     enum Operation { Darken, Lighten };
1939
1940     Operation operation = (side == BSTop || side == BSLeft) == (style == INSET) ? Darken : Lighten;
1941
1942     // Here we will darken the border decoration color when needed. This will yield a similar behavior as in FF.
1943     if (operation == Darken) {
1944         if (differenceSquared(color, Color::black) > differenceSquared(baseDarkColor, Color::black))
1945             color = color.dark();
1946     } else {
1947         if (differenceSquared(color, Color::white) > differenceSquared(baseLightColor, Color::white))
1948             color = color.light();
1949     }
1950 }
1951
1952 void RenderObject::setIsDragging(bool isDragging)
1953 {
1954     if (isDragging || hasRareData())
1955         ensureRareData().setIsDragging(isDragging);
1956 }
1957
1958 void RenderObject::setHasReflection(bool hasReflection)
1959 {
1960     if (hasReflection || hasRareData())
1961         ensureRareData().setHasReflection(hasReflection);
1962 }
1963
1964 void RenderObject::setIsRenderFlowThread(bool isFlowThread)
1965 {
1966     if (isFlowThread || hasRareData())
1967         ensureRareData().setIsRenderFlowThread(isFlowThread);
1968 }
1969
1970 void RenderObject::setHasOutlineAutoAncestor(bool hasOutlineAutoAncestor)
1971 {
1972     if (hasOutlineAutoAncestor || hasRareData())
1973         ensureRareData().setHasOutlineAutoAncestor(hasOutlineAutoAncestor);
1974 }
1975
1976 void RenderObject::setIsRegisteredForVisibleInViewportCallback(bool registered)
1977 {
1978     if (registered || hasRareData())
1979         ensureRareData().setIsRegisteredForVisibleInViewportCallback(registered);
1980 }
1981
1982 void RenderObject::setVisibleInViewportState(VisibleInViewportState visible)
1983 {
1984     if (visible != VisibilityUnknown || hasRareData())
1985         ensureRareData().setVisibleInViewportState(visible);
1986 }
1987
1988 RenderObject::RareDataMap& RenderObject::rareDataMap()
1989 {
1990     static NeverDestroyed<RareDataMap> map;
1991     return map;
1992 }
1993
1994 const RenderObject::RenderObjectRareData& RenderObject::rareData() const
1995 {
1996     ASSERT(hasRareData());
1997     return *rareDataMap().get(this);
1998 }
1999
2000 RenderObject::RenderObjectRareData& RenderObject::ensureRareData()
2001 {
2002     setHasRareData(true);
2003     return *rareDataMap().ensure(this, [] { return std::make_unique<RenderObjectRareData>(); }).iterator->value;
2004 }
2005
2006 void RenderObject::removeRareData()
2007 {
2008     rareDataMap().remove(this);
2009     setHasRareData(false);
2010 }
2011
2012 #if ENABLE(TREE_DEBUGGING)
2013
2014 void printRenderTreeForLiveDocuments()
2015 {
2016     for (const auto* document : Document::allDocuments()) {
2017         if (!document->renderView())
2018             continue;
2019         if (document->frame() && document->frame()->isMainFrame())
2020             fprintf(stderr, "----------------------main frame--------------------------\n");
2021         fprintf(stderr, "%s", document->url().string().utf8().data());
2022         showRenderTree(document->renderView());
2023     }
2024 }
2025
2026 void printLayerTreeForLiveDocuments()
2027 {
2028     for (const auto* document : Document::allDocuments()) {
2029         if (!document->renderView())
2030             continue;
2031         if (document->frame() && document->frame()->isMainFrame())
2032             fprintf(stderr, "----------------------main frame--------------------------\n");
2033         fprintf(stderr, "%s", document->url().string().utf8().data());
2034         showLayerTree(document->renderView());
2035     }
2036 }
2037
2038 #endif // ENABLE(TREE_DEBUGGING)
2039
2040 } // namespace WebCore
2041
2042 #if ENABLE(TREE_DEBUGGING)
2043
2044 void showNodeTree(const WebCore::RenderObject* object)
2045 {
2046     if (!object)
2047         return;
2048     object->showNodeTreeForThis();
2049 }
2050
2051 void showLineTree(const WebCore::RenderObject* object)
2052 {
2053     if (!object)
2054         return;
2055     object->showLineTreeForThis();
2056 }
2057
2058 void showRenderTree(const WebCore::RenderObject* object)
2059 {
2060     if (!object)
2061         return;
2062     object->showRenderTreeForThis();
2063 }
2064
2065 #endif