Provide a viewport parameter to disable clipping to the safe area
[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 page().theme();
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         if (!view.frameView().clipToSafeArea())
902             shouldClipToLayer = false;
903     }
904
905     if (view().usesCompositing()) {
906         ASSERT(repaintContainer->isComposited());
907         repaintContainer->layer()->setBackingNeedsRepaintInRect(r, shouldClipToLayer ? GraphicsLayer::ClipToLayer : GraphicsLayer::DoNotClipToLayer);
908     }
909 }
910
911 void RenderObject::repaint() const
912 {
913     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
914     if (!isRooted())
915         return;
916
917     const RenderView& view = this->view();
918     if (view.printing())
919         return;
920
921     RenderLayerModelObject* repaintContainer = containerForRepaint();
922     repaintUsingContainer(repaintContainer, clippedOverflowRectForRepaint(repaintContainer));
923 }
924
925 void RenderObject::repaintRectangle(const LayoutRect& r, bool shouldClipToLayer) const
926 {
927     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
928     if (!isRooted())
929         return;
930
931     const RenderView& view = this->view();
932     if (view.printing())
933         return;
934
935     LayoutRect dirtyRect(r);
936     // FIXME: layoutDelta needs to be applied in parts before/after transforms and
937     // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
938     dirtyRect.move(view.layoutDelta());
939
940     RenderLayerModelObject* repaintContainer = containerForRepaint();
941     repaintUsingContainer(repaintContainer, computeRectForRepaint(dirtyRect, repaintContainer), shouldClipToLayer);
942 }
943
944 void RenderObject::repaintSlowRepaintObject() const
945 {
946     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
947     if (!isRooted())
948         return;
949
950     const RenderView& view = this->view();
951     if (view.printing())
952         return;
953
954     const RenderLayerModelObject* repaintContainer = containerForRepaint();
955
956     bool shouldClipToLayer = true;
957     IntRect repaintRect;
958     // If this is the root background, we need to check if there is an extended background rect. If
959     // there is, then we should not allow painting to clip to the layer size.
960     if (isDocumentElementRenderer() || isBody()) {
961         shouldClipToLayer = !view.frameView().hasExtendedBackgroundRectForPainting();
962         repaintRect = snappedIntRect(view.backgroundRect());
963     } else
964         repaintRect = snappedIntRect(clippedOverflowRectForRepaint(repaintContainer));
965
966     repaintUsingContainer(repaintContainer, repaintRect, shouldClipToLayer);
967 }
968
969 IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
970 {
971     return snappedIntRect(absoluteClippedOverflowRect());
972 }
973     
974 LayoutRect RenderObject::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
975 {
976     LayoutRect r(clippedOverflowRectForRepaint(repaintContainer));
977     r.inflate(outlineWidth);
978     return r;
979 }
980
981 LayoutRect RenderObject::clippedOverflowRectForRepaint(const RenderLayerModelObject*) const
982 {
983     ASSERT_NOT_REACHED();
984     return LayoutRect();
985 }
986
987 LayoutRect RenderObject::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const
988 {
989     if (repaintContainer == this)
990         return rect;
991
992     auto* parent = this->parent();
993     if (!parent)
994         return rect;
995
996     LayoutRect adjustedRect = rect;
997     if (parent->hasOverflowClip()) {
998         downcast<RenderBox>(*parent).applyCachedClipAndScrollPositionForRepaint(adjustedRect);
999         if (adjustedRect.isEmpty())
1000             return adjustedRect;
1001     }
1002     return parent->computeRectForRepaint(adjustedRect, repaintContainer, context);
1003 }
1004
1005 FloatRect RenderObject::computeFloatRectForRepaint(const FloatRect&, const RenderLayerModelObject*, bool) const
1006 {
1007     ASSERT_NOT_REACHED();
1008     return FloatRect();
1009 }
1010
1011 #if ENABLE(TREE_DEBUGGING)
1012
1013 static void showRenderTreeLegend()
1014 {
1015     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");
1016 }
1017
1018 void RenderObject::showNodeTreeForThis() const
1019 {
1020     if (!node())
1021         return;
1022     node()->showTreeForThis();
1023 }
1024
1025 void RenderObject::showRenderTreeForThis() const
1026 {
1027     const WebCore::RenderObject* root = this;
1028     while (root->parent())
1029         root = root->parent();
1030     showRenderTreeLegend();
1031     root->showRenderSubTreeAndMark(this, 1);
1032 }
1033
1034 void RenderObject::showLineTreeForThis() const
1035 {
1036     if (!is<RenderBlockFlow>(*this))
1037         return;
1038     showRenderTreeLegend();
1039     showRenderObject(false, 1);
1040     downcast<RenderBlockFlow>(*this).showLineTreeAndMark(nullptr, 2);
1041 }
1042
1043 static const RenderFlowThread* flowThreadContainingBlockFromRenderer(const RenderObject* renderer)
1044 {
1045     if (!renderer)
1046         return nullptr;
1047
1048     if (renderer->flowThreadState() == RenderObject::NotInsideFlowThread)
1049         return nullptr;
1050
1051     if (is<RenderFlowThread>(*renderer))
1052         return downcast<RenderFlowThread>(renderer);
1053
1054     if (is<RenderBlock>(*renderer))
1055         return downcast<RenderBlock>(*renderer).cachedFlowThreadContainingBlock();
1056
1057     return nullptr;
1058 }
1059
1060 void RenderObject::showRegionsInformation() const
1061 {
1062     const RenderFlowThread* ftcb = flowThreadContainingBlockFromRenderer(this);
1063
1064     if (!ftcb) {
1065         // Only the boxes have region range information.
1066         // Try to get the flow thread containing block information
1067         // from the containing block of this box.
1068         if (is<RenderBox>(*this))
1069             ftcb = flowThreadContainingBlockFromRenderer(containingBlock());
1070     }
1071
1072     if (!ftcb)
1073         return;
1074
1075     RenderRegion* startRegion = nullptr;
1076     RenderRegion* endRegion = nullptr;
1077     ftcb->getRegionRangeForBox(downcast<RenderBox>(this), startRegion, endRegion);
1078     fprintf(stderr, " [Rs:%p Re:%p]", startRegion, endRegion);
1079 }
1080
1081 void RenderObject::showRenderObject(bool mark, int depth) const
1082 {
1083     if (isInlineBlockOrInlineTable())
1084         fputc('N', stderr);
1085     else if (isInline())
1086         fputc('I', stderr);
1087     else
1088         fputc('B', stderr);
1089     
1090     if (isPositioned()) {
1091         if (isRelPositioned())
1092             fputc('R', stderr);
1093         else if (isStickyPositioned())
1094             fputc('K', stderr);
1095         else if (isOutOfFlowPositioned()) {
1096             if (style().position() == AbsolutePosition)
1097                 fputc('A', stderr);
1098             else
1099                 fputc('X', stderr);
1100         }
1101     } else
1102         fputc('-', stderr);
1103
1104     if (isFloating())
1105         fputc('F', stderr);
1106     else
1107         fputc('-', stderr);
1108
1109     if (hasOverflowClip())
1110         fputc('O', stderr);
1111     else
1112         fputc('-', stderr);
1113
1114     if (isAnonymous())
1115         fputc('Y', stderr);
1116     else
1117         fputc('-', stderr);
1118
1119     if (isPseudoElement() || isAnonymous())
1120         fputc('G', stderr);
1121     else
1122         fputc('-', stderr);
1123
1124     if (hasLayer())
1125         fputc('L', stderr);
1126     else
1127         fputc('-', stderr);
1128
1129     if (isComposited())
1130         fputc('C', stderr);
1131     else
1132         fputc('-', stderr);
1133
1134     fputc(' ', stderr);
1135
1136     if (node() && node()->needsStyleRecalc())
1137         fputc('+', stderr);
1138     else
1139         fputc('-', stderr);
1140
1141     if (needsLayout())
1142         fputc('+', stderr);
1143     else
1144         fputc('-', stderr);
1145
1146     int printedCharacters = 0;
1147     if (mark) {
1148         fprintf(stderr, "*");
1149         ++printedCharacters;
1150     }
1151
1152     while (++printedCharacters <= depth * 2)
1153         fputc(' ', stderr);
1154
1155     if (node())
1156         fprintf(stderr, "%s ", node()->nodeName().utf8().data());
1157
1158     String name = renderName();
1159     // FIXME: Renderer's name should not include property value listing.
1160     int pos = name.find('(');
1161     if (pos > 0)
1162         fprintf(stderr, "%s", name.left(pos - 1).utf8().data());
1163     else
1164         fprintf(stderr, "%s", name.utf8().data());
1165
1166     if (is<RenderBox>(*this)) {
1167         auto& renderBox = downcast<RenderBox>(*this);
1168         FloatRect boxRect = renderBox.frameRect();
1169         if (renderBox.isInFlowPositioned())
1170             boxRect.move(renderBox.offsetForInFlowPosition());
1171         fprintf(stderr, "  (%.2f, %.2f) (%.2f, %.2f)", boxRect.x(), boxRect.y(), boxRect.width(), boxRect.height());
1172     } else if (is<RenderInline>(*this) && isInFlowPositioned()) {
1173         FloatSize inlineOffset = downcast<RenderInline>(*this).offsetForInFlowPosition();
1174         fprintf(stderr, "  (%.2f, %.2f)", inlineOffset.width(), inlineOffset.height());
1175     }
1176
1177     fprintf(stderr, " renderer->(%p)", this);
1178     if (node()) {
1179         fprintf(stderr, " node->(%p)", node());
1180         if (node()->isTextNode()) {
1181             String value = node()->nodeValue();
1182             fprintf(stderr, " length->(%u)", value.length());
1183
1184             value.replaceWithLiteral('\\', "\\\\");
1185             value.replaceWithLiteral('\n', "\\n");
1186             
1187             const int maxPrintedLength = 80;
1188             if (value.length() > maxPrintedLength) {
1189                 String substring = value.substring(0, maxPrintedLength);
1190                 fprintf(stderr, " \"%s\"...", substring.utf8().data());
1191             } else
1192                 fprintf(stderr, " \"%s\"", value.utf8().data());
1193         }
1194     }
1195     if (is<RenderBoxModelObject>(*this)) {
1196         auto& renderer = downcast<RenderBoxModelObject>(*this);
1197         if (renderer.hasContinuation())
1198             fprintf(stderr, " continuation->(%p)", renderer.continuation());
1199     }
1200     showRegionsInformation();
1201     if (needsLayout()) {
1202         fprintf(stderr, " layout->");
1203         if (selfNeedsLayout())
1204             fprintf(stderr, "[self]");
1205         if (normalChildNeedsLayout())
1206             fprintf(stderr, "[normal child]");
1207         if (posChildNeedsLayout())
1208             fprintf(stderr, "[positioned child]");
1209         if (needsSimplifiedNormalFlowLayout())
1210             fprintf(stderr, "[simplified]");
1211         if (needsPositionedMovementLayout())
1212             fprintf(stderr, "[positioned movement]");
1213     }
1214     fprintf(stderr, "\n");
1215 }
1216
1217 void RenderObject::showRenderSubTreeAndMark(const RenderObject* markedObject, int depth) const
1218 {
1219     showRenderObject(markedObject == this, depth);
1220     if (is<RenderBlockFlow>(*this))
1221         downcast<RenderBlockFlow>(*this).showLineTreeAndMark(nullptr, depth + 1);
1222
1223     for (const RenderObject* child = firstChildSlow(); child; child = child->nextSibling())
1224         child->showRenderSubTreeAndMark(markedObject, depth + 1);
1225 }
1226
1227 #endif // NDEBUG
1228
1229 SelectionSubtreeRoot& RenderObject::selectionRoot() const
1230 {
1231     RenderFlowThread* flowThread = flowThreadContainingBlock();
1232     if (!flowThread)
1233         return view();
1234
1235     if (is<RenderNamedFlowThread>(*flowThread))
1236         return downcast<RenderNamedFlowThread>(*flowThread);
1237     if (is<RenderMultiColumnFlowThread>(*flowThread)) {
1238         if (!flowThread->containingBlock())
1239             return view();
1240         return flowThread->containingBlock()->selectionRoot();
1241     }
1242     ASSERT_NOT_REACHED();
1243     return view();
1244 }
1245
1246 void RenderObject::selectionStartEnd(unsigned& spos, unsigned& epos) const
1247 {
1248     selectionRoot().selectionData().selectionStartEndPositions(spos, epos);
1249 }
1250
1251 FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, MapCoordinatesFlags mode, bool* wasFixed) const
1252 {
1253     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
1254     mapLocalToContainer(nullptr, transformState, mode | ApplyContainerFlip, wasFixed);
1255     transformState.flatten();
1256     
1257     return transformState.lastPlanarPoint();
1258 }
1259
1260 FloatPoint RenderObject::absoluteToLocal(const FloatPoint& containerPoint, MapCoordinatesFlags mode) const
1261 {
1262     TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint);
1263     mapAbsoluteToLocalPoint(mode, transformState);
1264     transformState.flatten();
1265     
1266     return transformState.lastPlanarPoint();
1267 }
1268
1269 FloatQuad RenderObject::absoluteToLocalQuad(const FloatQuad& quad, MapCoordinatesFlags mode) const
1270 {
1271     TransformState transformState(TransformState::UnapplyInverseTransformDirection, quad.boundingBox().center(), quad);
1272     mapAbsoluteToLocalPoint(mode, transformState);
1273     transformState.flatten();
1274     return transformState.lastPlanarQuad();
1275 }
1276
1277 void RenderObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
1278 {
1279     if (repaintContainer == this)
1280         return;
1281
1282     auto* parent = this->parent();
1283     if (!parent)
1284         return;
1285
1286     // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
1287     LayoutPoint centerPoint(transformState.mappedPoint());
1288     if (mode & ApplyContainerFlip && is<RenderBox>(*parent)) {
1289         if (parent->style().isFlippedBlocksWritingMode())
1290             transformState.move(downcast<RenderBox>(parent)->flipForWritingMode(LayoutPoint(transformState.mappedPoint())) - centerPoint);
1291         mode &= ~ApplyContainerFlip;
1292     }
1293
1294     if (is<RenderBox>(*parent))
1295         transformState.move(-toLayoutSize(downcast<RenderBox>(*parent).scrollPosition()));
1296
1297     parent->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed);
1298 }
1299
1300 const RenderObject* RenderObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
1301 {
1302     ASSERT_UNUSED(ancestorToStopAt, ancestorToStopAt != this);
1303
1304     auto* container = parent();
1305     if (!container)
1306         return nullptr;
1307
1308     // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
1309     LayoutSize offset;
1310     if (is<RenderBox>(*container))
1311         offset = -toLayoutSize(downcast<RenderBox>(*container).scrollPosition());
1312
1313     geometryMap.push(this, offset, false);
1314     
1315     return container;
1316 }
1317
1318 void RenderObject::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
1319 {
1320     if (auto* parent = this->parent()) {
1321         parent->mapAbsoluteToLocalPoint(mode, transformState);
1322         if (is<RenderBox>(*parent))
1323             transformState.move(toLayoutSize(downcast<RenderBox>(*parent).scrollPosition()));
1324     }
1325 }
1326
1327 bool RenderObject::shouldUseTransformFromContainer(const RenderObject* containerObject) const
1328 {
1329 #if ENABLE(3D_TRANSFORMS)
1330     return hasTransform() || (containerObject && containerObject->style().hasPerspective());
1331 #else
1332     UNUSED_PARAM(containerObject);
1333     return hasTransform();
1334 #endif
1335 }
1336
1337 void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const LayoutSize& offsetInContainer, TransformationMatrix& transform) const
1338 {
1339     transform.makeIdentity();
1340     transform.translate(offsetInContainer.width(), offsetInContainer.height());
1341     RenderLayer* layer;
1342     if (hasLayer() && (layer = downcast<RenderLayerModelObject>(*this).layer()) && layer->transform())
1343         transform.multiply(layer->currentTransform());
1344     
1345 #if ENABLE(3D_TRANSFORMS)
1346     if (containerObject && containerObject->hasLayer() && containerObject->style().hasPerspective()) {
1347         // Perpsective on the container affects us, so we have to factor it in here.
1348         ASSERT(containerObject->hasLayer());
1349         FloatPoint perspectiveOrigin = downcast<RenderLayerModelObject>(*containerObject).layer()->perspectiveOrigin();
1350
1351         TransformationMatrix perspectiveMatrix;
1352         perspectiveMatrix.applyPerspective(containerObject->style().perspective());
1353         
1354         transform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0);
1355         transform = perspectiveMatrix * transform;
1356         transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0);
1357     }
1358 #else
1359     UNUSED_PARAM(containerObject);
1360 #endif
1361 }
1362
1363 FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const
1364 {
1365     // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
1366     // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
1367     TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), localQuad);
1368     mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip, wasFixed);
1369     transformState.flatten();
1370     
1371     return transformState.lastPlanarQuad();
1372 }
1373
1374 FloatPoint RenderObject::localToContainerPoint(const FloatPoint& localPoint, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const
1375 {
1376     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
1377     mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip, wasFixed);
1378     transformState.flatten();
1379
1380     return transformState.lastPlanarPoint();
1381 }
1382
1383 LayoutSize RenderObject::offsetFromContainer(RenderElement& container, const LayoutPoint&, bool* offsetDependsOnPoint) const
1384 {
1385     ASSERT(&container == this->container());
1386
1387     LayoutSize offset;
1388     if (is<RenderBox>(container))
1389         offset -= toLayoutSize(downcast<RenderBox>(container).scrollPosition());
1390
1391     if (offsetDependsOnPoint)
1392         *offsetDependsOnPoint = is<RenderFlowThread>(container);
1393
1394     return offset;
1395 }
1396
1397 LayoutSize RenderObject::offsetFromAncestorContainer(RenderElement& container) const
1398 {
1399     LayoutSize offset;
1400     LayoutPoint referencePoint;
1401     const RenderObject* currContainer = this;
1402     do {
1403         RenderElement* nextContainer = currContainer->container();
1404         ASSERT(nextContainer);  // This means we reached the top without finding container.
1405         if (!nextContainer)
1406             break;
1407         ASSERT(!currContainer->hasTransform());
1408         LayoutSize currentOffset = currContainer->offsetFromContainer(*nextContainer, referencePoint);
1409         offset += currentOffset;
1410         referencePoint.move(currentOffset);
1411         currContainer = nextContainer;
1412     } while (currContainer != &container);
1413
1414     return offset;
1415 }
1416
1417 LayoutRect RenderObject::localCaretRect(InlineBox*, unsigned, LayoutUnit* extraWidthToEndOfLine)
1418 {
1419     if (extraWidthToEndOfLine)
1420         *extraWidthToEndOfLine = 0;
1421
1422     return LayoutRect();
1423 }
1424
1425 bool RenderObject::isRooted() const
1426 {
1427     return isDescendantOf(&view());
1428 }
1429
1430 static inline RenderElement* containerForElement(const RenderObject& renderer, const RenderLayerModelObject* repaintContainer, bool* repaintContainerSkipped)
1431 {
1432     // This method is extremely similar to containingBlock(), but with a few notable
1433     // exceptions.
1434     // (1) For normal flow elements, it just returns the parent.
1435     // (2) For absolute positioned elements, it will return a relative positioned inline, while
1436     // containingBlock() skips to the non-anonymous containing block.
1437     // This does mean that computePositionedLogicalWidth and computePositionedLogicalHeight have to use container().
1438     EPosition pos = renderer.style().position();
1439     auto* parent = renderer.parent();
1440     if (is<RenderText>(renderer) || (pos != FixedPosition && pos != AbsolutePosition))
1441         return parent;
1442     for (; parent && (pos == AbsolutePosition ? !parent->canContainAbsolutelyPositionedObjects() : !parent->canContainFixedPositionObjects()); parent = parent->parent()) {
1443         if (repaintContainerSkipped && repaintContainer == parent)
1444             *repaintContainerSkipped = true;
1445     }
1446     return parent;
1447 }
1448
1449 RenderElement* RenderObject::container() const
1450 {
1451     return containerForElement(*this, nullptr, nullptr);
1452 }
1453
1454 RenderElement* RenderObject::container(const RenderLayerModelObject* repaintContainer, bool& repaintContainerSkipped) const
1455 {
1456     repaintContainerSkipped = false;
1457     return containerForElement(*this, repaintContainer, &repaintContainerSkipped);
1458 }
1459
1460 bool RenderObject::isSelectionBorder() const
1461 {
1462     SelectionState st = selectionState();
1463     return st == SelectionStart
1464         || st == SelectionEnd
1465         || st == SelectionBoth
1466         || view().selectionUnsplitStart() == this
1467         || view().selectionUnsplitEnd() == this;
1468 }
1469
1470 void RenderObject::willBeDestroyed()
1471 {
1472     // For accessibility management, notify the parent of the imminent change to its child set.
1473     // We do it now, before remove(), while the parent pointer is still available.
1474     if (AXObjectCache* cache = document().existingAXObjectCache())
1475         cache->childrenChanged(this->parent());
1476
1477     removeFromParent();
1478
1479     ASSERT(renderTreeBeingDestroyed() || !is<RenderElement>(*this) || !view().frameView().hasSlowRepaintObject(downcast<RenderElement>(*this)));
1480
1481     // The remove() call above may invoke axObjectCache()->childrenChanged() on the parent, which may require the AX render
1482     // object for this renderer. So we remove the AX render object now, after the renderer is removed.
1483     if (AXObjectCache* cache = document().existingAXObjectCache())
1484         cache->remove(this);
1485
1486     // FIXME: Would like to do this in RenderBoxModelObject, but the timing is so complicated that this can't easily
1487     // be moved into RenderLayerModelObject::willBeDestroyed().
1488     // FIXME: Is this still true?
1489     if (hasLayer()) {
1490         setHasLayer(false);
1491         downcast<RenderLayerModelObject>(*this).destroyLayer();
1492     }
1493
1494     removeRareData();
1495 }
1496
1497 void RenderObject::insertedIntoTree()
1498 {
1499     // FIXME: We should ASSERT(isRooted()) here but generated content makes some out-of-order insertion.
1500
1501     if (!isFloating() && parent()->childrenInline())
1502         parent()->dirtyLinesFromChangedChild(*this);
1503
1504     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
1505         flowThread->flowThreadDescendantInserted(*this);
1506 }
1507
1508 void RenderObject::willBeRemovedFromTree()
1509 {
1510     // FIXME: We should ASSERT(isRooted()) but we have some out-of-order removals which would need to be fixed first.
1511     // Update cached boundaries in SVG renderers, if a child is removed.
1512     parent()->setNeedsBoundariesUpdate();
1513 }
1514
1515 void RenderObject::destroyAndCleanupAnonymousWrappers()
1516 {
1517     // If the tree is destroyed, there is no need for a clean-up phase.
1518     if (renderTreeBeingDestroyed()) {
1519         destroy();
1520         return;
1521     }
1522
1523     auto* destroyRoot = this;
1524     auto* destroyRootParent = destroyRoot->parent();
1525     while (destroyRootParent && destroyRootParent->isAnonymous()) {
1526         if (!destroyRootParent->isTableCell() && !destroyRootParent->isTableRow()
1527             && !destroyRootParent->isTableCaption() && !destroyRootParent->isTableSection() && !destroyRootParent->isTable())
1528             break;
1529         // single child?
1530         if (!(destroyRootParent->firstChild() == destroyRoot && destroyRootParent->lastChild() == destroyRoot))
1531             break;
1532         destroyRoot = destroyRootParent;
1533         destroyRootParent = destroyRootParent->parent();
1534     }
1535
1536     if (is<RenderTableRow>(*destroyRoot)) {
1537         downcast<RenderTableRow>(*destroyRoot).destroyAndCollapseAnonymousSiblingRows();
1538         return;
1539     }
1540
1541     destroyRoot->destroy();
1542     // WARNING: |this| is deleted here.
1543 }
1544
1545 void RenderObject::destroy()
1546 {
1547     m_bitfields.setBeingDestroyed(true);
1548
1549 #if PLATFORM(IOS)
1550     if (hasLayer())
1551         downcast<RenderBoxModelObject>(*this).layer()->willBeDestroyed();
1552 #endif
1553
1554     willBeDestroyed();
1555     if (is<RenderWidget>(*this)) {
1556         downcast<RenderWidget>(*this).deref();
1557         return;
1558     }
1559     delete this;
1560 }
1561
1562 Position RenderObject::positionForPoint(const LayoutPoint& point)
1563 {
1564     // FIXME: This should just create a Position object instead (webkit.org/b/168566). 
1565     return positionForPoint(point, nullptr).deepEquivalent();
1566 }
1567
1568 VisiblePosition RenderObject::positionForPoint(const LayoutPoint&, const RenderRegion*)
1569 {
1570     return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
1571 }
1572
1573 void RenderObject::updateDragState(bool dragOn)
1574 {
1575     bool valueChanged = (dragOn != isDragging());
1576     setIsDragging(dragOn);
1577
1578     if (!is<RenderElement>(*this))
1579         return;
1580     auto& renderElement = downcast<RenderElement>(*this);
1581
1582     if (valueChanged && renderElement.element() && (style().affectedByDrag() || renderElement.element()->childrenAffectedByDrag()))
1583         renderElement.element()->invalidateStyleForSubtree();
1584
1585     for (auto& child : childrenOfType<RenderObject>(renderElement))
1586         child.updateDragState(dragOn);
1587 }
1588
1589 bool RenderObject::isComposited() const
1590 {
1591     return hasLayer() && downcast<RenderLayerModelObject>(*this).layer()->isComposited();
1592 }
1593
1594 bool RenderObject::isAnonymousInlineBlock() const
1595 {
1596     return isAnonymous() && style().display() == INLINE_BLOCK && style().styleType() == NOPSEUDO && isRenderBlockFlow() && !isRubyRun() && !isRubyBase() && !isRuby(parent());
1597 }
1598
1599 bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter hitTestFilter)
1600 {
1601     bool inside = false;
1602     if (hitTestFilter != HitTestSelf) {
1603         // First test the foreground layer (lines and inlines).
1604         inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestForeground);
1605
1606         // Test floats next.
1607         if (!inside)
1608             inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestFloat);
1609
1610         // Finally test to see if the mouse is in the background (within a child block's background).
1611         if (!inside)
1612             inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestChildBlockBackgrounds);
1613     }
1614
1615     // See if the mouse is inside us but not any of our descendants
1616     if (hitTestFilter != HitTestDescendants && !inside)
1617         inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestBlockBackground);
1618
1619     return inside;
1620 }
1621
1622 void RenderObject::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
1623 {
1624     if (result.innerNode())
1625         return;
1626
1627     Node* node = this->node();
1628
1629     // If we hit the anonymous renderers inside generated content we should
1630     // actually hit the generated content so walk up to the PseudoElement.
1631     if (!node && parent() && parent()->isBeforeOrAfterContent()) {
1632         for (auto* renderer = parent(); renderer && !node; renderer = renderer->parent())
1633             node = renderer->element();
1634     }
1635
1636     if (node) {
1637         result.setInnerNode(node);
1638         if (!result.innerNonSharedNode())
1639             result.setInnerNonSharedNode(node);
1640         result.setLocalPoint(point);
1641     }
1642 }
1643
1644 bool RenderObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& /*locationInContainer*/, const LayoutPoint& /*accumulatedOffset*/, HitTestAction)
1645 {
1646     return false;
1647 }
1648
1649 int RenderObject::innerLineHeight() const
1650 {
1651     return style().computedLineHeight();
1652 }
1653
1654 #if ENABLE(DASHBOARD_SUPPORT)
1655 void RenderObject::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
1656 {
1657     // Convert the style regions to absolute coordinates.
1658     if (style().visibility() != VISIBLE || !is<RenderBox>(*this))
1659         return;
1660     
1661     auto& box = downcast<RenderBox>(*this);
1662     FloatPoint absPos = localToAbsolute();
1663
1664     const Vector<StyleDashboardRegion>& styleRegions = style().dashboardRegions();
1665     for (const auto& styleRegion : styleRegions) {
1666         LayoutUnit w = box.width();
1667         LayoutUnit h = box.height();
1668
1669         AnnotatedRegionValue region;
1670         region.label = styleRegion.label;
1671         region.bounds = LayoutRect(styleRegion.offset.left().value(),
1672                                    styleRegion.offset.top().value(),
1673                                    w - styleRegion.offset.left().value() - styleRegion.offset.right().value(),
1674                                    h - styleRegion.offset.top().value() - styleRegion.offset.bottom().value());
1675         region.type = styleRegion.type;
1676
1677         region.clip = computeAbsoluteRepaintRect(region.bounds);
1678         if (region.clip.height() < 0) {
1679             region.clip.setHeight(0);
1680             region.clip.setWidth(0);
1681         }
1682
1683         region.bounds.setX(absPos.x() + styleRegion.offset.left().value());
1684         region.bounds.setY(absPos.y() + styleRegion.offset.top().value());
1685
1686         regions.append(region);
1687     }
1688 }
1689
1690 void RenderObject::collectAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
1691 {
1692     // RenderTexts don't have their own style, they just use their parent's style,
1693     // so we don't want to include them.
1694     if (is<RenderText>(*this))
1695         return;
1696
1697     addAnnotatedRegions(regions);
1698     for (RenderObject* current = downcast<RenderElement>(*this).firstChild(); current; current = current->nextSibling())
1699         current->collectAnnotatedRegions(regions);
1700 }
1701 #endif
1702
1703 int RenderObject::caretMinOffset() const
1704 {
1705     return 0;
1706 }
1707
1708 int RenderObject::caretMaxOffset() const
1709 {
1710     if (isReplaced())
1711         return node() ? std::max(1U, node()->countChildNodes()) : 1;
1712     if (isHR())
1713         return 1;
1714     return 0;
1715 }
1716
1717 int RenderObject::previousOffset(int current) const
1718 {
1719     return current - 1;
1720 }
1721
1722 int RenderObject::previousOffsetForBackwardDeletion(int current) const
1723 {
1724     return current - 1;
1725 }
1726
1727 int RenderObject::nextOffset(int current) const
1728 {
1729     return current + 1;
1730 }
1731
1732 void RenderObject::adjustRectForOutlineAndShadow(LayoutRect& rect) const
1733 {
1734     LayoutUnit outlineSize = outlineStyleForRepaint().outlineSize();
1735     if (const ShadowData* boxShadow = style().boxShadow()) {
1736         boxShadow->adjustRectForShadow(rect, outlineSize);
1737         return;
1738     }
1739     rect.inflate(outlineSize);
1740 }
1741
1742 void RenderObject::imageChanged(CachedImage* image, const IntRect* rect)
1743 {
1744     imageChanged(static_cast<WrappedImagePtr>(image), rect);
1745 }
1746
1747 RenderBoxModelObject* RenderObject::offsetParent() const
1748 {
1749     // If any of the following holds true return null and stop this algorithm:
1750     // A is the root element.
1751     // A is the HTML body element.
1752     // The computed value of the position property for element A is fixed.
1753     if (isDocumentElementRenderer() || isBody() || (isOutOfFlowPositioned() && style().position() == FixedPosition))
1754         return nullptr;
1755
1756     // If A is an area HTML element which has a map HTML element somewhere in the ancestor
1757     // chain return the nearest ancestor map HTML element and stop this algorithm.
1758     // FIXME: Implement!
1759     
1760     // Return the nearest ancestor element of A for which at least one of the following is
1761     // true and stop this algorithm if such an ancestor is found:
1762     //     * The computed value of the position property is not static.
1763     //     * It is the HTML body element.
1764     //     * The computed value of the position property of A is static and the ancestor
1765     //       is one of the following HTML elements: td, th, or table.
1766     //     * Our own extension: if there is a difference in the effective zoom
1767
1768     bool skipTables = isPositioned();
1769     float currZoom = style().effectiveZoom();
1770     auto current = parent();
1771     while (current && (!current->element() || (!current->isPositioned() && !current->isBody())) && !is<RenderNamedFlowThread>(*current)) {
1772         Element* element = current->element();
1773         if (!skipTables && element && (is<HTMLTableElement>(*element) || is<HTMLTableCellElement>(*element)))
1774             break;
1775  
1776         float newZoom = current->style().effectiveZoom();
1777         if (currZoom != newZoom)
1778             break;
1779         currZoom = newZoom;
1780         current = current->parent();
1781     }
1782     
1783     // CSS regions specification says that region flows should return the body element as their offsetParent.
1784     if (is<RenderNamedFlowThread>(current)) {
1785         auto* body = document().bodyOrFrameset();
1786         current = body ? body->renderer() : nullptr;
1787     }
1788     
1789     return is<RenderBoxModelObject>(current) ? downcast<RenderBoxModelObject>(current) : nullptr;
1790 }
1791
1792 VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity) const
1793 {
1794     // If this is a non-anonymous renderer in an editable area, then it's simple.
1795     if (Node* node = nonPseudoNode()) {
1796         if (!node->hasEditableStyle()) {
1797             // If it can be found, we prefer a visually equivalent position that is editable. 
1798             Position position = createLegacyEditingPosition(node, offset);
1799             Position candidate = position.downstream(CanCrossEditingBoundary);
1800             if (candidate.deprecatedNode()->hasEditableStyle())
1801                 return VisiblePosition(candidate, affinity);
1802             candidate = position.upstream(CanCrossEditingBoundary);
1803             if (candidate.deprecatedNode()->hasEditableStyle())
1804                 return VisiblePosition(candidate, affinity);
1805         }
1806         // FIXME: Eliminate legacy editing positions
1807         return VisiblePosition(createLegacyEditingPosition(node, offset), affinity);
1808     }
1809
1810     // We don't want to cross the boundary between editable and non-editable
1811     // regions of the document, but that is either impossible or at least
1812     // extremely unlikely in any normal case because we stop as soon as we
1813     // find a single non-anonymous renderer.
1814
1815     // Find a nearby non-anonymous renderer.
1816     const RenderObject* child = this;
1817     while (const auto parent = child->parent()) {
1818         // Find non-anonymous content after.
1819         const RenderObject* renderer = child;
1820         while ((renderer = renderer->nextInPreOrder(parent))) {
1821             if (Node* node = renderer->nonPseudoNode())
1822                 return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
1823         }
1824
1825         // Find non-anonymous content before.
1826         renderer = child;
1827         while ((renderer = renderer->previousInPreOrder())) {
1828             if (renderer == parent)
1829                 break;
1830             if (Node* node = renderer->nonPseudoNode())
1831                 return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
1832         }
1833
1834         // Use the parent itself unless it too is anonymous.
1835         if (Element* element = parent->nonPseudoElement())
1836             return VisiblePosition(firstPositionInOrBeforeNode(element), DOWNSTREAM);
1837
1838         // Repeat at the next level up.
1839         child = parent;
1840     }
1841
1842     // Everything was anonymous. Give up.
1843     return VisiblePosition();
1844 }
1845
1846 VisiblePosition RenderObject::createVisiblePosition(const Position& position) const
1847 {
1848     if (position.isNotNull())
1849         return VisiblePosition(position);
1850
1851     ASSERT(!node());
1852     return createVisiblePosition(0, DOWNSTREAM);
1853 }
1854
1855 CursorDirective RenderObject::getCursor(const LayoutPoint&, Cursor&) const
1856 {
1857     return SetCursorBasedOnStyle;
1858 }
1859
1860 bool RenderObject::canUpdateSelectionOnRootLineBoxes()
1861 {
1862     if (needsLayout())
1863         return false;
1864
1865     RenderBlock* containingBlock = this->containingBlock();
1866     return containingBlock ? !containingBlock->needsLayout() : true;
1867 }
1868
1869 // We only create "generated" child renderers like one for first-letter if:
1870 // - the firstLetterBlock can have children in the DOM and
1871 // - the block doesn't have any special assumption on its text children.
1872 // This correctly prevents form controls from having such renderers.
1873 bool RenderObject::canHaveGeneratedChildren() const
1874 {
1875     return canHaveChildren();
1876 }
1877
1878 Node* RenderObject::generatingPseudoHostElement() const
1879 {
1880     return downcast<PseudoElement>(*node()).hostElement();
1881 }
1882
1883 void RenderObject::setNeedsBoundariesUpdate()
1884 {
1885     if (auto renderer = parent())
1886         renderer->setNeedsBoundariesUpdate();
1887 }
1888
1889 FloatRect RenderObject::objectBoundingBox() const
1890 {
1891     ASSERT_NOT_REACHED();
1892     return FloatRect();
1893 }
1894
1895 FloatRect RenderObject::strokeBoundingBox() const
1896 {
1897     ASSERT_NOT_REACHED();
1898     return FloatRect();
1899 }
1900
1901 // Returns the smallest rectangle enclosing all of the painted content
1902 // respecting clipping, masking, filters, opacity, stroke-width and markers
1903 FloatRect RenderObject::repaintRectInLocalCoordinates() const
1904 {
1905     ASSERT_NOT_REACHED();
1906     return FloatRect();
1907 }
1908
1909 AffineTransform RenderObject::localTransform() const
1910 {
1911     static const AffineTransform identity;
1912     return identity;
1913 }
1914
1915 const AffineTransform& RenderObject::localToParentTransform() const
1916 {
1917     static const AffineTransform identity;
1918     return identity;
1919 }
1920
1921 bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction)
1922 {
1923     ASSERT_NOT_REACHED();
1924     return false;
1925 }
1926
1927 RenderNamedFlowFragment* RenderObject::currentRenderNamedFlowFragment() const
1928 {
1929     RenderFlowThread* flowThread = flowThreadContainingBlock();
1930     if (!is<RenderNamedFlowThread>(flowThread))
1931         return nullptr;
1932
1933     // FIXME: Once regions are fully integrated with the compositing system we should uncomment this assert.
1934     // This assert needs to be disabled because it's possible to ask for the ancestor clipping rectangle of
1935     // a layer without knowing the containing region in advance.
1936     // ASSERT(flowThread->currentRegion() && flowThread->currentRegion()->isRenderNamedFlowFragment());
1937
1938     return downcast<RenderNamedFlowFragment>(flowThread->currentRegion());
1939 }
1940
1941 RenderFlowThread* RenderObject::locateFlowThreadContainingBlock() const
1942 {
1943     RenderBlock* containingBlock = this->containingBlock();
1944     return containingBlock ? containingBlock->flowThreadContainingBlock() : nullptr;
1945 }
1946
1947 void RenderObject::calculateBorderStyleColor(const EBorderStyle& style, const BoxSide& side, Color& color)
1948 {
1949     ASSERT(style == INSET || style == OUTSET);
1950     // This values were derived empirically.
1951     const RGBA32 baseDarkColor = 0xFF202020;
1952     const RGBA32 baseLightColor = 0xFFEBEBEB;
1953     enum Operation { Darken, Lighten };
1954
1955     Operation operation = (side == BSTop || side == BSLeft) == (style == INSET) ? Darken : Lighten;
1956
1957     // Here we will darken the border decoration color when needed. This will yield a similar behavior as in FF.
1958     if (operation == Darken) {
1959         if (differenceSquared(color, Color::black) > differenceSquared(baseDarkColor, Color::black))
1960             color = color.dark();
1961     } else {
1962         if (differenceSquared(color, Color::white) > differenceSquared(baseLightColor, Color::white))
1963             color = color.light();
1964     }
1965 }
1966
1967 void RenderObject::setIsDragging(bool isDragging)
1968 {
1969     if (isDragging || hasRareData())
1970         ensureRareData().setIsDragging(isDragging);
1971 }
1972
1973 void RenderObject::setHasReflection(bool hasReflection)
1974 {
1975     if (hasReflection || hasRareData())
1976         ensureRareData().setHasReflection(hasReflection);
1977 }
1978
1979 void RenderObject::setIsRenderFlowThread(bool isFlowThread)
1980 {
1981     if (isFlowThread || hasRareData())
1982         ensureRareData().setIsRenderFlowThread(isFlowThread);
1983 }
1984
1985 void RenderObject::setHasOutlineAutoAncestor(bool hasOutlineAutoAncestor)
1986 {
1987     if (hasOutlineAutoAncestor || hasRareData())
1988         ensureRareData().setHasOutlineAutoAncestor(hasOutlineAutoAncestor);
1989 }
1990
1991 RenderObject::RareDataMap& RenderObject::rareDataMap()
1992 {
1993     static NeverDestroyed<RareDataMap> map;
1994     return map;
1995 }
1996
1997 const RenderObject::RenderObjectRareData& RenderObject::rareData() const
1998 {
1999     ASSERT(hasRareData());
2000     return *rareDataMap().get(this);
2001 }
2002
2003 RenderObject::RenderObjectRareData& RenderObject::ensureRareData()
2004 {
2005     setHasRareData(true);
2006     return *rareDataMap().ensure(this, [] { return std::make_unique<RenderObjectRareData>(); }).iterator->value;
2007 }
2008
2009 void RenderObject::removeRareData()
2010 {
2011     rareDataMap().remove(this);
2012     setHasRareData(false);
2013 }
2014
2015 #if ENABLE(TREE_DEBUGGING)
2016
2017 void printRenderTreeForLiveDocuments()
2018 {
2019     for (const auto* document : Document::allDocuments()) {
2020         if (!document->renderView())
2021             continue;
2022         if (document->frame() && document->frame()->isMainFrame())
2023             fprintf(stderr, "----------------------main frame--------------------------\n");
2024         fprintf(stderr, "%s", document->url().string().utf8().data());
2025         showRenderTree(document->renderView());
2026     }
2027 }
2028
2029 void printLayerTreeForLiveDocuments()
2030 {
2031     for (const auto* document : Document::allDocuments()) {
2032         if (!document->renderView())
2033             continue;
2034         if (document->frame() && document->frame()->isMainFrame())
2035             fprintf(stderr, "----------------------main frame--------------------------\n");
2036         fprintf(stderr, "%s", document->url().string().utf8().data());
2037         showLayerTree(document->renderView());
2038     }
2039 }
2040
2041 #endif // ENABLE(TREE_DEBUGGING)
2042
2043 } // namespace WebCore
2044
2045 #if ENABLE(TREE_DEBUGGING)
2046
2047 void showNodeTree(const WebCore::RenderObject* object)
2048 {
2049     if (!object)
2050         return;
2051     object->showNodeTreeForThis();
2052 }
2053
2054 void showLineTree(const WebCore::RenderObject* object)
2055 {
2056     if (!object)
2057         return;
2058     object->showLineTreeForThis();
2059 }
2060
2061 void showRenderTree(const WebCore::RenderObject* object)
2062 {
2063     if (!object)
2064         return;
2065     object->showRenderTreeForThis();
2066 }
2067
2068 #endif