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