Move some RenderObject member functions to RenderElement.
[WebKit-https.git] / Source / WebCore / rendering / RenderObject.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  *           (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011, 2013 Apple Inc. All rights reserved.
7  * Copyright (C) 2009 Google Inc. All rights reserved.
8  * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  *
25  */
26
27 #include "config.h"
28 #include "RenderObject.h"
29
30 #include "AXObjectCache.h"
31 #include "AnimationController.h"
32 #include "EventHandler.h"
33 #include "FloatQuad.h"
34 #include "FlowThreadController.h"
35 #include "FocusController.h"
36 #include "FrameSelection.h"
37 #include "FrameView.h"
38 #include "GeometryUtilities.h"
39 #include "GraphicsContext.h"
40 #include "HTMLAnchorElement.h"
41 #include "HTMLElement.h"
42 #include "HTMLImageElement.h"
43 #include "HTMLNames.h"
44 #include "HTMLTableCellElement.h"
45 #include "HTMLTableElement.h"
46 #include "HitTestResult.h"
47 #include "LogicalSelectionOffsetCaches.h"
48 #include "Page.h"
49 #include "PseudoElement.h"
50 #include "RenderCounter.h"
51 #include "RenderFlowThread.h"
52 #include "RenderGeometryMap.h"
53 #include "RenderInline.h"
54 #include "RenderIterator.h"
55 #include "RenderLayer.h"
56 #include "RenderLayerBacking.h"
57 #include "RenderNamedFlowFragment.h"
58 #include "RenderNamedFlowThread.h" 
59 #include "RenderSVGResourceContainer.h"
60 #include "RenderScrollbarPart.h"
61 #include "RenderTheme.h"
62 #include "RenderView.h"
63 #include "SVGRenderSupport.h"
64 #include "Settings.h"
65 #include "ShadowRoot.h"
66 #include "StyleResolver.h"
67 #include "TransformState.h"
68 #include "htmlediting.h"
69 #include <algorithm>
70 #include <stdio.h>
71 #include <wtf/RefCountedLeakCounter.h>
72
73 #if PLATFORM(IOS)
74 #include "SelectionRect.h"
75 #endif
76
77 namespace WebCore {
78
79 using namespace HTMLNames;
80
81 #ifndef NDEBUG
82 RenderObject::SetLayoutNeededForbiddenScope::SetLayoutNeededForbiddenScope(RenderObject* renderObject, bool isForbidden)
83     : m_renderObject(renderObject)
84     , m_preexistingForbidden(m_renderObject->isSetNeedsLayoutForbidden())
85 {
86     m_renderObject->setNeedsLayoutIsForbidden(isForbidden);
87 }
88
89 RenderObject::SetLayoutNeededForbiddenScope::~SetLayoutNeededForbiddenScope()
90 {
91     m_renderObject->setNeedsLayoutIsForbidden(m_preexistingForbidden);
92 }
93 #endif
94
95 struct SameSizeAsRenderObject {
96     virtual ~SameSizeAsRenderObject() { } // Allocate vtable pointer.
97     void* pointers[4];
98 #ifndef NDEBUG
99     unsigned m_debugBitfields : 2;
100 #endif
101     unsigned m_bitfields;
102 };
103
104 COMPILE_ASSERT(sizeof(RenderObject) == sizeof(SameSizeAsRenderObject), RenderObject_should_stay_small);
105
106 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, renderObjectCounter, ("RenderObject"));
107
108 RenderObject::RenderObject(Node& node)
109     : CachedImageClient()
110     , m_node(node)
111     , m_parent(0)
112     , m_previous(0)
113     , m_next(0)
114 #ifndef NDEBUG
115     , m_hasAXObject(false)
116     , m_setNeedsLayoutForbidden(false)
117 #endif
118     , m_bitfields(node)
119 {
120     if (!node.isDocumentNode())
121         view().didCreateRenderer();
122 #ifndef NDEBUG
123     renderObjectCounter.increment();
124 #endif
125 }
126
127 RenderObject::~RenderObject()
128 {
129 #ifndef NDEBUG
130     ASSERT(!m_hasAXObject);
131     renderObjectCounter.decrement();
132 #endif
133     view().didDestroyRenderer();
134 }
135
136 RenderTheme& RenderObject::theme() const
137 {
138     ASSERT(document().page());
139     return document().page()->theme();
140 }
141
142 bool RenderObject::isDescendantOf(const RenderObject* obj) const
143 {
144     for (const RenderObject* r = this; r; r = r->m_parent) {
145         if (r == obj)
146             return true;
147     }
148     return false;
149 }
150
151 bool RenderObject::isLegend() const
152 {
153     return node() && node()->hasTagName(legendTag);
154 }
155
156 bool RenderObject::isHTMLMarquee() const
157 {
158     return node() && node()->renderer() == this && node()->hasTagName(marqueeTag);
159 }
160
161 void RenderObject::setFlowThreadStateIncludingDescendants(FlowThreadState state)
162 {
163     setFlowThreadState(state);
164
165     for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling()) {
166         // If the child is a fragmentation context it already updated the descendants flag accordingly.
167         if (child->isRenderFlowThread())
168             continue;
169         ASSERT(state != child->flowThreadState());
170         child->setFlowThreadStateIncludingDescendants(state);
171     }
172 }
173
174 void RenderObject::setParent(RenderElement* parent)
175 {
176     m_parent = parent;
177
178     // Only update if our flow thread state is different from our new parent and if we're not a RenderFlowThread.
179     // A RenderFlowThread is always considered to be inside itself, so it never has to change its state
180     // in response to parent changes.
181     FlowThreadState newState = parent ? parent->flowThreadState() : NotInsideFlowThread;
182     if (newState != flowThreadState() && !isRenderFlowThread())
183         setFlowThreadStateIncludingDescendants(newState);
184 }
185
186 void RenderObject::removeFromParent()
187 {
188     if (parent())
189         parent()->removeChild(*this);
190 }
191
192 RenderObject* RenderObject::nextInPreOrder() const
193 {
194     if (RenderObject* o = firstChildSlow())
195         return o;
196
197     return nextInPreOrderAfterChildren();
198 }
199
200 RenderObject* RenderObject::nextInPreOrderAfterChildren() const
201 {
202     RenderObject* o;
203     if (!(o = nextSibling())) {
204         o = parent();
205         while (o && !o->nextSibling())
206             o = o->parent();
207         if (o)
208             o = o->nextSibling();
209     }
210
211     return o;
212 }
213
214 RenderObject* RenderObject::nextInPreOrder(const RenderObject* stayWithin) const
215 {
216     if (RenderObject* o = firstChildSlow())
217         return o;
218
219     return nextInPreOrderAfterChildren(stayWithin);
220 }
221
222 RenderObject* RenderObject::nextInPreOrderAfterChildren(const RenderObject* stayWithin) const
223 {
224     if (this == stayWithin)
225         return 0;
226
227     const RenderObject* current = this;
228     RenderObject* next;
229     while (!(next = current->nextSibling())) {
230         current = current->parent();
231         if (!current || current == stayWithin)
232             return 0;
233     }
234     return next;
235 }
236
237 RenderObject* RenderObject::previousInPreOrder() const
238 {
239     if (RenderObject* o = previousSibling()) {
240         while (RenderObject* last = o->lastChildSlow())
241             o = last;
242         return o;
243     }
244
245     return parent();
246 }
247
248 RenderObject* RenderObject::previousInPreOrder(const RenderObject* stayWithin) const
249 {
250     if (this == stayWithin)
251         return 0;
252
253     return previousInPreOrder();
254 }
255
256 RenderObject* RenderObject::childAt(unsigned index) const
257 {
258     RenderObject* child = firstChildSlow();
259     for (unsigned i = 0; child && i < index; i++)
260         child = child->nextSibling();
261     return child;
262 }
263
264 RenderObject* RenderObject::firstLeafChild() const
265 {
266     RenderObject* r = firstChildSlow();
267     while (r) {
268         RenderObject* n = 0;
269         n = r->firstChildSlow();
270         if (!n)
271             break;
272         r = n;
273     }
274     return r;
275 }
276
277 RenderObject* RenderObject::lastLeafChild() const
278 {
279     RenderObject* r = lastChildSlow();
280     while (r) {
281         RenderObject* n = 0;
282         n = r->lastChildSlow();
283         if (!n)
284             break;
285         r = n;
286     }
287     return r;
288 }
289
290 #if ENABLE(IOS_TEXT_AUTOSIZING)
291 // Inspired by Node::traverseNextNode.
292 RenderObject* RenderObject::traverseNext(const RenderObject* stayWithin) const
293 {
294     RenderObject* child = firstChildSlow();
295     if (child) {
296         ASSERT(!stayWithin || child->isDescendantOf(stayWithin));
297         return child;
298     }
299     if (this == stayWithin)
300         return 0;
301     if (nextSibling()) {
302         ASSERT(!stayWithin || nextSibling()->isDescendantOf(stayWithin));
303         return nextSibling();
304     }
305     const RenderObject* n = this;
306     while (n && !n->nextSibling() && (!stayWithin || n->parent() != stayWithin))
307         n = n->parent();
308     if (n) {
309         ASSERT(!stayWithin || !n->nextSibling() || n->nextSibling()->isDescendantOf(stayWithin));
310         return n->nextSibling();
311     }
312     return 0;
313 }
314
315 // Non-recursive version of the DFS search.
316 RenderObject* RenderObject::traverseNext(const RenderObject* stayWithin, HeightTypeTraverseNextInclusionFunction inclusionFunction, int& currentDepth, int& newFixedDepth) const
317 {
318     BlockContentHeightType overflowType;
319
320     // Check for suitable children.
321     for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling()) {
322         overflowType = inclusionFunction(child);
323         if (overflowType != FixedHeight) {
324             currentDepth++;
325             if (overflowType == OverflowHeight)
326                 newFixedDepth = currentDepth;
327             ASSERT(!stayWithin || child->isDescendantOf(stayWithin));
328             return child;
329         }
330     }
331
332     if (this == stayWithin)
333         return 0;
334
335     // Now we traverse other nodes if they exist, otherwise
336     // we go to the parent node and try doing the same.
337     const RenderObject* n = this;
338     while (n) {
339         while (n && !n->nextSibling() && (!stayWithin || n->parent() != stayWithin)) {
340             n = n->parent();
341             currentDepth--;
342         }
343         if (!n)
344             return 0;
345         for (RenderObject* sibling = n->nextSibling(); sibling; sibling = sibling->nextSibling()) {
346             overflowType = inclusionFunction(sibling);
347             if (overflowType != FixedHeight) {
348                 if (overflowType == OverflowHeight)
349                     newFixedDepth = currentDepth;
350                 ASSERT(!stayWithin || !n->nextSibling() || n->nextSibling()->isDescendantOf(stayWithin));
351                 return sibling;
352             }
353         }
354         if (!stayWithin || n->parent() != stayWithin) {
355             n = n->parent();
356             currentDepth--;
357         } else
358             return 0;
359     }
360     return 0;
361 }
362
363 RenderObject* RenderObject::traverseNext(const RenderObject* stayWithin, TraverseNextInclusionFunction inclusionFunction) const
364 {
365     for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling()) {
366         if (inclusionFunction(child)) {
367             ASSERT(!stayWithin || child->isDescendantOf(stayWithin));
368             return child;
369         }
370     }
371
372     if (this == stayWithin)
373         return 0;
374
375     for (RenderObject* sibling = nextSibling(); sibling; sibling = sibling->nextSibling()) {
376         if (inclusionFunction(sibling)) {
377             ASSERT(!stayWithin || sibling->isDescendantOf(stayWithin));
378             return sibling;
379         }
380     }
381
382     const RenderObject* n = this;
383     while (n) {
384         while (n && !n->nextSibling() && (!stayWithin || n->parent() != stayWithin))
385             n = n->parent();
386         if (n) {
387             for (RenderObject* sibling = n->nextSibling(); sibling; sibling = sibling->nextSibling()) {
388                 if (inclusionFunction(sibling)) {
389                     ASSERT(!stayWithin || !n->nextSibling() || n->nextSibling()->isDescendantOf(stayWithin));
390                     return sibling;
391                 }
392             }
393             if ((!stayWithin || n->parent() != stayWithin))
394                 n = n->parent();
395             else
396                 return 0;
397         }
398     }
399     return 0;
400 }
401
402 static RenderObject::BlockContentHeightType includeNonFixedHeight(const RenderObject* renderer)
403 {
404     const RenderStyle& style = renderer->style();
405     if (style.height().type() == Fixed) {
406         if (is<RenderBlock>(*renderer)) {
407             // For fixed height styles, if the overflow size of the element spills out of the specified
408             // height, assume we can apply text auto-sizing.
409             if (style.overflowY() == OVISIBLE
410                 && style.height().value() < downcast<RenderBlock>(renderer)->layoutOverflowRect().maxY())
411                 return RenderObject::OverflowHeight;
412         }
413         return RenderObject::FixedHeight;
414     }
415     return RenderObject::FlexibleHeight;
416 }
417
418
419 void RenderObject::adjustComputedFontSizesOnBlocks(float size, float visibleWidth)
420 {
421     Document* document = view().frameView().frame().document();
422     if (!document)
423         return;
424
425     Vector<int> depthStack;
426     int currentDepth = 0;
427     int newFixedDepth = 0;
428
429     // We don't apply autosizing to nodes with fixed height normally.
430     // But we apply it to nodes which are located deep enough
431     // (nesting depth is greater than some const) inside of a parent block
432     // which has fixed height but its content overflows intentionally.
433     for (RenderObject* descendent = traverseNext(this, includeNonFixedHeight, currentDepth, newFixedDepth); descendent; descendent = descendent->traverseNext(this, includeNonFixedHeight, currentDepth, newFixedDepth)) {
434         while (depthStack.size() > 0 && currentDepth <= depthStack[depthStack.size() - 1])
435             depthStack.remove(depthStack.size() - 1);
436         if (newFixedDepth)
437             depthStack.append(newFixedDepth);
438
439         int stackSize = depthStack.size();
440         if (is<RenderBlockFlow>(*descendent) && !descendent->isListItem() && (!stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth))
441             downcast<RenderBlockFlow>(*descendent).adjustComputedFontSizes(size, visibleWidth);
442         newFixedDepth = 0;
443     }
444
445     // Remove style from auto-sizing table that are no longer valid.
446     document->validateAutoSizingNodes();
447 }
448
449 void RenderObject::resetTextAutosizing()
450 {
451     Document* document = view().frameView().frame().document();
452     if (!document)
453         return;
454
455     document->resetAutoSizingNodes();
456
457     Vector<int> depthStack;
458     int currentDepth = 0;
459     int newFixedDepth = 0;
460
461     for (RenderObject* descendent = traverseNext(this, includeNonFixedHeight, currentDepth, newFixedDepth); descendent; descendent = descendent->traverseNext(this, includeNonFixedHeight, currentDepth, newFixedDepth)) {
462         while (depthStack.size() > 0 && currentDepth <= depthStack[depthStack.size() - 1])
463             depthStack.remove(depthStack.size() - 1);
464         if (newFixedDepth)
465             depthStack.append(newFixedDepth);
466
467         int stackSize = depthStack.size();
468         if (is<RenderBlockFlow>(*descendent) && !descendent->isListItem() && (!stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth))
469             downcast<RenderBlockFlow>(*descendent).resetComputedFontSize();
470         newFixedDepth = 0;
471     }
472 }
473 #endif // ENABLE(IOS_TEXT_AUTOSIZING)
474
475 RenderLayer* RenderObject::enclosingLayer() const
476 {
477     for (auto& renderer : lineageOfType<RenderLayerModelObject>(*this)) {
478         if (renderer.layer())
479             return renderer.layer();
480     }
481     return nullptr;
482 }
483
484 bool RenderObject::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
485 {
486     RenderLayer* enclosingLayer = this->enclosingLayer();
487     if (!enclosingLayer)
488         return false;
489
490     enclosingLayer->scrollRectToVisible(rect, alignX, alignY);
491     return true;
492 }
493
494 RenderBox& RenderObject::enclosingBox() const
495 {
496     return *lineageOfType<RenderBox>(const_cast<RenderObject&>(*this)).first();
497 }
498
499 RenderBoxModelObject& RenderObject::enclosingBoxModelObject() const
500 {
501     return *lineageOfType<RenderBoxModelObject>(const_cast<RenderObject&>(*this)).first();
502 }
503
504 bool RenderObject::fixedPositionedWithNamedFlowContainingBlock() const
505 {
506     return ((flowThreadState() == RenderObject::InsideOutOfFlowThread)
507         && (style().position() == FixedPosition)
508         && (containingBlock()->isOutOfFlowRenderFlowThread()));
509 }
510
511 static bool hasFixedPosInNamedFlowContainingBlock(const RenderObject* renderer)
512 {
513     ASSERT(renderer->flowThreadState() != RenderObject::NotInsideFlowThread);
514
515     RenderObject* curr = const_cast<RenderObject*>(renderer);
516     while (curr) {
517         if (curr->fixedPositionedWithNamedFlowContainingBlock())
518             return true;
519         curr = curr->containingBlock();
520     }
521
522     return false;
523 }
524
525 RenderBlock* RenderObject::firstLineBlock() const
526 {
527     return 0;
528 }
529
530 static inline bool objectIsRelayoutBoundary(const RenderElement* object)
531 {
532     // FIXME: In future it may be possible to broaden these conditions in order to improve performance.
533     if (object->isRenderView())
534         return true;
535
536     if (object->isTextControl())
537         return true;
538
539     if (object->isSVGRoot())
540         return true;
541
542     if (!object->hasOverflowClip())
543         return false;
544
545     if (object->style().width().isIntrinsicOrAuto() || object->style().height().isIntrinsicOrAuto() || object->style().height().isPercent())
546         return false;
547
548     // Table parts can't be relayout roots since the table is responsible for layouting all the parts.
549     if (object->isTablePart())
550         return false;
551
552     return true;
553 }
554
555 void RenderObject::clearNeedsLayout()
556 {
557     m_bitfields.setNeedsLayout(false);
558     setEverHadLayout(true);
559     setPosChildNeedsLayoutBit(false);
560     setNeedsSimplifiedNormalFlowLayoutBit(false);
561     setNormalChildNeedsLayoutBit(false);
562     setNeedsPositionedMovementLayoutBit(false);
563     if (is<RenderElement>(*this))
564         downcast<RenderElement>(*this).setAncestorLineBoxDirty(false);
565 #ifndef NDEBUG
566     checkBlockPositionedObjectsNeedLayout();
567 #endif
568 }
569
570 static void scheduleRelayoutForSubtree(RenderElement& renderer)
571 {
572     if (!is<RenderView>(renderer)) {
573         if (!renderer.isRooted())
574             return;
575         renderer.view().frameView().scheduleRelayoutOfSubtree(renderer);
576         return;
577     }
578     downcast<RenderView>(renderer).frameView().scheduleRelayout();
579 }
580
581 void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, RenderElement* newRoot)
582 {
583     ASSERT(!scheduleRelayout || !newRoot);
584     ASSERT(!isSetNeedsLayoutForbidden());
585
586     auto ancestor = container();
587
588     bool simplifiedNormalFlowLayout = needsSimplifiedNormalFlowLayout() && !selfNeedsLayout() && !normalChildNeedsLayout();
589     bool hasOutOfFlowPosition = !isText() && style().hasOutOfFlowPosition();
590
591     while (ancestor) {
592 #ifndef NDEBUG
593         // FIXME: Remove this once we remove the special cases for counters, quotes and mathml
594         // calling setNeedsLayout during preferred width computation.
595         SetLayoutNeededForbiddenScope layoutForbiddenScope(ancestor, isSetNeedsLayoutForbidden());
596 #endif
597         // Don't mark the outermost object of an unrooted subtree. That object will be
598         // marked when the subtree is added to the document.
599         auto container = ancestor->container();
600         if (!container && !ancestor->isRenderView())
601             return;
602         if (hasOutOfFlowPosition) {
603             bool willSkipRelativelyPositionedInlines = !ancestor->isRenderBlock() || ancestor->isAnonymousBlock();
604             // Skip relatively positioned inlines and anonymous blocks to get to the enclosing RenderBlock.
605             while (ancestor && (!ancestor->isRenderBlock() || ancestor->isAnonymousBlock()))
606                 ancestor = ancestor->container();
607             if (!ancestor || ancestor->posChildNeedsLayout())
608                 return;
609             if (willSkipRelativelyPositionedInlines)
610                 container = ancestor->container();
611             ancestor->setPosChildNeedsLayoutBit(true);
612             simplifiedNormalFlowLayout = true;
613         } else if (simplifiedNormalFlowLayout) {
614             if (ancestor->needsSimplifiedNormalFlowLayout())
615                 return;
616             ancestor->setNeedsSimplifiedNormalFlowLayoutBit(true);
617         } else {
618             if (ancestor->normalChildNeedsLayout())
619                 return;
620             ancestor->setNormalChildNeedsLayoutBit(true);
621         }
622         ASSERT(!ancestor->isSetNeedsLayoutForbidden());
623
624         if (ancestor == newRoot)
625             return;
626
627         if (scheduleRelayout && objectIsRelayoutBoundary(ancestor))
628             break;
629
630         hasOutOfFlowPosition = ancestor->style().hasOutOfFlowPosition();
631         ancestor = container;
632     }
633
634     if (scheduleRelayout && ancestor)
635         scheduleRelayoutForSubtree(*ancestor);
636 }
637
638 #ifndef NDEBUG
639 void RenderObject::checkBlockPositionedObjectsNeedLayout()
640 {
641     ASSERT(!needsLayout());
642
643     if (is<RenderBlock>(*this))
644         downcast<RenderBlock>(*this).checkPositionedObjectsNeedLayout();
645 }
646 #endif
647
648 void RenderObject::setPreferredLogicalWidthsDirty(bool shouldBeDirty, MarkingBehavior markParents)
649 {
650     bool alreadyDirty = preferredLogicalWidthsDirty();
651     m_bitfields.setPreferredLogicalWidthsDirty(shouldBeDirty);
652     if (shouldBeDirty && !alreadyDirty && markParents == MarkContainingBlockChain && (isText() || !style().hasOutOfFlowPosition()))
653         invalidateContainerPreferredLogicalWidths();
654 }
655
656 void RenderObject::invalidateContainerPreferredLogicalWidths()
657 {
658     // In order to avoid pathological behavior when inlines are deeply nested, we do include them
659     // in the chain that we mark dirty (even though they're kind of irrelevant).
660     auto o = isTableCell() ? containingBlock() : container();
661     while (o && !o->preferredLogicalWidthsDirty()) {
662         // Don't invalidate the outermost object of an unrooted subtree. That object will be 
663         // invalidated when the subtree is added to the document.
664         auto container = o->isTableCell() ? o->containingBlock() : o->container();
665         if (!container && !o->isRenderView())
666             break;
667
668         o->m_bitfields.setPreferredLogicalWidthsDirty(true);
669         if (o->style().hasOutOfFlowPosition())
670             // A positioned object has no effect on the min/max width of its containing block ever.
671             // We can optimize this case and not go up any further.
672             break;
673         o = container;
674     }
675 }
676
677 void RenderObject::setLayerNeedsFullRepaint()
678 {
679     ASSERT(hasLayer());
680     downcast<RenderLayerModelObject>(*this).layer()->setRepaintStatus(NeedsFullRepaint);
681 }
682
683 void RenderObject::setLayerNeedsFullRepaintForPositionedMovementLayout()
684 {
685     ASSERT(hasLayer());
686     downcast<RenderLayerModelObject>(*this).layer()->setRepaintStatus(NeedsFullRepaintForPositionedMovementLayout);
687 }
688
689 RenderBlock* RenderObject::containingBlock() const
690 {
691     auto parent = this->parent();
692     if (!parent && is<RenderScrollbarPart>(*this))
693         parent = downcast<RenderScrollbarPart>(*this).rendererOwningScrollbar();
694
695     const RenderStyle& style = this->style();
696     if (!is<RenderText>(*this) && style.position() == FixedPosition)
697         parent = containingBlockForFixedPosition(parent);
698     else if (!is<RenderText>(*this) && style.position() == AbsolutePosition)
699         parent = containingBlockForAbsolutePosition(parent);
700     else
701         parent = containingBlockForObjectInFlow(parent);
702
703     if (!is<RenderBlock>(parent))
704         return nullptr; // This can still happen in case of an orphaned tree
705
706     return downcast<RenderBlock>(parent);
707 }
708
709 void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, float x1, float y1, float x2, float y2,
710     BoxSide side, Color color, EBorderStyle borderStyle, float adjacentWidth1, float adjacentWidth2, bool antialias) const
711 {
712     float deviceScaleFactor = document().deviceScaleFactor();
713     float thickness;
714     float length;
715     if (side == BSTop || side == BSBottom) {
716         thickness = y2 - y1;
717         length = x2 - x1;
718     } else {
719         thickness = x2 - x1;
720         length = y2 - y1;
721     }
722     if (borderStyle == DOUBLE && (thickness * deviceScaleFactor) < 3)
723         borderStyle = SOLID;
724
725     // FIXME: We really would like this check to be an ASSERT as we don't want to draw empty borders. However
726     // nothing guarantees that the following recursive calls to drawLineForBoxSide will have non-null dimensions.
727     if (!thickness || !length)
728         return;
729
730     const RenderStyle& style = this->style();
731     switch (borderStyle) {
732         case BNONE:
733         case BHIDDEN:
734             return;
735         case DOTTED:
736         case DASHED: {
737             if (thickness > 0) {
738                 bool wasAntialiased = graphicsContext->shouldAntialias();
739                 StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
740                 graphicsContext->setShouldAntialias(antialias);
741                 graphicsContext->setStrokeColor(color, style.colorSpace());
742                 graphicsContext->setStrokeThickness(thickness);
743                 graphicsContext->setStrokeStyle(borderStyle == DASHED ? DashedStroke : DottedStroke);
744
745                 // FIXME: There's some odd adjustment in GraphicsContext::drawLine() that disables device pixel precision line drawing.
746                 int adjustedX = floorToInt((x1 + x2) / 2);
747                 int adjustedY = floorToInt((y1 + y2) / 2);
748
749                 switch (side) {
750                     case BSBottom:
751                     case BSTop:
752                         graphicsContext->drawLine(FloatPoint(x1, adjustedY), FloatPoint(x2, adjustedY));
753                         break;
754                     case BSRight:
755                     case BSLeft:
756                         graphicsContext->drawLine(FloatPoint(adjustedX, y1), FloatPoint(adjustedX, y2));
757                         break;
758                 }
759                 graphicsContext->setShouldAntialias(wasAntialiased);
760                 graphicsContext->setStrokeStyle(oldStrokeStyle);
761             }
762             break;
763         }
764         case DOUBLE: {
765             float thirdOfThickness = ceilToDevicePixel(thickness / 3, deviceScaleFactor);
766             ASSERT(thirdOfThickness);
767
768             if (adjacentWidth1 == 0 && adjacentWidth2 == 0) {
769                 StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
770                 graphicsContext->setStrokeStyle(NoStroke);
771                 graphicsContext->setFillColor(color, style.colorSpace());
772                 
773                 bool wasAntialiased = graphicsContext->shouldAntialias();
774                 graphicsContext->setShouldAntialias(antialias);
775
776                 switch (side) {
777                     case BSTop:
778                     case BSBottom:
779                         graphicsContext->drawRect(snapRectToDevicePixels(x1, y1, length, thirdOfThickness, deviceScaleFactor));
780                         graphicsContext->drawRect(snapRectToDevicePixels(x1, y2 - thirdOfThickness, length, thirdOfThickness, deviceScaleFactor));
781                         break;
782                     case BSLeft:
783                     case BSRight:
784                         graphicsContext->drawRect(snapRectToDevicePixels(x1, y1, thirdOfThickness, length, deviceScaleFactor));
785                         graphicsContext->drawRect(snapRectToDevicePixels(x2 - thirdOfThickness, y1, thirdOfThickness, length, deviceScaleFactor));
786                         break;
787                 }
788
789                 graphicsContext->setShouldAntialias(wasAntialiased);
790                 graphicsContext->setStrokeStyle(oldStrokeStyle);
791             } else {
792                 float adjacent1BigThird = ceilToDevicePixel(adjacentWidth1 / 3, deviceScaleFactor);
793                 float adjacent2BigThird = ceilToDevicePixel(adjacentWidth2 / 3, deviceScaleFactor);
794
795                 float offset1 = floorToDevicePixel(fabs(adjacentWidth1) * 2 / 3, deviceScaleFactor);
796                 float offset2 = floorToDevicePixel(fabs(adjacentWidth2) * 2 / 3, deviceScaleFactor);
797
798                 float mitreOffset1 = adjacentWidth1 < 0 ? offset1 : 0;
799                 float mitreOffset2 = adjacentWidth1 > 0 ? offset1 : 0;
800                 float mitreOffset3 = adjacentWidth2 < 0 ? offset2 : 0;
801                 float mitreOffset4 = adjacentWidth2 > 0 ? offset2 : 0;
802
803                 FloatRect paintBorderRect;
804                 switch (side) {
805                     case BSTop:
806                         paintBorderRect = snapRectToDevicePixels(LayoutRect(x1 + mitreOffset1, y1, (x2 - mitreOffset3) - (x1 + mitreOffset1), thirdOfThickness), deviceScaleFactor);
807                         drawLineForBoxSide(graphicsContext, paintBorderRect.x(), paintBorderRect.y(), paintBorderRect.maxX(), paintBorderRect.maxY(), side, color, SOLID,
808                             adjacent1BigThird, adjacent2BigThird, antialias);
809
810                         paintBorderRect = snapRectToDevicePixels(LayoutRect(x1 + mitreOffset2, y2 - thirdOfThickness, (x2 - mitreOffset4) - (x1 + mitreOffset2), thirdOfThickness), deviceScaleFactor);
811                         drawLineForBoxSide(graphicsContext, paintBorderRect.x(), paintBorderRect.y(), paintBorderRect.maxX(), paintBorderRect.maxY(), side, color, SOLID,
812                             adjacent1BigThird, adjacent2BigThird, antialias);
813                         break;
814                     case BSLeft:
815                         paintBorderRect = snapRectToDevicePixels(LayoutRect(x1, y1 + mitreOffset1, thirdOfThickness, (y2 - mitreOffset3) - (y1 + mitreOffset1)), deviceScaleFactor);
816                         drawLineForBoxSide(graphicsContext, paintBorderRect.x(), paintBorderRect.y(), paintBorderRect.maxX(), paintBorderRect.maxY(), side, color, SOLID,
817                             adjacent1BigThird, adjacent2BigThird, antialias);
818
819                         paintBorderRect = snapRectToDevicePixels(LayoutRect(x2 - thirdOfThickness, y1 + mitreOffset2, thirdOfThickness, (y2 - mitreOffset4) - (y1 + mitreOffset2)), deviceScaleFactor);
820                         drawLineForBoxSide(graphicsContext, paintBorderRect.x(), paintBorderRect.y(), paintBorderRect.maxX(), paintBorderRect.maxY(), side, color, SOLID,
821                             adjacent1BigThird, adjacent2BigThird, antialias);
822                         break;
823                     case BSBottom:
824                         paintBorderRect = snapRectToDevicePixels(LayoutRect(x1 + mitreOffset2, y1, (x2 - mitreOffset4) - (x1 + mitreOffset2), thirdOfThickness), deviceScaleFactor);
825                         drawLineForBoxSide(graphicsContext, paintBorderRect.x(), paintBorderRect.y(), paintBorderRect.maxX(), paintBorderRect.maxY(), side, color, SOLID,
826                             adjacent1BigThird, adjacent2BigThird, antialias);
827
828                         paintBorderRect = snapRectToDevicePixels(LayoutRect(x1 + mitreOffset1, y2 - thirdOfThickness, (x2 - mitreOffset3) - (x1 + mitreOffset1), thirdOfThickness), deviceScaleFactor);
829                         drawLineForBoxSide(graphicsContext, paintBorderRect.x(), paintBorderRect.y(), paintBorderRect.maxX(), paintBorderRect.maxY(), side, color, SOLID,
830                             adjacent1BigThird, adjacent2BigThird, antialias);
831                         break;
832                     case BSRight:
833                         paintBorderRect = snapRectToDevicePixels(LayoutRect(x1, y1 + mitreOffset2, thirdOfThickness, (y2 - mitreOffset4) - (y1 + mitreOffset2)), deviceScaleFactor);
834                         drawLineForBoxSide(graphicsContext, paintBorderRect.x(), paintBorderRect.y(), paintBorderRect.maxX(), paintBorderRect.maxY(), side, color, SOLID,
835                             adjacent1BigThird, adjacent2BigThird, antialias);
836
837                         paintBorderRect = snapRectToDevicePixels(LayoutRect(x2 - thirdOfThickness, y1 + mitreOffset1, thirdOfThickness, (y2 - mitreOffset3) - (y1 + mitreOffset1)), deviceScaleFactor);
838                         drawLineForBoxSide(graphicsContext, paintBorderRect.x(), paintBorderRect.y(), paintBorderRect.maxX(), paintBorderRect.maxY(), side, color, SOLID,
839                             adjacent1BigThird, adjacent2BigThird, antialias);
840                         break;
841                     default:
842                         break;
843                 }
844             }
845             break;
846         }
847         case RIDGE:
848         case GROOVE: {
849             EBorderStyle s1;
850             EBorderStyle s2;
851             if (borderStyle == GROOVE) {
852                 s1 = INSET;
853                 s2 = OUTSET;
854             } else {
855                 s1 = OUTSET;
856                 s2 = INSET;
857             }
858
859             float adjacent1BigHalf = ceilToDevicePixel(adjacentWidth1 / 2, deviceScaleFactor);
860             float adjacent2BigHalf = ceilToDevicePixel(adjacentWidth2 / 2, deviceScaleFactor);
861
862             float adjacent1SmallHalf = floorToDevicePixel(adjacentWidth1 / 2, deviceScaleFactor);
863             float adjacent2SmallHalf = floorToDevicePixel(adjacentWidth2 / 2, deviceScaleFactor);
864
865             float offset1 = 0;
866             float offset2 = 0;
867             float offset3 = 0;
868             float offset4 = 0;
869
870             if (((side == BSTop || side == BSLeft) && adjacentWidth1 < 0) || ((side == BSBottom || side == BSRight) && adjacentWidth1 > 0))
871                 offset1 = floorToDevicePixel(adjacentWidth1 / 2, deviceScaleFactor);
872
873             if (((side == BSTop || side == BSLeft) && adjacentWidth2 < 0) || ((side == BSBottom || side == BSRight) && adjacentWidth2 > 0))
874                 offset2 = ceilToDevicePixel(adjacentWidth2 / 2, deviceScaleFactor);
875
876             if (((side == BSTop || side == BSLeft) && adjacentWidth1 > 0) || ((side == BSBottom || side == BSRight) && adjacentWidth1 < 0))
877                 offset3 = floorToDevicePixel(fabs(adjacentWidth1) / 2, deviceScaleFactor);
878
879             if (((side == BSTop || side == BSLeft) && adjacentWidth2 > 0) || ((side == BSBottom || side == BSRight) && adjacentWidth2 < 0))
880                 offset4 = ceilToDevicePixel(adjacentWidth2 / 2, deviceScaleFactor);
881
882             float adjustedX = ceilToDevicePixel((x1 + x2) / 2, deviceScaleFactor);
883             float adjustedY = ceilToDevicePixel((y1 + y2) / 2, deviceScaleFactor);
884             /// Quads can't use the default snapping rect functions.
885             x1 = roundToDevicePixel(x1, deviceScaleFactor);
886             x2 = roundToDevicePixel(x2, deviceScaleFactor);
887             y1 = roundToDevicePixel(y1, deviceScaleFactor);
888             y2 = roundToDevicePixel(y2, deviceScaleFactor);
889
890             switch (side) {
891                 case BSTop:
892                     drawLineForBoxSide(graphicsContext, x1 + offset1, y1, x2 - offset2, adjustedY, side, color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias);
893                     drawLineForBoxSide(graphicsContext, x1 + offset3, adjustedY, x2 - offset4, y2, side, color, s2, adjacent1SmallHalf, adjacent2SmallHalf, antialias);
894                     break;
895                 case BSLeft:
896                     drawLineForBoxSide(graphicsContext, x1, y1 + offset1, adjustedX, y2 - offset2, side, color, s1, adjacent1BigHalf, adjacent2BigHalf, antialias);
897                     drawLineForBoxSide(graphicsContext, adjustedX, y1 + offset3, x2, y2 - offset4, side, color, s2, adjacent1SmallHalf, adjacent2SmallHalf, antialias);
898                     break;
899                 case BSBottom:
900                     drawLineForBoxSide(graphicsContext, x1 + offset1, y1, x2 - offset2, adjustedY, side, color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias);
901                     drawLineForBoxSide(graphicsContext, x1 + offset3, adjustedY, x2 - offset4, y2, side, color, s1, adjacent1SmallHalf, adjacent2SmallHalf, antialias);
902                     break;
903                 case BSRight:
904                     drawLineForBoxSide(graphicsContext, x1, y1 + offset1, adjustedX, y2 - offset2, side, color, s2, adjacent1BigHalf, adjacent2BigHalf, antialias);
905                     drawLineForBoxSide(graphicsContext, adjustedX, y1 + offset3, x2, y2 - offset4, side, color, s1, adjacent1SmallHalf, adjacent2SmallHalf, antialias);
906                     break;
907             }
908             break;
909         }
910         case INSET:
911             // FIXME: Maybe we should lighten the colors on one side like Firefox.
912             // https://bugs.webkit.org/show_bug.cgi?id=58608
913             if (side == BSTop || side == BSLeft)
914                 color = color.dark();
915             FALLTHROUGH;
916         case OUTSET:
917             if (borderStyle == OUTSET && (side == BSBottom || side == BSRight))
918                 color = color.dark();
919             FALLTHROUGH;
920         case SOLID: {
921             StrokeStyle oldStrokeStyle = graphicsContext->strokeStyle();
922             ASSERT(x2 >= x1);
923             ASSERT(y2 >= y1);
924             if (!adjacentWidth1 && !adjacentWidth2) {
925                 // Turn off antialiasing to match the behavior of drawConvexPolygon();
926                 // this matters for rects in transformed contexts.
927                 graphicsContext->setStrokeStyle(NoStroke);
928                 graphicsContext->setFillColor(color, style.colorSpace());
929                 bool wasAntialiased = graphicsContext->shouldAntialias();
930                 graphicsContext->setShouldAntialias(antialias);
931                 graphicsContext->drawRect(snapRectToDevicePixels(x1, y1, x2 - x1, y2 - y1, deviceScaleFactor));
932                 graphicsContext->setShouldAntialias(wasAntialiased);
933                 graphicsContext->setStrokeStyle(oldStrokeStyle);
934                 return;
935             }
936
937             // FIXME: These roundings should be replaced by ASSERT(device pixel positioned) when all the callers transitioned to device pixels.
938             x1 = roundToDevicePixel(x1, deviceScaleFactor);
939             y1 = roundToDevicePixel(y1, deviceScaleFactor);
940             x2 = roundToDevicePixel(x2, deviceScaleFactor);
941             y2 = roundToDevicePixel(y2, deviceScaleFactor);
942
943             FloatPoint quad[4];
944             switch (side) {
945                 case BSTop:
946                     quad[0] = FloatPoint(x1 + std::max<float>(-adjacentWidth1, 0), y1);
947                     quad[1] = FloatPoint(x1 + std::max<float>(adjacentWidth1, 0), y2);
948                     quad[2] = FloatPoint(x2 - std::max<float>(adjacentWidth2, 0), y2);
949                     quad[3] = FloatPoint(x2 - std::max<float>(-adjacentWidth2, 0), y1);
950                     break;
951                 case BSBottom:
952                     quad[0] = FloatPoint(x1 + std::max<float>(adjacentWidth1, 0), y1);
953                     quad[1] = FloatPoint(x1 + std::max<float>(-adjacentWidth1, 0), y2);
954                     quad[2] = FloatPoint(x2 - std::max<float>(-adjacentWidth2, 0), y2);
955                     quad[3] = FloatPoint(x2 - std::max<float>(adjacentWidth2, 0), y1);
956                     break;
957                 case BSLeft:
958                     quad[0] = FloatPoint(x1, y1 + std::max<float>(-adjacentWidth1, 0));
959                     quad[1] = FloatPoint(x1, y2 - std::max<float>(-adjacentWidth2, 0));
960                     quad[2] = FloatPoint(x2, y2 - std::max<float>(adjacentWidth2, 0));
961                     quad[3] = FloatPoint(x2, y1 + std::max<float>(adjacentWidth1, 0));
962                     break;
963                 case BSRight:
964                     quad[0] = FloatPoint(x1, y1 + std::max<float>(adjacentWidth1, 0));
965                     quad[1] = FloatPoint(x1, y2 - std::max<float>(adjacentWidth2, 0));
966                     quad[2] = FloatPoint(x2, y2 - std::max<float>(-adjacentWidth2, 0));
967                     quad[3] = FloatPoint(x2, y1 + std::max<float>(-adjacentWidth1, 0));
968                     break;
969             }
970
971             graphicsContext->setStrokeStyle(NoStroke);
972             graphicsContext->setFillColor(color, style.colorSpace());
973             graphicsContext->drawConvexPolygon(4, quad, antialias);
974             graphicsContext->setStrokeStyle(oldStrokeStyle);
975             break;
976         }
977     }
978 }
979
980 void RenderObject::paintFocusRing(PaintInfo& paintInfo, const LayoutPoint& paintOffset, RenderStyle* style)
981 {
982     ASSERT(style->outlineStyleIsAuto());
983
984     Vector<IntRect> focusRingRects;
985     addFocusRingRects(focusRingRects, paintOffset, paintInfo.paintContainer);
986 #if PLATFORM(MAC)
987     bool needsRepaint;
988     paintInfo.context->drawFocusRing(focusRingRects, style->outlineWidth(), style->outlineOffset(), document().page()->focusController().timeSinceFocusWasSet(), needsRepaint);
989     if (needsRepaint)
990         document().page()->focusController().setFocusedElementNeedsRepaint();
991 #else
992     paintInfo.context->drawFocusRing(focusRingRects, style->outlineWidth(), style->outlineOffset(), style->visitedDependentColor(CSSPropertyOutlineColor));
993 #endif
994 }
995
996 void RenderObject::addPDFURLRect(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
997 {
998     Vector<IntRect> focusRingRects;
999     addFocusRingRects(focusRingRects, paintOffset, paintInfo.paintContainer);
1000     IntRect urlRect = unionRect(focusRingRects);
1001
1002     if (urlRect.isEmpty())
1003         return;
1004     Node* node = this->node();
1005     if (!is<Element>(node) || !node->isLink())
1006         return;
1007     const AtomicString& href = downcast<Element>(*node).getAttribute(hrefAttr);
1008     if (href.isNull())
1009         return;
1010     paintInfo.context->setURLForRect(node->document().completeURL(href), snappedIntRect(urlRect));
1011 }
1012
1013 void RenderObject::paintOutline(PaintInfo& paintInfo, const LayoutRect& paintRect)
1014 {
1015     if (!hasOutline())
1016         return;
1017
1018     RenderStyle& styleToUse = style();
1019     LayoutUnit outlineWidth = styleToUse.outlineWidth();
1020
1021     int outlineOffset = styleToUse.outlineOffset();
1022
1023     // Only paint the focus ring by hand if the theme isn't able to draw it.
1024     if (styleToUse.outlineStyleIsAuto() && !theme().supportsFocusRing(styleToUse))
1025         paintFocusRing(paintInfo, paintRect.location(), &styleToUse);
1026
1027     if (hasOutlineAnnotation() && !styleToUse.outlineStyleIsAuto() && !theme().supportsFocusRing(styleToUse))
1028         addPDFURLRect(paintInfo, paintRect.location());
1029
1030     if (styleToUse.outlineStyleIsAuto() || styleToUse.outlineStyle() == BNONE)
1031         return;
1032
1033     IntRect inner = snappedIntRect(paintRect);
1034     inner.inflate(outlineOffset);
1035
1036     IntRect outer = snappedIntRect(inner);
1037     outer.inflate(outlineWidth);
1038
1039     // FIXME: This prevents outlines from painting inside the object. See bug 12042
1040     if (outer.isEmpty())
1041         return;
1042
1043     EBorderStyle outlineStyle = styleToUse.outlineStyle();
1044     Color outlineColor = styleToUse.visitedDependentColor(CSSPropertyOutlineColor);
1045
1046     GraphicsContext* graphicsContext = paintInfo.context;
1047     bool useTransparencyLayer = outlineColor.hasAlpha();
1048     if (useTransparencyLayer) {
1049         if (outlineStyle == SOLID) {
1050             Path path;
1051             path.addRect(outer);
1052             path.addRect(inner);
1053             graphicsContext->setFillRule(RULE_EVENODD);
1054             graphicsContext->setFillColor(outlineColor, styleToUse.colorSpace());
1055             graphicsContext->fillPath(path);
1056             return;
1057         }
1058         graphicsContext->beginTransparencyLayer(static_cast<float>(outlineColor.alpha()) / 255);
1059         outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineColor.blue());
1060     }
1061
1062     int leftOuter = outer.x();
1063     int leftInner = inner.x();
1064     int rightOuter = outer.maxX();
1065     int rightInner = inner.maxX();
1066     int topOuter = outer.y();
1067     int topInner = inner.y();
1068     int bottomOuter = outer.maxY();
1069     int bottomInner = inner.maxY();
1070     
1071     drawLineForBoxSide(graphicsContext, leftOuter, topOuter, leftInner, bottomOuter, BSLeft, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1072     drawLineForBoxSide(graphicsContext, leftOuter, topOuter, rightOuter, topInner, BSTop, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1073     drawLineForBoxSide(graphicsContext, rightInner, topOuter, rightOuter, bottomOuter, BSRight, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1074     drawLineForBoxSide(graphicsContext, leftOuter, bottomInner, rightOuter, bottomOuter, BSBottom, outlineColor, outlineStyle, outlineWidth, outlineWidth);
1075
1076     if (useTransparencyLayer)
1077         graphicsContext->endTransparencyLayer();
1078 }
1079
1080 #if PLATFORM(IOS)
1081 // This function is similar in spirit to RenderText::absoluteRectsForRange, but returns rectangles
1082 // which are annotated with additional state which helps iOS draw selections in its unique way.
1083 // No annotations are added in this class.
1084 // FIXME: Move to RenderText with absoluteRectsForRange()?
1085 void RenderObject::collectSelectionRects(Vector<SelectionRect>& rects, unsigned start, unsigned end)
1086 {
1087     Vector<FloatQuad> quads;
1088
1089     if (!firstChildSlow()) {
1090         // FIXME: WebKit's position for an empty span after a BR is incorrect, so we can't trust 
1091         // quads for them. We don't need selection rects for those anyway though, since they 
1092         // are just empty containers. See <https://bugs.webkit.org/show_bug.cgi?id=49358>.
1093         RenderObject* previous = previousSibling();
1094         Node* node = this->node();
1095         if (!previous || !previous->isBR() || !node || !node->isContainerNode() || !isInline()) {
1096             // For inline elements we don't use absoluteQuads, since it takes into account continuations and leads to wrong results.
1097             absoluteQuadsForSelection(quads);
1098         }
1099     } else {
1100         unsigned offset = start;
1101         for (RenderObject* child = childAt(start); child && offset < end; child = child->nextSibling(), ++offset)
1102             child->absoluteQuads(quads);
1103     }
1104
1105     unsigned numberOfQuads = quads.size();
1106     for (unsigned i = 0; i < numberOfQuads; ++i)
1107         rects.append(SelectionRect(quads[i].enclosingBoundingBox(), isHorizontalWritingMode(), view().pageNumberForBlockProgressionOffset(quads[i].enclosingBoundingBox().x())));
1108 }
1109 #endif
1110
1111 IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms) const
1112 {
1113     if (useTransforms) {
1114         Vector<FloatQuad> quads;
1115         absoluteQuads(quads);
1116
1117         size_t n = quads.size();
1118         if (!n)
1119             return IntRect();
1120     
1121         IntRect result = quads[0].enclosingBoundingBox();
1122         for (size_t i = 1; i < n; ++i)
1123             result.unite(quads[i].enclosingBoundingBox());
1124         return result;
1125     }
1126
1127     FloatPoint absPos = localToAbsolute();
1128     Vector<IntRect> rects;
1129     absoluteRects(rects, flooredLayoutPoint(absPos));
1130
1131     size_t n = rects.size();
1132     if (!n)
1133         return IntRect();
1134
1135     LayoutRect result = rects[0];
1136     for (size_t i = 1; i < n; ++i)
1137         result.unite(rects[i]);
1138     return snappedIntRect(result);
1139 }
1140
1141 void RenderObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
1142 {
1143     Vector<IntRect> rects;
1144     // FIXME: addFocusRingRects() needs to be passed this transform-unaware
1145     // localToAbsolute() offset here because RenderInline::addFocusRingRects()
1146     // implicitly assumes that. This doesn't work correctly with transformed
1147     // descendants.
1148     FloatPoint absolutePoint = localToAbsolute();
1149     addFocusRingRects(rects, flooredLayoutPoint(absolutePoint));
1150     size_t count = rects.size();
1151     for (size_t i = 0; i < count; ++i) {
1152         IntRect rect = rects[i];
1153         rect.move(-absolutePoint.x(), -absolutePoint.y());
1154         quads.append(localToAbsoluteQuad(FloatQuad(rect)));
1155     }
1156 }
1157
1158 FloatRect RenderObject::absoluteBoundingBoxRectForRange(const Range* range)
1159 {
1160     if (!range || !range->startContainer())
1161         return FloatRect();
1162
1163     range->ownerDocument().updateLayout();
1164
1165     Vector<FloatQuad> quads;
1166     range->textQuads(quads);
1167
1168     if (quads.isEmpty())
1169         return FloatRect();
1170
1171     FloatRect result = quads[0].boundingBox();
1172     for (size_t i = 1; i < quads.size(); ++i)
1173         result.uniteEvenIfEmpty(quads[i].boundingBox());
1174
1175     return result;
1176 }
1177
1178 void RenderObject::addAbsoluteRectForLayer(LayoutRect& result)
1179 {
1180     if (hasLayer())
1181         result.unite(absoluteBoundingBoxRectIgnoringTransforms());
1182     for (RenderObject* current = firstChildSlow(); current; current = current->nextSibling())
1183         current->addAbsoluteRectForLayer(result);
1184 }
1185
1186 // FIXME: change this to use the subtreePaint terminology
1187 LayoutRect RenderObject::paintingRootRect(LayoutRect& topLevelRect)
1188 {
1189     LayoutRect result = absoluteBoundingBoxRectIgnoringTransforms();
1190     topLevelRect = result;
1191     for (RenderObject* current = firstChildSlow(); current; current = current->nextSibling())
1192         current->addAbsoluteRectForLayer(result);
1193     return result;
1194 }
1195
1196 RenderLayerModelObject* RenderObject::containerForRepaint() const
1197 {
1198     RenderLayerModelObject* repaintContainer = 0;
1199
1200     if (view().usesCompositing()) {
1201         if (RenderLayer* parentLayer = enclosingLayer()) {
1202             RenderLayer* compLayer = parentLayer->enclosingCompositingLayerForRepaint();
1203             if (compLayer)
1204                 repaintContainer = &compLayer->renderer();
1205         }
1206     }
1207     if (view().hasSoftwareFilters()) {
1208         if (RenderLayer* parentLayer = enclosingLayer()) {
1209             RenderLayer* enclosingFilterLayer = parentLayer->enclosingFilterLayer();
1210             if (enclosingFilterLayer)
1211                 return &enclosingFilterLayer->renderer();
1212         }
1213     }
1214
1215     // If we have a flow thread, then we need to do individual repaints within the RenderRegions instead.
1216     // Return the flow thread as a repaint container in order to create a chokepoint that allows us to change
1217     // repainting to do individual region repaints.
1218     RenderFlowThread* parentRenderFlowThread = flowThreadContainingBlock();
1219     if (parentRenderFlowThread) {
1220         // If the element has a fixed positioned element with named flow as CB along the CB chain
1221         // then the repaint container is not the flow thread.
1222         if (hasFixedPosInNamedFlowContainingBlock(this))
1223             return repaintContainer;
1224         // If we have already found a repaint container then we will repaint into that container only if it is part of the same
1225         // flow thread. Otherwise we will need to catch the repaint call and send it to the flow thread.
1226         RenderFlowThread* repaintContainerFlowThread = repaintContainer ? repaintContainer->flowThreadContainingBlock() : 0;
1227         if (!repaintContainerFlowThread || repaintContainerFlowThread != parentRenderFlowThread)
1228             repaintContainer = parentRenderFlowThread;
1229     }
1230     return repaintContainer;
1231 }
1232
1233 void RenderObject::repaintUsingContainer(const RenderLayerModelObject* repaintContainer, const LayoutRect& r, bool shouldClipToLayer) const
1234 {
1235     if (!repaintContainer) {
1236         view().repaintViewRectangle(r);
1237         return;
1238     }
1239
1240     if (is<RenderFlowThread>(*repaintContainer)) {
1241         downcast<RenderFlowThread>(*repaintContainer).repaintRectangleInRegions(r);
1242         return;
1243     }
1244
1245     if (repaintContainer->hasFilter() && repaintContainer->layer() && repaintContainer->layer()->requiresFullLayerImageForFilters()) {
1246         repaintContainer->layer()->setFilterBackendNeedsRepaintingInRect(r);
1247         return;
1248     }
1249
1250     RenderView& v = view();
1251     if (repaintContainer->isRenderView()) {
1252         ASSERT(repaintContainer == &v);
1253         bool viewHasCompositedLayer = v.hasLayer() && v.layer()->isComposited();
1254         if (!viewHasCompositedLayer || v.layer()->backing()->paintsIntoWindow()) {
1255             v.repaintViewRectangle(viewHasCompositedLayer && v.layer()->transform() ? LayoutRect(v.layer()->transform()->mapRect(snapRectToDevicePixels(r, document().deviceScaleFactor()))) : r);
1256             return;
1257         }
1258     }
1259     
1260     if (v.usesCompositing()) {
1261         ASSERT(repaintContainer->hasLayer() && repaintContainer->layer()->isComposited());
1262         repaintContainer->layer()->setBackingNeedsRepaintInRect(r, shouldClipToLayer ? GraphicsLayer::ClipToLayer : GraphicsLayer::DoNotClipToLayer);
1263     }
1264 }
1265
1266 void RenderObject::repaint() const
1267 {
1268     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1269     RenderView* view;
1270     if (!isRooted(&view))
1271         return;
1272
1273     if (view->printing())
1274         return; // Don't repaint if we're printing.
1275
1276     RenderLayerModelObject* repaintContainer = containerForRepaint();
1277     repaintUsingContainer(repaintContainer ? repaintContainer : view, clippedOverflowRectForRepaint(repaintContainer));
1278 }
1279
1280 void RenderObject::repaintRectangle(const LayoutRect& r, bool shouldClipToLayer) const
1281 {
1282     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1283     RenderView* view;
1284     if (!isRooted(&view))
1285         return;
1286
1287     if (view->printing())
1288         return; // Don't repaint if we're printing.
1289
1290     LayoutRect dirtyRect(r);
1291
1292     // FIXME: layoutDelta needs to be applied in parts before/after transforms and
1293     // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
1294     dirtyRect.move(view->layoutDelta());
1295
1296     RenderLayerModelObject* repaintContainer = containerForRepaint();
1297     computeRectForRepaint(repaintContainer, dirtyRect);
1298     repaintUsingContainer(repaintContainer ? repaintContainer : view, dirtyRect, shouldClipToLayer);
1299 }
1300
1301 void RenderObject::repaintSlowRepaintObject() const
1302 {
1303     // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
1304     RenderView* view;
1305     if (!isRooted(&view))
1306         return;
1307
1308     // Don't repaint if we're printing.
1309     if (view->printing())
1310         return;
1311
1312     RenderLayerModelObject* repaintContainer = containerForRepaint();
1313     if (!repaintContainer)
1314         repaintContainer = view;
1315
1316     bool shouldClipToLayer = true;
1317     IntRect repaintRect;
1318
1319     // If this is the root background, we need to check if there is an extended background rect. If
1320     // there is, then we should not allow painting to clip to the layer size.
1321     if (isRoot() || isBody()) {
1322         shouldClipToLayer = !view->frameView().hasExtendedBackgroundRectForPainting();
1323         repaintRect = snappedIntRect(view->backgroundRect(view));
1324     } else
1325         repaintRect = snappedIntRect(clippedOverflowRectForRepaint(repaintContainer));
1326
1327     repaintUsingContainer(repaintContainer, repaintRect, shouldClipToLayer);
1328 }
1329
1330 IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
1331 {
1332     return snappedIntRect(absoluteClippedOverflowRect());
1333 }
1334
1335 bool RenderObject::checkForRepaintDuringLayout() const
1336 {
1337     return !document().view()->needsFullRepaint() && !hasLayer() && everHadLayout();
1338 }
1339
1340 LayoutRect RenderObject::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
1341 {
1342     LayoutRect r(clippedOverflowRectForRepaint(repaintContainer));
1343     r.inflate(outlineWidth);
1344     return r;
1345 }
1346
1347 LayoutRect RenderObject::clippedOverflowRectForRepaint(const RenderLayerModelObject*) const
1348 {
1349     ASSERT_NOT_REACHED();
1350     return LayoutRect();
1351 }
1352
1353 void RenderObject::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
1354 {
1355     if (repaintContainer == this)
1356         return;
1357
1358     if (auto* parent = this->parent()) {
1359         if (parent->hasOverflowClip()) {
1360             downcast<RenderBox>(*parent).applyCachedClipAndScrollOffsetForRepaint(rect);
1361             if (rect.isEmpty())
1362                 return;
1363         }
1364
1365         parent->computeRectForRepaint(repaintContainer, rect, fixed);
1366     }
1367 }
1368
1369 void RenderObject::computeFloatRectForRepaint(const RenderLayerModelObject*, FloatRect&, bool) const
1370 {
1371     ASSERT_NOT_REACHED();
1372 }
1373
1374 #ifndef NDEBUG
1375
1376 static void showRenderTreeLegend()
1377 {
1378     fprintf(stderr, "\n(R)elative/A(B)solute/Fi(X)ed/Stick(Y) positioned, (O)verflow clipping, (A)nonymous, (G)enerated, (F)loating, has(L)ayer, (C)omposited, (D)irty layout, Dirty (S)tyle\n");
1379 }
1380
1381 void RenderObject::showNodeTreeForThis() const
1382 {
1383     if (!node())
1384         return;
1385     node()->showTreeForThis();
1386 }
1387
1388 void RenderObject::showRenderTreeForThis() const
1389 {
1390     const WebCore::RenderObject* root = this;
1391     while (root->parent())
1392         root = root->parent();
1393     showRenderTreeLegend();
1394     root->showRenderSubTreeAndMark(this, 1);
1395 }
1396
1397 void RenderObject::showLineTreeForThis() const
1398 {
1399     if (!is<RenderBlockFlow>(*this))
1400         return;
1401     showRenderTreeLegend();
1402     showRenderObject(false, 1);
1403     downcast<RenderBlockFlow>(*this).showLineTreeAndMark(nullptr, 2);
1404 }
1405
1406 void RenderObject::showRegionsInformation() const
1407 {
1408     if (RenderFlowThread* flowThread = flowThreadContainingBlock()) {
1409         if (is<RenderBox>(*this)) {
1410             RenderRegion* startRegion = nullptr;
1411             RenderRegion* endRegion = nullptr;
1412             flowThread->getRegionRangeForBox(downcast<RenderBox>(this), startRegion, endRegion);
1413             fprintf(stderr, " [Rs:%p Re:%p]", startRegion, endRegion);
1414         }
1415     }
1416 }
1417
1418 void RenderObject::showRenderObject(bool mark, int depth) const
1419 {
1420 #if COMPILER(CLANG)
1421 #pragma clang diagnostic push
1422 #pragma clang diagnostic ignored "-Wunknown-pragmas"
1423 #pragma clang diagnostic ignored "-Wundefined-bool-conversion"
1424 #endif
1425     // As this function is intended to be used when debugging, the |this| pointer may be 0.
1426     if (!this) {
1427         fprintf(stderr, "(null)\n");
1428         return;
1429     }
1430 #if COMPILER(CLANG)
1431 #pragma clang diagnostic pop
1432 #endif
1433
1434     if (isPositioned()) {
1435         if (isRelPositioned())
1436             fputc('R', stderr);
1437         else if (isStickyPositioned())
1438             fputc('Y', stderr);
1439         else if (isOutOfFlowPositioned()) {
1440             if (style().position() == AbsolutePosition)
1441                 fputc('B', stderr);
1442             else
1443                 fputc('X', stderr);
1444         }
1445     } else
1446         fputc('-', stderr);
1447
1448     if (hasOverflowClip())
1449         fputc('O', stderr);
1450     else
1451         fputc('-', stderr);
1452
1453     if (isAnonymousBlock())
1454         fputc('A', stderr);
1455     else
1456         fputc('-', stderr);
1457
1458     if (isPseudoElement() || isAnonymous())
1459         fputc('G', stderr);
1460     else
1461         fputc('-', stderr);
1462
1463     if (isFloating())
1464         fputc('F', stderr);
1465     else
1466         fputc('-', stderr);
1467
1468     if (hasLayer())
1469         fputc('L', stderr);
1470     else
1471         fputc('-', stderr);
1472
1473     if (isComposited())
1474         fputc('C', stderr);
1475     else
1476         fputc('-', stderr);
1477
1478     fputc(' ', stderr);
1479
1480     if (needsLayout())
1481         fputc('D', stderr);
1482     else
1483         fputc('-', stderr);
1484
1485     if (node() && node()->needsStyleRecalc())
1486         fputc('S', stderr);
1487     else
1488         fputc('-', stderr);
1489
1490     int printedCharacters = 0;
1491     if (mark) {
1492         fprintf(stderr, "*");
1493         ++printedCharacters;
1494     }
1495
1496     while (++printedCharacters <= depth * 2)
1497         fputc(' ', stderr);
1498
1499     if (node())
1500         fprintf(stderr, "%s ", node()->nodeName().utf8().data());
1501
1502     String name = renderName();
1503     // FIXME: Renderer's name should not include property value listing.
1504     int pos = name.find('(');
1505     if (pos > 0)
1506         fprintf(stderr, "%s", name.left(pos - 1).utf8().data());
1507     else
1508         fprintf(stderr, "%s", name.utf8().data());
1509
1510     if (is<RenderBox>(*this)) {
1511         const auto& box = downcast<RenderBox>(*this);
1512         fprintf(stderr, "  (%.2f, %.2f) (%.2f, %.2f)", box.x().toFloat(), box.y().toFloat(), box.width().toFloat(), box.height().toFloat());
1513     }
1514
1515     fprintf(stderr, " renderer->(%p)", this);
1516     if (node()) {
1517         fprintf(stderr, " node->(%p)", node());
1518         if (node()->isTextNode()) {
1519             String value = node()->nodeValue();
1520             fprintf(stderr, " length->(%u)", value.length());
1521
1522             value.replaceWithLiteral('\\', "\\\\");
1523             value.replaceWithLiteral('\n', "\\n");
1524             
1525             const int maxPrintedLength = 80;
1526             if (value.length() > maxPrintedLength) {
1527                 String substring = value.substring(0, maxPrintedLength);
1528                 fprintf(stderr, " \"%s\"...", substring.utf8().data());
1529             } else
1530                 fprintf(stderr, " \"%s\"", value.utf8().data());
1531         }
1532     }
1533
1534     showRegionsInformation();
1535     fprintf(stderr, "\n");
1536 }
1537
1538 void RenderObject::showRenderSubTreeAndMark(const RenderObject* markedObject, int depth) const
1539 {
1540 #if COMPILER(CLANG)
1541 #pragma clang diagnostic push
1542 #pragma clang diagnostic ignored "-Wunknown-pragmas"
1543 #pragma clang diagnostic ignored "-Wundefined-bool-conversion"
1544 #endif
1545     // As this function is intended to be used when debugging, the |this| pointer may be 0.
1546     if (!this)
1547         return;
1548 #if COMPILER(CLANG)
1549 #pragma clang diagnostic pop
1550 #endif
1551
1552     showRenderObject(markedObject == this, depth);
1553     if (is<RenderBlockFlow>(*this))
1554         downcast<RenderBlockFlow>(*this).showLineTreeAndMark(nullptr, depth + 1);
1555
1556     for (const RenderObject* child = firstChildSlow(); child; child = child->nextSibling())
1557         child->showRenderSubTreeAndMark(markedObject, depth + 1);
1558 }
1559
1560 #endif // NDEBUG
1561
1562 Color RenderObject::selectionBackgroundColor() const
1563 {
1564     Color color;
1565     if (style().userSelect() != SELECT_NONE) {
1566         if (frame().selection().shouldShowBlockCursor() && frame().selection().isCaret())
1567             color = style().visitedDependentColor(CSSPropertyColor).blendWithWhite();
1568         else {
1569             RefPtr<RenderStyle> pseudoStyle = selectionPseudoStyle();
1570             if (pseudoStyle && pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
1571                 color = pseudoStyle->visitedDependentColor(CSSPropertyBackgroundColor).blendWithWhite();
1572             else
1573                 color = frame().selection().isFocusedAndActive() ? theme().activeSelectionBackgroundColor() : theme().inactiveSelectionBackgroundColor();
1574         }
1575     }
1576
1577     return color;
1578 }
1579
1580 Color RenderObject::selectionColor(int colorProperty) const
1581 {
1582     Color color;
1583     // If the element is unselectable, or we are only painting the selection,
1584     // don't override the foreground color with the selection foreground color.
1585     if (style().userSelect() == SELECT_NONE
1586         || (view().frameView().paintBehavior() & PaintBehaviorSelectionOnly))
1587         return color;
1588
1589     if (RefPtr<RenderStyle> pseudoStyle = selectionPseudoStyle()) {
1590         color = pseudoStyle->visitedDependentColor(colorProperty);
1591         if (!color.isValid())
1592             color = pseudoStyle->visitedDependentColor(CSSPropertyColor);
1593     } else
1594         color = frame().selection().isFocusedAndActive() ? theme().activeSelectionForegroundColor() : theme().inactiveSelectionForegroundColor();
1595
1596     return color;
1597 }
1598
1599 PassRefPtr<RenderStyle> RenderObject::selectionPseudoStyle() const
1600 {
1601     if (isAnonymous())
1602         return nullptr;
1603
1604     if (ShadowRoot* root = m_node.containingShadowRoot()) {
1605         if (root->type() == ShadowRoot::UserAgentShadowRoot) {
1606             if (Element* shadowHost = m_node.shadowHost())
1607                 return shadowHost->renderer()->getUncachedPseudoStyle(PseudoStyleRequest(SELECTION));
1608         }
1609     }
1610
1611     return getUncachedPseudoStyle(PseudoStyleRequest(SELECTION));
1612 }
1613
1614 Color RenderObject::selectionForegroundColor() const
1615 {
1616     return selectionColor(CSSPropertyWebkitTextFillColor);
1617 }
1618
1619 Color RenderObject::selectionEmphasisMarkColor() const
1620 {
1621     return selectionColor(CSSPropertyWebkitTextEmphasisColor);
1622 }
1623
1624 SelectionSubtreeRoot& RenderObject::selectionRoot() const
1625 {
1626     RenderFlowThread* flowThread = flowThreadContainingBlock();
1627     if (is<RenderNamedFlowThread>(flowThread))
1628         return downcast<RenderNamedFlowThread>(*flowThread);
1629
1630     return view();
1631 }
1632
1633 void RenderObject::selectionStartEnd(int& spos, int& epos) const
1634 {
1635     selectionRoot().selectionStartEndPositions(spos, epos);
1636 }
1637
1638 FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, MapCoordinatesFlags mode) const
1639 {
1640     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
1641     mapLocalToContainer(0, transformState, mode | ApplyContainerFlip);
1642     transformState.flatten();
1643     
1644     return transformState.lastPlanarPoint();
1645 }
1646
1647 FloatPoint RenderObject::absoluteToLocal(const FloatPoint& containerPoint, MapCoordinatesFlags mode) const
1648 {
1649     TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint);
1650     mapAbsoluteToLocalPoint(mode, transformState);
1651     transformState.flatten();
1652     
1653     return transformState.lastPlanarPoint();
1654 }
1655
1656 FloatQuad RenderObject::absoluteToLocalQuad(const FloatQuad& quad, MapCoordinatesFlags mode) const
1657 {
1658     TransformState transformState(TransformState::UnapplyInverseTransformDirection, quad.boundingBox().center(), quad);
1659     mapAbsoluteToLocalPoint(mode, transformState);
1660     transformState.flatten();
1661     return transformState.lastPlanarQuad();
1662 }
1663
1664 void RenderObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
1665 {
1666     if (repaintContainer == this)
1667         return;
1668
1669     auto* parent = this->parent();
1670     if (!parent)
1671         return;
1672
1673     // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
1674     LayoutPoint centerPoint(transformState.mappedPoint());
1675     if (mode & ApplyContainerFlip && is<RenderBox>(*parent)) {
1676         if (parent->style().isFlippedBlocksWritingMode())
1677             transformState.move(downcast<RenderBox>(parent)->flipForWritingMode(LayoutPoint(transformState.mappedPoint())) - centerPoint);
1678         mode &= ~ApplyContainerFlip;
1679     }
1680
1681     if (is<RenderBox>(*parent))
1682         transformState.move(-downcast<RenderBox>(*parent).scrolledContentOffset());
1683
1684     parent->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed);
1685 }
1686
1687 const RenderObject* RenderObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
1688 {
1689     ASSERT_UNUSED(ancestorToStopAt, ancestorToStopAt != this);
1690
1691     auto* container = parent();
1692     if (!container)
1693         return nullptr;
1694
1695     // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
1696     LayoutSize offset;
1697     if (is<RenderBox>(*container))
1698         offset = -downcast<RenderBox>(*container).scrolledContentOffset();
1699
1700     geometryMap.push(this, offset, false);
1701     
1702     return container;
1703 }
1704
1705 void RenderObject::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
1706 {
1707     if (auto* parent = this->parent()) {
1708         parent->mapAbsoluteToLocalPoint(mode, transformState);
1709         if (is<RenderBox>(*parent))
1710             transformState.move(downcast<RenderBox>(*parent).scrolledContentOffset());
1711     }
1712 }
1713
1714 bool RenderObject::shouldUseTransformFromContainer(const RenderObject* containerObject) const
1715 {
1716 #if ENABLE(3D_RENDERING)
1717     // hasTransform() indicates whether the object has transform, transform-style or perspective. We just care about transform,
1718     // so check the layer's transform directly.
1719     return (hasLayer() && downcast<RenderLayerModelObject>(*this).layer()->transform()) || (containerObject && containerObject->style().hasPerspective());
1720 #else
1721     UNUSED_PARAM(containerObject);
1722     return hasTransform();
1723 #endif
1724 }
1725
1726 void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const LayoutSize& offsetInContainer, TransformationMatrix& transform) const
1727 {
1728     transform.makeIdentity();
1729     transform.translate(offsetInContainer.width(), offsetInContainer.height());
1730     RenderLayer* layer;
1731     if (hasLayer() && (layer = downcast<RenderLayerModelObject>(*this).layer()) && layer->transform())
1732         transform.multiply(layer->currentTransform());
1733     
1734 #if ENABLE(3D_RENDERING)
1735     if (containerObject && containerObject->hasLayer() && containerObject->style().hasPerspective()) {
1736         // Perpsective on the container affects us, so we have to factor it in here.
1737         ASSERT(containerObject->hasLayer());
1738         FloatPoint perspectiveOrigin = downcast<RenderLayerModelObject>(*containerObject).layer()->perspectiveOrigin();
1739
1740         TransformationMatrix perspectiveMatrix;
1741         perspectiveMatrix.applyPerspective(containerObject->style().perspective());
1742         
1743         transform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0);
1744         transform = perspectiveMatrix * transform;
1745         transform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0);
1746     }
1747 #else
1748     UNUSED_PARAM(containerObject);
1749 #endif
1750 }
1751
1752 FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const
1753 {
1754     // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
1755     // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
1756     TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), localQuad);
1757     mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
1758     transformState.flatten();
1759     
1760     return transformState.lastPlanarQuad();
1761 }
1762
1763 FloatPoint RenderObject::localToContainerPoint(const FloatPoint& localPoint, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const
1764 {
1765     TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
1766     mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
1767     transformState.flatten();
1768
1769     return transformState.lastPlanarPoint();
1770 }
1771
1772 LayoutSize RenderObject::offsetFromContainer(RenderElement& container, const LayoutPoint&, bool* offsetDependsOnPoint) const
1773 {
1774     ASSERT(&container == this->container());
1775
1776     LayoutSize offset;
1777     if (is<RenderBox>(container))
1778         offset -= downcast<RenderBox>(container).scrolledContentOffset();
1779
1780     if (offsetDependsOnPoint)
1781         *offsetDependsOnPoint = is<RenderFlowThread>(container);
1782
1783     return offset;
1784 }
1785
1786 LayoutSize RenderObject::offsetFromAncestorContainer(RenderElement& container) const
1787 {
1788     LayoutSize offset;
1789     LayoutPoint referencePoint;
1790     const RenderObject* currContainer = this;
1791     do {
1792         RenderElement* nextContainer = currContainer->container();
1793         ASSERT(nextContainer);  // This means we reached the top without finding container.
1794         if (!nextContainer)
1795             break;
1796         ASSERT(!currContainer->hasTransform());
1797         LayoutSize currentOffset = currContainer->offsetFromContainer(*nextContainer, referencePoint);
1798         offset += currentOffset;
1799         referencePoint.move(currentOffset);
1800         currContainer = nextContainer;
1801     } while (currContainer != &container);
1802
1803     return offset;
1804 }
1805
1806 LayoutRect RenderObject::localCaretRect(InlineBox*, int, LayoutUnit* extraWidthToEndOfLine)
1807 {
1808     if (extraWidthToEndOfLine)
1809         *extraWidthToEndOfLine = 0;
1810
1811     return LayoutRect();
1812 }
1813
1814 bool RenderObject::isRooted(RenderView** view) const
1815 {
1816     const RenderObject* renderer = this;
1817     while (renderer->parent())
1818         renderer = renderer->parent();
1819
1820     if (!is<RenderView>(*renderer))
1821         return false;
1822
1823     if (view)
1824         *view = const_cast<RenderView*>(downcast<RenderView>(renderer));
1825
1826     return true;
1827 }
1828
1829 RespectImageOrientationEnum RenderObject::shouldRespectImageOrientation() const
1830 {
1831 #if USE(CG) || USE(CAIRO)
1832     // This can only be enabled for ports which honor the orientation flag in their drawing code.
1833     if (document().isImageDocument())
1834         return RespectImageOrientation;
1835 #endif
1836     // Respect the image's orientation if it's being used as a full-page image or it's
1837     // an <img> and the setting to respect it everywhere is set.
1838     return (frame().settings().shouldRespectImageOrientation() && is<HTMLImageElement>(node())) ? RespectImageOrientation : DoNotRespectImageOrientation;
1839 }
1840
1841 bool RenderObject::hasOutlineAnnotation() const
1842 {
1843     return node() && node()->isLink() && document().printing();
1844 }
1845
1846 bool RenderObject::hasEntirelyFixedBackground() const
1847 {
1848     return style().hasEntirelyFixedBackground();
1849 }
1850
1851 RenderElement* RenderObject::container(const RenderLayerModelObject* repaintContainer, bool* repaintContainerSkipped) const
1852 {
1853     if (repaintContainerSkipped)
1854         *repaintContainerSkipped = false;
1855
1856     // This method is extremely similar to containingBlock(), but with a few notable
1857     // exceptions.
1858     // (1) It can be used on orphaned subtrees, i.e., it can be called safely even when
1859     // the object is not part of the primary document subtree yet.
1860     // (2) For normal flow elements, it just returns the parent.
1861     // (3) For absolute positioned elements, it will return a relative positioned inline.
1862     // containingBlock() simply skips relpositioned inlines and lets an enclosing block handle
1863     // the layout of the positioned object.  This does mean that computePositionedLogicalWidth and
1864     // computePositionedLogicalHeight have to use container().
1865     auto o = parent();
1866
1867     if (isText())
1868         return o;
1869
1870     EPosition pos = style().position();
1871     if (pos == FixedPosition) {
1872         // container() can be called on an object that is not in the
1873         // tree yet.  We don't call view() since it will assert if it
1874         // can't get back to the canvas.  Instead we just walk as high up
1875         // as we can.  If we're in the tree, we'll get the root.  If we
1876         // aren't we'll get the root of our little subtree (most likely
1877         // we'll just return 0).
1878         // FIXME: The definition of view() has changed to not crawl up the render tree.  It might
1879         // be safe now to use it.
1880         while (o && o->parent() && !(o->hasTransform() && o->isRenderBlock())) {
1881             // foreignObject is the containing block for its contents.
1882             if (o->isSVGForeignObject())
1883                 break;
1884
1885             // The render flow thread is the top most containing block
1886             // for the fixed positioned elements.
1887             if (o->isOutOfFlowRenderFlowThread())
1888                 break;
1889
1890             if (repaintContainerSkipped && o == repaintContainer)
1891                 *repaintContainerSkipped = true;
1892
1893             o = o->parent();
1894         }
1895     } else if (pos == AbsolutePosition) {
1896         // Same goes here.  We technically just want our containing block, but
1897         // we may not have one if we're part of an uninstalled subtree.  We'll
1898         // climb as high as we can though.
1899         while (o && o->style().position() == StaticPosition && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) {
1900             if (o->isSVGForeignObject()) // foreignObject is the containing block for contents inside it
1901                 break;
1902
1903             if (repaintContainerSkipped && o == repaintContainer)
1904                 *repaintContainerSkipped = true;
1905
1906             o = o->parent();
1907         }
1908     }
1909
1910     return o;
1911 }
1912
1913 bool RenderObject::isSelectionBorder() const
1914 {
1915     SelectionState st = selectionState();
1916     return st == SelectionStart
1917         || st == SelectionEnd
1918         || st == SelectionBoth
1919         || view().selectionUnsplitStart() == this
1920         || view().selectionUnsplitEnd() == this;
1921 }
1922
1923 inline void RenderObject::clearLayoutRootIfNeeded() const
1924 {
1925     if (documentBeingDestroyed())
1926         return;
1927
1928     if (view().frameView().layoutRoot() == this) {
1929         ASSERT_NOT_REACHED();
1930         // This indicates a failure to layout the child, which is why
1931         // the layout root is still set to |this|. Make sure to clear it
1932         // since we are getting destroyed.
1933         view().frameView().clearLayoutRoot();
1934     }
1935 }
1936
1937 void RenderObject::willBeDestroyed()
1938 {
1939     // For accessibility management, notify the parent of the imminent change to its child set.
1940     // We do it now, before remove(), while the parent pointer is still available.
1941     if (AXObjectCache* cache = document().existingAXObjectCache())
1942         cache->childrenChanged(this->parent());
1943
1944     removeFromParent();
1945
1946     ASSERT(documentBeingDestroyed() || !is<RenderElement>(*this) || !view().frameView().hasSlowRepaintObject(downcast<RenderElement>(this)));
1947
1948     // The remove() call above may invoke axObjectCache()->childrenChanged() on the parent, which may require the AX render
1949     // object for this renderer. So we remove the AX render object now, after the renderer is removed.
1950     if (AXObjectCache* cache = document().existingAXObjectCache())
1951         cache->remove(this);
1952
1953     // FIXME: Would like to do this in RenderBoxModelObject, but the timing is so complicated that this can't easily
1954     // be moved into RenderBoxModelObject::destroy.
1955     if (hasLayer()) {
1956         setHasLayer(false);
1957         downcast<RenderLayerModelObject>(*this).destroyLayer();
1958     }
1959
1960     clearLayoutRootIfNeeded();
1961 }
1962
1963 void RenderObject::insertedIntoTree()
1964 {
1965     // FIXME: We should ASSERT(isRooted()) here but generated content makes some out-of-order insertion.
1966
1967     if (!isFloating() && parent()->childrenInline())
1968         parent()->dirtyLinesFromChangedChild(*this);
1969
1970     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
1971         flowThread->flowThreadDescendantInserted(this);
1972 }
1973
1974 void RenderObject::willBeRemovedFromTree()
1975 {
1976     // FIXME: We should ASSERT(isRooted()) but we have some out-of-order removals which would need to be fixed first.
1977
1978     removeFromRenderFlowThread();
1979
1980     // Update cached boundaries in SVG renderers, if a child is removed.
1981     parent()->setNeedsBoundariesUpdate();
1982 }
1983
1984 void RenderObject::removeFromRenderFlowThread()
1985 {
1986     if (flowThreadState() == NotInsideFlowThread)
1987         return;
1988
1989     // Sometimes we remove the element from the flow, but it's not destroyed at that time.
1990     // It's only until later when we actually destroy it and remove all the children from it.
1991     // Currently, that happens for firstLetter elements and list markers.
1992     // Pass in the flow thread so that we don't have to look it up for all the children.
1993     removeFromRenderFlowThreadIncludingDescendants(true);
1994 }
1995
1996 void RenderObject::removeFromRenderFlowThreadIncludingDescendants(bool shouldUpdateState)
1997 {
1998     // Once we reach another flow thread we don't need to update the flow thread state
1999     // but we have to continue cleanup the flow thread info.
2000     if (isRenderFlowThread())
2001         shouldUpdateState = false;
2002
2003     for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling())
2004         child->removeFromRenderFlowThreadIncludingDescendants(shouldUpdateState);
2005
2006     // We have to ask for our containing flow thread as it may be above the removed sub-tree.
2007     RenderFlowThread* flowThreadContainingBlock = this->flowThreadContainingBlock();
2008     if (flowThreadContainingBlock)
2009         flowThreadContainingBlock->removeFlowChildInfo(this);
2010     if (is<RenderBlock>(*this))
2011         downcast<RenderBlock>(*this).setCachedFlowThreadContainingBlockNeedsUpdate();
2012     if (shouldUpdateState)
2013         setFlowThreadState(NotInsideFlowThread);
2014 }
2015
2016 void RenderObject::invalidateFlowThreadContainingBlockIncludingDescendants(RenderFlowThread* flowThread)
2017 {
2018     if (flowThreadState() == NotInsideFlowThread)
2019         return;
2020
2021     if (is<RenderBlock>(*this)) {
2022         RenderBlock& block = downcast<RenderBlock>(*this);
2023
2024         if (block.cachedFlowThreadContainingBlockNeedsUpdate())
2025             return;
2026
2027         flowThread = block.cachedFlowThreadContainingBlock();
2028         block.setCachedFlowThreadContainingBlockNeedsUpdate();
2029     }
2030
2031     if (flowThread)
2032         flowThread->removeFlowChildInfo(this);
2033
2034     for (RenderObject* child = firstChildSlow(); child; child = child->nextSibling())
2035         child->invalidateFlowThreadContainingBlockIncludingDescendants(flowThread);
2036 }
2037
2038 void RenderObject::destroyAndCleanupAnonymousWrappers()
2039 {
2040     // If the tree is destroyed, there is no need for a clean-up phase.
2041     if (documentBeingDestroyed()) {
2042         destroy();
2043         return;
2044     }
2045
2046     RenderObject* destroyRoot = this;
2047     for (auto destroyRootParent = destroyRoot->parent(); destroyRootParent && destroyRootParent->isAnonymous(); destroyRoot = destroyRootParent, destroyRootParent = destroyRootParent->parent()) {
2048         // Currently we only remove anonymous cells' and table sections' wrappers but we should remove all unneeded
2049         // wrappers. See http://webkit.org/b/52123 as an example where this is needed.
2050         if (!destroyRootParent->isTableCell() && !destroyRootParent->isTableSection())
2051             break;
2052
2053         if (destroyRootParent->firstChild() != this || destroyRootParent->lastChild() != this)
2054             break;
2055     }
2056
2057     destroyRoot->destroy();
2058
2059     // WARNING: |this| is deleted here.
2060 }
2061
2062 void RenderObject::destroy()
2063 {
2064 #if PLATFORM(IOS)
2065     if (hasLayer())
2066         downcast<RenderBoxModelObject>(*this).layer()->willBeDestroyed();
2067 #endif
2068
2069     willBeDestroyed();
2070     delete this;
2071 }
2072
2073 VisiblePosition RenderObject::positionForPoint(const LayoutPoint&, const RenderRegion*)
2074 {
2075     return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
2076 }
2077
2078 void RenderObject::updateDragState(bool dragOn)
2079 {
2080     bool valueChanged = (dragOn != isDragging());
2081     setIsDragging(dragOn);
2082     if (valueChanged && node() && (style().affectedByDrag() || (is<Element>(*node()) && downcast<Element>(*node()).childrenAffectedByDrag())))
2083         node()->setNeedsStyleRecalc();
2084     for (RenderObject* curr = firstChildSlow(); curr; curr = curr->nextSibling())
2085         curr->updateDragState(dragOn);
2086 }
2087
2088 bool RenderObject::isComposited() const
2089 {
2090     return hasLayer() && downcast<RenderLayerModelObject>(*this).layer()->isComposited();
2091 }
2092
2093 bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter hitTestFilter)
2094 {
2095     bool inside = false;
2096     if (hitTestFilter != HitTestSelf) {
2097         // First test the foreground layer (lines and inlines).
2098         inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestForeground);
2099
2100         // Test floats next.
2101         if (!inside)
2102             inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestFloat);
2103
2104         // Finally test to see if the mouse is in the background (within a child block's background).
2105         if (!inside)
2106             inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestChildBlockBackgrounds);
2107     }
2108
2109     // See if the mouse is inside us but not any of our descendants
2110     if (hitTestFilter != HitTestDescendants && !inside)
2111         inside = nodeAtPoint(request, result, locationInContainer, accumulatedOffset, HitTestBlockBackground);
2112
2113     return inside;
2114 }
2115
2116 void RenderObject::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
2117 {
2118     if (result.innerNode())
2119         return;
2120
2121     Node* node = this->node();
2122
2123     // If we hit the anonymous renderers inside generated content we should
2124     // actually hit the generated content so walk up to the PseudoElement.
2125     if (!node && parent() && parent()->isBeforeOrAfterContent()) {
2126         for (auto renderer = parent(); renderer && !node; renderer = renderer->parent())
2127             node = renderer->element();
2128     }
2129
2130     if (node) {
2131         result.setInnerNode(node);
2132         if (!result.innerNonSharedNode())
2133             result.setInnerNonSharedNode(node);
2134         result.setLocalPoint(point);
2135     }
2136 }
2137
2138 bool RenderObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& /*locationInContainer*/, const LayoutPoint& /*accumulatedOffset*/, HitTestAction)
2139 {
2140     return false;
2141 }
2142
2143 int RenderObject::innerLineHeight() const
2144 {
2145     return style().computedLineHeight();
2146 }
2147
2148 RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const
2149 {
2150     if (pseudo < FIRST_INTERNAL_PSEUDOID && !style().hasPseudoStyle(pseudo))
2151         return 0;
2152
2153     RenderStyle* cachedStyle = style().getCachedPseudoStyle(pseudo);
2154     if (cachedStyle)
2155         return cachedStyle;
2156     
2157     RefPtr<RenderStyle> result = getUncachedPseudoStyle(PseudoStyleRequest(pseudo), parentStyle);
2158     if (result)
2159         return style().addCachedPseudoStyle(result.release());
2160     return 0;
2161 }
2162
2163 PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle, RenderStyle* ownStyle) const
2164 {
2165     if (pseudoStyleRequest.pseudoId < FIRST_INTERNAL_PSEUDOID && !ownStyle && !style().hasPseudoStyle(pseudoStyleRequest.pseudoId))
2166         return nullptr;
2167     
2168     if (!parentStyle) {
2169         ASSERT(!ownStyle);
2170         parentStyle = &style();
2171     }
2172
2173     // FIXME: This "find nearest element parent" should be a helper function.
2174     Node* node = this->node();
2175     while (node && !is<Element>(*node))
2176         node = node->parentNode();
2177     if (!node)
2178         return nullptr;
2179     Element& element = downcast<Element>(*node);
2180
2181     if (pseudoStyleRequest.pseudoId == FIRST_LINE_INHERITED) {
2182         RefPtr<RenderStyle> result = document().ensureStyleResolver().styleForElement(&element, parentStyle, DisallowStyleSharing);
2183         result->setStyleType(FIRST_LINE_INHERITED);
2184         return result.release();
2185     }
2186
2187     return document().ensureStyleResolver().pseudoStyleForElement(&element, pseudoStyleRequest, parentStyle);
2188 }
2189
2190 static Color decorationColor(RenderStyle* style)
2191 {
2192     Color result;
2193     // Check for text decoration color first.
2194     result = style->visitedDependentColor(CSSPropertyWebkitTextDecorationColor);
2195     if (result.isValid())
2196         return result;
2197     if (style->textStrokeWidth() > 0) {
2198         // Prefer stroke color if possible but not if it's fully transparent.
2199         result = style->visitedDependentColor(CSSPropertyWebkitTextStrokeColor);
2200         if (result.alpha())
2201             return result;
2202     }
2203     
2204     result = style->visitedDependentColor(CSSPropertyWebkitTextFillColor);
2205     return result;
2206 }
2207
2208 void RenderObject::getTextDecorationColors(int decorations, Color& underline, Color& overline,
2209                                            Color& linethrough, bool quirksMode, bool firstlineStyle)
2210 {
2211     RenderObject* current = this;
2212     RenderStyle* styleToUse = nullptr;
2213     TextDecoration currDecs = TextDecorationNone;
2214     Color resultColor;
2215     do {
2216         styleToUse = firstlineStyle ? &current->firstLineStyle() : &current->style();
2217         currDecs = styleToUse->textDecoration();
2218         resultColor = decorationColor(styleToUse);
2219         // Parameter 'decorations' is cast as an int to enable the bitwise operations below.
2220         if (currDecs) {
2221             if (currDecs & TextDecorationUnderline) {
2222                 decorations &= ~TextDecorationUnderline;
2223                 underline = resultColor;
2224             }
2225             if (currDecs & TextDecorationOverline) {
2226                 decorations &= ~TextDecorationOverline;
2227                 overline = resultColor;
2228             }
2229             if (currDecs & TextDecorationLineThrough) {
2230                 decorations &= ~TextDecorationLineThrough;
2231                 linethrough = resultColor;
2232             }
2233         }
2234         if (current->isRubyText())
2235             return;
2236         current = current->parent();
2237         if (current && current->isAnonymousBlock() && downcast<RenderBlock>(*current).continuation())
2238             current = downcast<RenderBlock>(*current).continuation();
2239     } while (current && decorations && (!quirksMode || !current->node() || (!is<HTMLAnchorElement>(*current->node()) && !current->node()->hasTagName(fontTag))));
2240
2241     // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
2242     if (decorations && current) {
2243         styleToUse = firstlineStyle ? &current->firstLineStyle() : &current->style();
2244         resultColor = decorationColor(styleToUse);
2245         if (decorations & TextDecorationUnderline)
2246             underline = resultColor;
2247         if (decorations & TextDecorationOverline)
2248             overline = resultColor;
2249         if (decorations & TextDecorationLineThrough)
2250             linethrough = resultColor;
2251     }
2252 }
2253
2254 #if ENABLE(DASHBOARD_SUPPORT)
2255 void RenderObject::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
2256 {
2257     // Convert the style regions to absolute coordinates.
2258     if (style().visibility() != VISIBLE || !is<RenderBox>(*this))
2259         return;
2260     
2261     auto& box = downcast<RenderBox>(*this);
2262     FloatPoint absPos = localToAbsolute();
2263
2264     const Vector<StyleDashboardRegion>& styleRegions = style().dashboardRegions();
2265     for (const auto& styleRegion : styleRegions) {
2266         LayoutUnit w = box.width();
2267         LayoutUnit h = box.height();
2268
2269         AnnotatedRegionValue region;
2270         region.label = styleRegion.label;
2271         region.bounds = LayoutRect(styleRegion.offset.left().value(),
2272                                    styleRegion.offset.top().value(),
2273                                    w - styleRegion.offset.left().value() - styleRegion.offset.right().value(),
2274                                    h - styleRegion.offset.top().value() - styleRegion.offset.bottom().value());
2275         region.type = styleRegion.type;
2276
2277         region.clip = region.bounds;
2278         computeAbsoluteRepaintRect(region.clip);
2279         if (region.clip.height() < 0) {
2280             region.clip.setHeight(0);
2281             region.clip.setWidth(0);
2282         }
2283
2284         region.bounds.setX(absPos.x() + styleRegion.offset.left().value());
2285         region.bounds.setY(absPos.y() + styleRegion.offset.top().value());
2286
2287         regions.append(region);
2288     }
2289 }
2290
2291 void RenderObject::collectAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
2292 {
2293     // RenderTexts don't have their own style, they just use their parent's style,
2294     // so we don't want to include them.
2295     if (is<RenderText>(*this))
2296         return;
2297
2298     addAnnotatedRegions(regions);
2299     for (RenderObject* current = downcast<RenderElement>(*this).firstChild(); current; current = current->nextSibling())
2300         current->collectAnnotatedRegions(regions);
2301 }
2302 #endif
2303
2304 int RenderObject::maximalOutlineSize(PaintPhase p) const
2305 {
2306     if (p != PaintPhaseOutline && p != PaintPhaseSelfOutline && p != PaintPhaseChildOutlines)
2307         return 0;
2308     return view().maximalOutlineSize();
2309 }
2310
2311 int RenderObject::caretMinOffset() const
2312 {
2313     return 0;
2314 }
2315
2316 int RenderObject::caretMaxOffset() const
2317 {
2318     if (isReplaced())
2319         return node() ? std::max(1U, node()->countChildNodes()) : 1;
2320     if (isHR())
2321         return 1;
2322     return 0;
2323 }
2324
2325 int RenderObject::previousOffset(int current) const
2326 {
2327     return current - 1;
2328 }
2329
2330 int RenderObject::previousOffsetForBackwardDeletion(int current) const
2331 {
2332     return current - 1;
2333 }
2334
2335 int RenderObject::nextOffset(int current) const
2336 {
2337     return current + 1;
2338 }
2339
2340 void RenderObject::adjustRectForOutlineAndShadow(LayoutRect& rect) const
2341 {
2342     int outlineSize = outlineStyleForRepaint().outlineSize();
2343     if (const ShadowData* boxShadow = style().boxShadow()) {
2344         boxShadow->adjustRectForShadow(rect, outlineSize);
2345         return;
2346     }
2347
2348     rect.inflate(outlineSize);
2349 }
2350
2351 void RenderObject::imageChanged(CachedImage* image, const IntRect* rect)
2352 {
2353     imageChanged(static_cast<WrappedImagePtr>(image), rect);
2354 }
2355
2356 RenderBoxModelObject* RenderObject::offsetParent() const
2357 {
2358     // If any of the following holds true return null and stop this algorithm:
2359     // A is the root element.
2360     // A is the HTML body element.
2361     // The computed value of the position property for element A is fixed.
2362     if (isRoot() || isBody() || (isOutOfFlowPositioned() && style().position() == FixedPosition))
2363         return nullptr;
2364
2365     // If A is an area HTML element which has a map HTML element somewhere in the ancestor
2366     // chain return the nearest ancestor map HTML element and stop this algorithm.
2367     // FIXME: Implement!
2368     
2369     // Return the nearest ancestor element of A for which at least one of the following is
2370     // true and stop this algorithm if such an ancestor is found:
2371     //     * The computed value of the position property is not static.
2372     //     * It is the HTML body element.
2373     //     * The computed value of the position property of A is static and the ancestor
2374     //       is one of the following HTML elements: td, th, or table.
2375     //     * Our own extension: if there is a difference in the effective zoom
2376
2377     bool skipTables = isPositioned();
2378     float currZoom = style().effectiveZoom();
2379     auto current = parent();
2380     while (current && (!current->element() || (!current->isPositioned() && !current->isBody())) && !is<RenderNamedFlowThread>(*current)) {
2381         Element* element = current->element();
2382         if (!skipTables && element && (is<HTMLTableElement>(*element) || is<HTMLTableCellElement>(*element)))
2383             break;
2384  
2385         float newZoom = current->style().effectiveZoom();
2386         if (currZoom != newZoom)
2387             break;
2388         currZoom = newZoom;
2389         current = current->parent();
2390     }
2391     
2392     // CSS regions specification says that region flows should return the body element as their offsetParent.
2393     if (is<RenderNamedFlowThread>(current))
2394         current = document().body() ? document().body()->renderer() : nullptr;
2395     
2396     return is<RenderBoxModelObject>(current) ? downcast<RenderBoxModelObject>(current) : nullptr;
2397 }
2398
2399 VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity) const
2400 {
2401     // If this is a non-anonymous renderer in an editable area, then it's simple.
2402     if (Node* node = nonPseudoNode()) {
2403         if (!node->hasEditableStyle()) {
2404             // If it can be found, we prefer a visually equivalent position that is editable. 
2405             Position position = createLegacyEditingPosition(node, offset);
2406             Position candidate = position.downstream(CanCrossEditingBoundary);
2407             if (candidate.deprecatedNode()->hasEditableStyle())
2408                 return VisiblePosition(candidate, affinity);
2409             candidate = position.upstream(CanCrossEditingBoundary);
2410             if (candidate.deprecatedNode()->hasEditableStyle())
2411                 return VisiblePosition(candidate, affinity);
2412         }
2413         // FIXME: Eliminate legacy editing positions
2414         return VisiblePosition(createLegacyEditingPosition(node, offset), affinity);
2415     }
2416
2417     // We don't want to cross the boundary between editable and non-editable
2418     // regions of the document, but that is either impossible or at least
2419     // extremely unlikely in any normal case because we stop as soon as we
2420     // find a single non-anonymous renderer.
2421
2422     // Find a nearby non-anonymous renderer.
2423     const RenderObject* child = this;
2424     while (const auto parent = child->parent()) {
2425         // Find non-anonymous content after.
2426         const RenderObject* renderer = child;
2427         while ((renderer = renderer->nextInPreOrder(parent))) {
2428             if (Node* node = renderer->nonPseudoNode())
2429                 return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
2430         }
2431
2432         // Find non-anonymous content before.
2433         renderer = child;
2434         while ((renderer = renderer->previousInPreOrder())) {
2435             if (renderer == parent)
2436                 break;
2437             if (Node* node = renderer->nonPseudoNode())
2438                 return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
2439         }
2440
2441         // Use the parent itself unless it too is anonymous.
2442         if (Element* element = parent->nonPseudoElement())
2443             return VisiblePosition(firstPositionInOrBeforeNode(element), DOWNSTREAM);
2444
2445         // Repeat at the next level up.
2446         child = parent;
2447     }
2448
2449     // Everything was anonymous. Give up.
2450     return VisiblePosition();
2451 }
2452
2453 VisiblePosition RenderObject::createVisiblePosition(const Position& position) const
2454 {
2455     if (position.isNotNull())
2456         return VisiblePosition(position);
2457
2458     ASSERT(!node());
2459     return createVisiblePosition(0, DOWNSTREAM);
2460 }
2461
2462 CursorDirective RenderObject::getCursor(const LayoutPoint&, Cursor&) const
2463 {
2464     return SetCursorBasedOnStyle;
2465 }
2466
2467 bool RenderObject::canUpdateSelectionOnRootLineBoxes()
2468 {
2469     if (needsLayout())
2470         return false;
2471
2472     RenderBlock* containingBlock = this->containingBlock();
2473     return containingBlock ? !containingBlock->needsLayout() : true;
2474 }
2475
2476 // We only create "generated" child renderers like one for first-letter if:
2477 // - the firstLetterBlock can have children in the DOM and
2478 // - the block doesn't have any special assumption on its text children.
2479 // This correctly prevents form controls from having such renderers.
2480 bool RenderObject::canHaveGeneratedChildren() const
2481 {
2482     return canHaveChildren();
2483 }
2484
2485 Node* RenderObject::generatingPseudoHostElement() const
2486 {
2487     return downcast<PseudoElement>(*node()).hostElement();
2488 }
2489
2490 void RenderObject::setNeedsBoundariesUpdate()
2491 {
2492     if (auto renderer = parent())
2493         renderer->setNeedsBoundariesUpdate();
2494 }
2495
2496 FloatRect RenderObject::objectBoundingBox() const
2497 {
2498     ASSERT_NOT_REACHED();
2499     return FloatRect();
2500 }
2501
2502 FloatRect RenderObject::strokeBoundingBox() const
2503 {
2504     ASSERT_NOT_REACHED();
2505     return FloatRect();
2506 }
2507
2508 // Returns the smallest rectangle enclosing all of the painted content
2509 // respecting clipping, masking, filters, opacity, stroke-width and markers
2510 FloatRect RenderObject::repaintRectInLocalCoordinates() const
2511 {
2512     ASSERT_NOT_REACHED();
2513     return FloatRect();
2514 }
2515
2516 AffineTransform RenderObject::localTransform() const
2517 {
2518     static const AffineTransform identity;
2519     return identity;
2520 }
2521
2522 const AffineTransform& RenderObject::localToParentTransform() const
2523 {
2524     static const AffineTransform identity;
2525     return identity;
2526 }
2527
2528 bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction)
2529 {
2530     ASSERT_NOT_REACHED();
2531     return false;
2532 }
2533
2534 RenderNamedFlowFragment* RenderObject::currentRenderNamedFlowFragment() const
2535 {
2536     RenderFlowThread* flowThread = flowThreadContainingBlock();
2537     if (!is<RenderNamedFlowThread>(flowThread))
2538         return nullptr;
2539
2540     // FIXME: Once regions are fully integrated with the compositing system we should uncomment this assert.
2541     // This assert needs to be disabled because it's possible to ask for the ancestor clipping rectangle of
2542     // a layer without knowing the containing region in advance.
2543     // ASSERT(flowThread->currentRegion() && flowThread->currentRegion()->isRenderNamedFlowFragment());
2544
2545     return downcast<RenderNamedFlowFragment>(flowThread->currentRegion());
2546 }
2547
2548 RenderFlowThread* RenderObject::locateFlowThreadContainingBlock() const
2549 {
2550     RenderBlock* containingBlock = this->containingBlock();
2551     return containingBlock ? containingBlock->flowThreadContainingBlock() : nullptr;
2552 }
2553
2554 } // namespace WebCore
2555
2556 #ifndef NDEBUG
2557
2558 void showNodeTree(const WebCore::RenderObject* object)
2559 {
2560     if (!object)
2561         return;
2562     object->showNodeTreeForThis();
2563 }
2564
2565 void showLineTree(const WebCore::RenderObject* object)
2566 {
2567     if (!object)
2568         return;
2569     object->showLineTreeForThis();
2570 }
2571
2572 void showRenderTree(const WebCore::RenderObject* object)
2573 {
2574     if (!object)
2575         return;
2576     object->showRenderTreeForThis();
2577 }
2578
2579 #endif