Implement the updated port/area-based Scroll Snap Module Level 1 Spec
[WebKit-https.git] / Source / WebCore / rendering / RenderView.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22 #include "RenderView.h"
23
24 #include "Document.h"
25 #include "Element.h"
26 #include "FloatQuad.h"
27 #include "FloatingObjects.h"
28 #include "FlowThreadController.h"
29 #include "Frame.h"
30 #include "FrameSelection.h"
31 #include "FrameView.h"
32 #include "GraphicsContext.h"
33 #include "HTMLBodyElement.h"
34 #include "HTMLFrameOwnerElement.h"
35 #include "HTMLHtmlElement.h"
36 #include "HTMLIFrameElement.h"
37 #include "HitTestResult.h"
38 #include "ImageQualityController.h"
39 #include "NodeTraversal.h"
40 #include "Page.h"
41 #include "RenderGeometryMap.h"
42 #include "RenderIterator.h"
43 #include "RenderLayer.h"
44 #include "RenderLayerBacking.h"
45 #include "RenderLayerCompositor.h"
46 #include "RenderMultiColumnFlowThread.h"
47 #include "RenderMultiColumnSet.h"
48 #include "RenderMultiColumnSpannerPlaceholder.h"
49 #include "RenderNamedFlowThread.h"
50 #include "RenderSelectionInfo.h"
51 #include "RenderWidget.h"
52 #include "ScrollbarTheme.h"
53 #include "Settings.h"
54 #include "StyleInheritedData.h"
55 #include "TransformState.h"
56 #include <wtf/SetForScope.h>
57 #include <wtf/StackStats.h>
58
59 namespace WebCore {
60
61 struct FrameFlatteningLayoutDisallower {
62     FrameFlatteningLayoutDisallower(FrameView& frameView)
63         : m_frameView(frameView)
64         , m_disallowLayout(frameView.frame().settings().frameFlatteningEnabled())
65     {
66         if (m_disallowLayout)
67             m_frameView.startDisallowingLayout();
68     }
69
70     ~FrameFlatteningLayoutDisallower()
71     {
72         if (m_disallowLayout)
73             m_frameView.endDisallowingLayout();
74     }
75
76 private:
77     FrameView& m_frameView;
78     bool m_disallowLayout { false };
79 };
80
81 struct SelectionIterator {
82     SelectionIterator(RenderObject* start)
83         : m_current(start)
84     {
85         checkForSpanner();
86     }
87     
88     RenderObject* current() const
89     {
90         return m_current;
91     }
92     
93     RenderObject* next()
94     {
95         RenderObject* currentSpan = m_spannerStack.isEmpty() ? nullptr : m_spannerStack.last()->spanner();
96         m_current = m_current->nextInPreOrder(currentSpan);
97         checkForSpanner();
98         if (!m_current && currentSpan) {
99             RenderObject* placeholder = m_spannerStack.last();
100             m_spannerStack.removeLast();
101             m_current = placeholder->nextInPreOrder();
102             checkForSpanner();
103         }
104         return m_current;
105     }
106
107 private:
108     void checkForSpanner()
109     {
110         if (!is<RenderMultiColumnSpannerPlaceholder>(m_current))
111             return;
112         auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current);
113         m_spannerStack.append(&placeholder);
114         m_current = placeholder.spanner();
115     }
116
117     RenderObject* m_current { nullptr };
118     Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack;
119 };
120
121 RenderView::RenderView(Document& document, RenderStyle&& style)
122     : RenderBlockFlow(document, WTFMove(style))
123     , m_frameView(*document.view())
124     , m_lazyRepaintTimer(*this, &RenderView::lazyRepaintTimerFired)
125 #if ENABLE(SERVICE_CONTROLS)
126     , m_selectionRectGatherer(*this)
127 #endif
128 {
129     setIsRenderView();
130
131     // FIXME: We should find a way to enforce this at compile time.
132     ASSERT(document.view());
133
134     // init RenderObject attributes
135     setInline(false);
136     
137     m_minPreferredLogicalWidth = 0;
138     m_maxPreferredLogicalWidth = 0;
139
140     setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
141     
142     setPositionState(AbsolutePosition); // to 0,0 :)
143 }
144
145 RenderView::~RenderView()
146 {
147 }
148
149 void RenderView::scheduleLazyRepaint(RenderBox& renderer)
150 {
151     if (renderer.renderBoxNeedsLazyRepaint())
152         return;
153     renderer.setRenderBoxNeedsLazyRepaint(true);
154     m_renderersNeedingLazyRepaint.add(&renderer);
155     if (!m_lazyRepaintTimer.isActive())
156         m_lazyRepaintTimer.startOneShot(0);
157 }
158
159 void RenderView::unscheduleLazyRepaint(RenderBox& renderer)
160 {
161     if (!renderer.renderBoxNeedsLazyRepaint())
162         return;
163     renderer.setRenderBoxNeedsLazyRepaint(false);
164     m_renderersNeedingLazyRepaint.remove(&renderer);
165     if (m_renderersNeedingLazyRepaint.isEmpty())
166         m_lazyRepaintTimer.stop();
167 }
168
169 void RenderView::lazyRepaintTimerFired()
170 {
171     bool shouldRepaint = document().pageCacheState() == Document::NotInPageCache;
172
173     for (auto& renderer : m_renderersNeedingLazyRepaint) {
174         if (shouldRepaint)
175             renderer->repaint();
176         renderer->setRenderBoxNeedsLazyRepaint(false);
177     }
178     m_renderersNeedingLazyRepaint.clear();
179 }
180
181 bool RenderView::hitTest(const HitTestRequest& request, HitTestResult& result)
182 {
183     return hitTest(request, result.hitTestLocation(), result);
184 }
185
186 bool RenderView::hitTest(const HitTestRequest& request, const HitTestLocation& location, HitTestResult& result)
187 {
188     document().updateLayout();
189     
190 #if !ASSERT_DISABLED
191     SetForScope<bool> hitTestRestorer { m_inHitTesting, true };
192 #endif
193
194     FrameFlatteningLayoutDisallower disallower(frameView());
195
196     bool resultLayer = layer()->hitTest(request, location, result);
197
198     // ScrollView scrollbars are not the same as RenderLayer scrollbars tested by RenderLayer::hitTestOverflowControls,
199     // so we need to test ScrollView scrollbars separately here. In case of using overlay scrollbars, the layer hit test
200     // will always work so we need to check the ScrollView scrollbars in that case too.
201     if (!resultLayer || ScrollbarTheme::theme().usesOverlayScrollbars()) {
202         // FIXME: Consider if this test should be done unconditionally.
203         if (request.allowsFrameScrollbars()) {
204             IntPoint windowPoint = frameView().contentsToWindow(location.roundedPoint());
205             if (Scrollbar* frameScrollbar = frameView().scrollbarAtPoint(windowPoint)) {
206                 result.setScrollbar(frameScrollbar);
207                 return true;
208             }
209         }
210     }
211
212     return resultLayer;
213 }
214
215 RenderBox::LogicalExtentComputedValues RenderView::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit) const
216 {
217     return { !shouldUsePrintingLayout() ? LayoutUnit(viewLogicalHeight()) : logicalHeight, LayoutUnit(), ComputedMarginValues() };
218 }
219
220 void RenderView::updateLogicalWidth()
221 {
222     if (!shouldUsePrintingLayout())
223         setLogicalWidth(viewLogicalWidth());
224 }
225
226 LayoutUnit RenderView::availableLogicalHeight(AvailableLogicalHeightType) const
227 {
228     // Make sure block progression pagination for percentages uses the column extent and
229     // not the view's extent. See https://bugs.webkit.org/show_bug.cgi?id=135204.
230     if (multiColumnFlowThread() && multiColumnFlowThread()->firstMultiColumnSet())
231         return multiColumnFlowThread()->firstMultiColumnSet()->computedColumnHeight();
232
233 #if PLATFORM(IOS)
234     // Workaround for <rdar://problem/7166808>.
235     if (document().isPluginDocument() && frameView().useFixedLayout())
236         return frameView().fixedLayoutSize().height();
237 #endif
238     return isHorizontalWritingMode() ? frameView().visibleHeight() : frameView().visibleWidth();
239 }
240
241 bool RenderView::isChildAllowed(const RenderObject& child, const RenderStyle&) const
242 {
243     return child.isBox();
244 }
245
246 void RenderView::layoutContent(const LayoutState& state)
247 {
248     UNUSED_PARAM(state);
249     ASSERT(needsLayout());
250
251     RenderBlockFlow::layout();
252     if (hasRenderNamedFlowThreads())
253         flowThreadController().layoutRenderNamedFlowThreads();
254 #ifndef NDEBUG
255     checkLayoutState(state);
256 #endif
257 }
258
259 #ifndef NDEBUG
260 void RenderView::checkLayoutState(const LayoutState& state)
261 {
262     ASSERT(layoutDeltaMatches(LayoutSize()));
263     ASSERT(!m_layoutStateDisableCount);
264     ASSERT(m_layoutState.get() == &state);
265 }
266 #endif
267
268 void RenderView::initializeLayoutState(LayoutState& state)
269 {
270     // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
271     state.m_clipped = false;
272
273     state.m_pageLogicalHeight = m_pageLogicalHeight;
274     state.m_pageLogicalHeightChanged = m_pageLogicalHeightChanged;
275     ASSERT(state.m_pageLogicalHeight >= 0);
276     state.m_isPaginated = state.m_pageLogicalHeight > 0;
277 }
278
279 // The algorithm below assumes this is a full layout. In case there are previously computed values for regions, supplemental steps are taken
280 // to ensure the results are the same as those obtained from a full layout (i.e. the auto-height regions from all the flows are marked as needing
281 // layout).
282 // 1. The flows are laid out from the outer flow to the inner flow. This successfully computes the outer non-auto-height regions size so the 
283 // inner flows have the necessary information to correctly fragment the content.
284 // 2. The flows are laid out from the inner flow to the outer flow. After an inner flow is laid out it goes into the constrained layout phase
285 // and marks the auto-height regions they need layout. This means the outer flows will relayout if they depend on regions with auto-height regions
286 // belonging to inner flows. This step will correctly set the computedAutoHeight for the auto-height regions. It's possible for non-auto-height
287 // regions to relayout if they depend on auto-height regions. This will invalidate the inner flow threads and mark them as needing layout.
288 // 3. The last step is to do one last layout if there are pathological dependencies between non-auto-height regions and auto-height regions
289 // as detected in the previous step.
290 void RenderView::layoutContentInAutoLogicalHeightRegions(const LayoutState& state)
291 {
292     // We need to invalidate all the flows with auto-height regions if one such flow needs layout.
293     // If none is found we do a layout a check back again afterwards.
294     if (!flowThreadController().updateFlowThreadsNeedingLayout()) {
295         // Do a first layout of the content. In some cases more layouts are not needed (e.g. only flows with non-auto-height regions have changed).
296         layoutContent(state);
297
298         // If we find no named flow needing a two step layout after the first layout, exit early.
299         // Otherwise, initiate the two step layout algorithm and recompute all the flows.
300         if (!flowThreadController().updateFlowThreadsNeedingTwoStepLayout())
301             return;
302     }
303
304     // Layout to recompute all the named flows with auto-height regions.
305     layoutContent(state);
306
307     // Propagate the computed auto-height values upwards.
308     // Non-auto-height regions may invalidate the flow thread because they depended on auto-height regions, but that's ok.
309     flowThreadController().updateFlowThreadsIntoConstrainedPhase();
310
311     // Do one last layout that should update the auto-height regions found in the main flow
312     // and solve pathological dependencies between regions (e.g. a non-auto-height region depending
313     // on an auto-height one).
314     if (needsLayout())
315         layoutContent(state);
316 }
317
318 void RenderView::layoutContentToComputeOverflowInRegions(const LayoutState& state)
319 {
320     if (!hasRenderNamedFlowThreads())
321         return;
322
323     // First pass through the flow threads and mark the regions as needing a simple layout.
324     // The regions extract the overflow from the flow thread and pass it to their containg
325     // block chain.
326     flowThreadController().updateFlowThreadsIntoOverflowPhase();
327     if (needsLayout())
328         layoutContent(state);
329
330     // In case scrollbars resized the regions a new pass is necessary to update the flow threads
331     // and recompute the overflow on regions. This is the final state of the flow threads.
332     flowThreadController().updateFlowThreadsIntoFinalPhase();
333     if (needsLayout())
334         layoutContent(state);
335
336     // Finally reset the layout state of the flow threads.
337     flowThreadController().updateFlowThreadsIntoMeasureContentPhase();
338 }
339
340 void RenderView::layout()
341 {
342     StackStats::LayoutCheckPoint layoutCheckPoint;
343     if (!document().paginated())
344         setPageLogicalHeight(0);
345
346     if (shouldUsePrintingLayout())
347         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth();
348
349     // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
350     bool relayoutChildren = !shouldUsePrintingLayout() && (width() != viewWidth() || height() != viewHeight());
351     if (relayoutChildren) {
352         setChildNeedsLayout(MarkOnlyThis);
353
354         for (auto& box : childrenOfType<RenderBox>(*this)) {
355             if (box.hasRelativeLogicalHeight()
356                 || box.style().logicalHeight().isPercentOrCalculated()
357                 || box.style().logicalMinHeight().isPercentOrCalculated()
358                 || box.style().logicalMaxHeight().isPercentOrCalculated()
359                 || box.isSVGRoot()
360                 )
361                 box.setChildNeedsLayout(MarkOnlyThis);
362         }
363     }
364
365     ASSERT(!m_layoutState);
366     if (!needsLayout())
367         return;
368
369     m_layoutState = std::make_unique<LayoutState>();
370     initializeLayoutState(*m_layoutState);
371
372     m_pageLogicalHeightChanged = false;
373
374     if (checkTwoPassLayoutForAutoHeightRegions())
375         layoutContentInAutoLogicalHeightRegions(*m_layoutState);
376     else
377         layoutContent(*m_layoutState);
378
379     layoutContentToComputeOverflowInRegions(*m_layoutState);
380
381 #ifndef NDEBUG
382     checkLayoutState(*m_layoutState);
383 #endif
384     m_layoutState = nullptr;
385     clearNeedsLayout();
386 }
387
388 LayoutUnit RenderView::pageOrViewLogicalHeight() const
389 {
390     if (document().printing())
391         return pageLogicalHeight();
392     
393     if (multiColumnFlowThread() && !style().hasInlineColumnAxis()) {
394         if (int pageLength = frameView().pagination().pageLength)
395             return pageLength;
396     }
397
398     return viewLogicalHeight();
399 }
400
401 LayoutUnit RenderView::clientLogicalWidthForFixedPosition() const
402 {
403     // FIXME: If the FrameView's fixedVisibleContentRect() is not empty, perhaps it should be consulted here too?
404     if (frameView().fixedElementsLayoutRelativeToFrame())
405         return (isHorizontalWritingMode() ? frameView().visibleWidth() : frameView().visibleHeight()) / frameView().frame().frameScaleFactor();
406
407 #if PLATFORM(IOS)
408     if (frameView().useCustomFixedPositionLayoutRect())
409         return isHorizontalWritingMode() ? frameView().customFixedPositionLayoutRect().width() : frameView().customFixedPositionLayoutRect().height();
410 #endif
411
412     if (frameView().frame().settings().visualViewportEnabled())
413         return isHorizontalWritingMode() ? frameView().layoutViewportRect().width() : frameView().layoutViewportRect().height();
414
415     return clientLogicalWidth();
416 }
417
418 LayoutUnit RenderView::clientLogicalHeightForFixedPosition() const
419 {
420     // FIXME: If the FrameView's fixedVisibleContentRect() is not empty, perhaps it should be consulted here too?
421     if (frameView().fixedElementsLayoutRelativeToFrame())
422         return (isHorizontalWritingMode() ? frameView().visibleHeight() : frameView().visibleWidth()) / frameView().frame().frameScaleFactor();
423
424 #if PLATFORM(IOS)
425     if (frameView().useCustomFixedPositionLayoutRect())
426         return isHorizontalWritingMode() ? frameView().customFixedPositionLayoutRect().height() : frameView().customFixedPositionLayoutRect().width();
427 #endif
428
429     if (frameView().frame().settings().visualViewportEnabled())
430         return isHorizontalWritingMode() ? frameView().layoutViewportRect().height() : frameView().layoutViewportRect().width();
431
432     return clientLogicalHeight();
433 }
434
435 void RenderView::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
436 {
437     // If a container was specified, and was not nullptr or the RenderView,
438     // then we should have found it by now.
439     ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);
440     ASSERT_UNUSED(wasFixed, !wasFixed || *wasFixed == (mode & IsFixed));
441
442     if (mode & IsFixed)
443         transformState.move(toLayoutSize(frameView().scrollPositionRespectingCustomFixedPosition()));
444
445     if (!repaintContainer && mode & UseTransforms && shouldUseTransformFromContainer(nullptr)) {
446         TransformationMatrix t;
447         getTransformFromContainer(nullptr, LayoutSize(), t);
448         transformState.applyTransform(t);
449     }
450 }
451
452 const RenderObject* RenderView::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
453 {
454     // If a container was specified, and was not nullptr or the RenderView,
455     // then we should have found it by now.
456     ASSERT_ARG(ancestorToStopAt, !ancestorToStopAt || ancestorToStopAt == this);
457
458     LayoutPoint scrollPosition = frameView().scrollPositionRespectingCustomFixedPosition();
459
460     if (!ancestorToStopAt && shouldUseTransformFromContainer(nullptr)) {
461         TransformationMatrix t;
462         getTransformFromContainer(nullptr, LayoutSize(), t);
463         geometryMap.pushView(this, toLayoutSize(scrollPosition), &t);
464     } else
465         geometryMap.pushView(this, toLayoutSize(scrollPosition));
466
467     return nullptr;
468 }
469
470 void RenderView::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
471 {
472     if (mode & UseTransforms && shouldUseTransformFromContainer(nullptr)) {
473         TransformationMatrix t;
474         getTransformFromContainer(nullptr, LayoutSize(), t);
475         transformState.applyTransform(t);
476     }
477
478     if (mode & IsFixed)
479         transformState.move(toLayoutSize(frameView().scrollPositionRespectingCustomFixedPosition()));
480 }
481
482 bool RenderView::requiresColumns(int) const
483 {
484     return frameView().pagination().mode != Pagination::Unpaginated;
485 }
486
487 void RenderView::computeColumnCountAndWidth()
488 {
489     int columnWidth = contentLogicalWidth();
490     if (style().hasInlineColumnAxis()) {
491         if (int pageLength = frameView().pagination().pageLength)
492             columnWidth = pageLength;
493     }
494     setComputedColumnCountAndWidth(1, columnWidth);
495 }
496
497 void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
498 {
499     // If we ever require layout but receive a paint anyway, something has gone horribly wrong.
500     ASSERT(!needsLayout());
501     // RenderViews should never be called to paint with an offset not on device pixels.
502     ASSERT(LayoutPoint(IntPoint(paintOffset.x(), paintOffset.y())) == paintOffset);
503
504     // This avoids painting garbage between columns if there is a column gap.
505     if (frameView().pagination().mode != Pagination::Unpaginated && paintInfo.shouldPaintWithinRoot(*this))
506         paintInfo.context().fillRect(paintInfo.rect, frameView().baseBackgroundColor());
507
508     paintObject(paintInfo, paintOffset);
509 }
510
511 RenderElement* RenderView::rendererForRootBackground() const
512 {
513     auto* firstChild = this->firstChild();
514     if (!firstChild)
515         return nullptr;
516     ASSERT(is<RenderElement>(*firstChild));
517     auto& documentRenderer = downcast<RenderElement>(*firstChild);
518
519     if (documentRenderer.hasBackground())
520         return &documentRenderer;
521
522     // We propagate the background only for HTML content.
523     if (!is<HTMLHtmlElement>(documentRenderer.element()))
524         return &documentRenderer;
525
526     if (auto* body = document().body()) {
527         if (auto* renderer = body->renderer())
528             return renderer;
529     }
530     return &documentRenderer;
531 }
532
533 static inline bool rendererObscuresBackground(const RenderElement& rootElement)
534 {
535     auto& style = rootElement.style();
536     if (style.visibility() != VISIBLE || style.opacity() != 1 || style.hasTransform())
537         return false;
538
539     if (style.hasBorderRadius())
540         return false;
541
542     if (rootElement.isComposited())
543         return false;
544
545     auto* rendererForBackground = rootElement.view().rendererForRootBackground();
546     if (!rendererForBackground)
547         return false;
548
549     if (rendererForBackground->style().backgroundClip() == TextFillBox)
550         return false;
551
552     return true;
553 }
554
555 void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&)
556 {
557     if (!paintInfo.shouldPaintWithinRoot(*this))
558         return;
559
560     // Check to see if we are enclosed by a layer that requires complex painting rules.  If so, we cannot blit
561     // when scrolling, and we need to use slow repaints.  Examples of layers that require this are transparent layers,
562     // layers with reflections, or transformed layers.
563     // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being inside
564     // a transform, transparency layer, etc.
565     for (HTMLFrameOwnerElement* element = document().ownerElement(); element && element->renderer(); element = element->document().ownerElement()) {
566         RenderLayer* layer = element->renderer()->enclosingLayer();
567         if (layer->cannotBlitToWindow()) {
568             frameView().setCannotBlitToWindow();
569             break;
570         }
571
572         if (RenderLayer* compositingLayer = layer->enclosingCompositingLayerForRepaint()) {
573             if (!compositingLayer->backing()->paintsIntoWindow()) {
574                 frameView().setCannotBlitToWindow();
575                 break;
576             }
577         }
578     }
579
580     if (document().ownerElement())
581         return;
582
583     if (paintInfo.skipRootBackground())
584         return;
585
586     bool rootFillsViewport = false;
587     bool rootObscuresBackground = false;
588     Element* documentElement = document().documentElement();
589     if (RenderElement* rootRenderer = documentElement ? documentElement->renderer() : nullptr) {
590         // The document element's renderer is currently forced to be a block, but may not always be.
591         RenderBox* rootBox = is<RenderBox>(*rootRenderer) ? downcast<RenderBox>(rootRenderer) : nullptr;
592         rootFillsViewport = rootBox && !rootBox->x() && !rootBox->y() && rootBox->width() >= width() && rootBox->height() >= height();
593         rootObscuresBackground = rendererObscuresBackground(*rootRenderer);
594     }
595
596     bool backgroundShouldExtendBeyondPage = frameView().frame().settings().backgroundShouldExtendBeyondPage();
597     compositor().setRootExtendedBackgroundColor(backgroundShouldExtendBeyondPage ? frameView().documentBackgroundColor() : Color());
598
599     Page* page = document().page();
600     float pageScaleFactor = page ? page->pageScaleFactor() : 1;
601
602     // If painting will entirely fill the view, no need to fill the background.
603     if (rootFillsViewport && rootObscuresBackground && pageScaleFactor >= 1)
604         return;
605
606     // This code typically only executes if the root element's visibility has been set to hidden,
607     // if there is a transform on the <html>, or if there is a page scale factor less than 1.
608     // Only fill with a background color (typically white) if we're the root document, 
609     // since iframes/frames with no background in the child document should show the parent's background.
610     // We use the base background color unless the backgroundShouldExtendBeyondPage setting is set,
611     // in which case we use the document's background color.
612     if (frameView().isTransparent()) // FIXME: This needs to be dynamic. We should be able to go back to blitting if we ever stop being transparent.
613         frameView().setCannotBlitToWindow(); // The parent must show behind the child.
614     else {
615         const Color& documentBackgroundColor = frameView().documentBackgroundColor();
616         const Color& backgroundColor = (backgroundShouldExtendBeyondPage && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView().baseBackgroundColor();
617         if (backgroundColor.isVisible()) {
618             CompositeOperator previousOperator = paintInfo.context().compositeOperation();
619             paintInfo.context().setCompositeOperation(CompositeCopy);
620             paintInfo.context().fillRect(paintInfo.rect, backgroundColor);
621             paintInfo.context().setCompositeOperation(previousOperator);
622         } else
623             paintInfo.context().clearRect(paintInfo.rect);
624     }
625 }
626
627 bool RenderView::shouldRepaint(const LayoutRect& rect) const
628 {
629     return !printing() && !rect.isEmpty();
630 }
631
632 void RenderView::repaintRootContents()
633 {
634     if (layer()->isComposited()) {
635         layer()->setBackingNeedsRepaint(GraphicsLayer::DoNotClipToLayer);
636         return;
637     }
638
639     // Always use layoutOverflowRect() to fix rdar://problem/27182267.
640     // This should be cleaned up via webkit.org/b/159913 and webkit.org/b/159914.
641     RenderLayerModelObject* repaintContainer = containerForRepaint();
642     repaintUsingContainer(repaintContainer, computeRectForRepaint(layoutOverflowRect(), repaintContainer));
643 }
644
645 void RenderView::repaintViewRectangle(const LayoutRect& repaintRect) const
646 {
647     if (!shouldRepaint(repaintRect))
648         return;
649
650     // FIXME: enclosingRect is needed as long as we integral snap ScrollView/FrameView/RenderWidget size/position.
651     IntRect enclosingRect = enclosingIntRect(repaintRect);
652     if (auto ownerElement = document().ownerElement()) {
653         RenderBox* ownerBox = ownerElement->renderBox();
654         if (!ownerBox)
655             return;
656         LayoutRect viewRect = this->viewRect();
657 #if PLATFORM(IOS)
658         // Don't clip using the visible rect since clipping is handled at a higher level on iPhone.
659         LayoutRect adjustedRect = enclosingRect;
660 #else
661         LayoutRect adjustedRect = intersection(enclosingRect, viewRect);
662 #endif
663         adjustedRect.moveBy(-viewRect.location());
664         adjustedRect.moveBy(ownerBox->contentBoxRect().location());
665
666         // A dirty rect in an iframe is relative to the contents of that iframe.
667         // When we traverse between parent frames and child frames, we need to make sure
668         // that the coordinate system is mapped appropriately between the iframe's contents
669         // and the Renderer that contains the iframe. This transformation must account for a
670         // left scrollbar (if one exists).
671         FrameView& frameView = this->frameView();
672         if (frameView.shouldPlaceBlockDirectionScrollbarOnLeft() && frameView.verticalScrollbar())
673             adjustedRect.move(LayoutSize(frameView.verticalScrollbar()->occupiedWidth(), 0));
674
675         ownerBox->repaintRectangle(adjustedRect);
676         return;
677     }
678
679     frameView().addTrackedRepaintRect(snapRectToDevicePixels(repaintRect, document().deviceScaleFactor()));
680     if (!m_accumulatedRepaintRegion) {
681         frameView().repaintContentRectangle(enclosingRect);
682         return;
683     }
684     m_accumulatedRepaintRegion->unite(enclosingRect);
685
686     // Region will get slow if it gets too complex. Merge all rects so far to bounds if this happens.
687     // FIXME: Maybe there should be a region type that does this automatically.
688     static const unsigned maximumRepaintRegionGridSize = 16 * 16;
689     if (m_accumulatedRepaintRegion->gridSize() > maximumRepaintRegionGridSize)
690         m_accumulatedRepaintRegion = std::make_unique<Region>(m_accumulatedRepaintRegion->bounds());
691 }
692
693 void RenderView::flushAccumulatedRepaintRegion() const
694 {
695     ASSERT(!document().ownerElement());
696     ASSERT(m_accumulatedRepaintRegion);
697     auto repaintRects = m_accumulatedRepaintRegion->rects();
698     for (auto& rect : repaintRects)
699         frameView().repaintContentRectangle(rect);
700     m_accumulatedRepaintRegion = nullptr;
701 }
702
703 void RenderView::repaintViewAndCompositedLayers()
704 {
705     repaintRootContents();
706
707     RenderLayerCompositor& compositor = this->compositor();
708     if (compositor.inCompositingMode())
709         compositor.repaintCompositedLayers();
710 }
711
712 LayoutRect RenderView::visualOverflowRect() const
713 {
714     if (frameView().paintsEntireContents())
715         return layoutOverflowRect();
716
717     return RenderBlockFlow::visualOverflowRect();
718 }
719
720 LayoutRect RenderView::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const
721 {
722     // If a container was specified, and was not nullptr or the RenderView,
723     // then we should have found it by now.
724     ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);
725
726     if (printing())
727         return rect;
728     
729     LayoutRect adjustedRect = rect;
730     if (style().isFlippedBlocksWritingMode()) {
731         // We have to flip by hand since the view's logical height has not been determined.  We
732         // can use the viewport width and height.
733         if (style().isHorizontalWritingMode())
734             adjustedRect.setY(viewHeight() - adjustedRect.maxY());
735         else
736             adjustedRect.setX(viewWidth() - adjustedRect.maxX());
737     }
738
739     if (context.m_hasPositionFixedDescendant)
740         adjustedRect.moveBy(frameView().scrollPositionRespectingCustomFixedPosition());
741     
742     // Apply our transform if we have one (because of full page zooming).
743     if (!repaintContainer && layer() && layer()->transform())
744         adjustedRect = LayoutRect(layer()->transform()->mapRect(snapRectToDevicePixels(adjustedRect, document().deviceScaleFactor())));
745     return adjustedRect;
746 }
747
748 bool RenderView::isScrollableOrRubberbandableBox() const
749 {
750     // The main frame might be allowed to rubber-band even if there is no content to scroll to. This is unique to
751     // the main frame; subframes and overflow areas have to have content that can be scrolled to in order to rubber-band.
752     FrameView::Scrollability defineScrollable = frame().ownerElement() ? FrameView::Scrollability::Scrollable : FrameView::Scrollability::ScrollableOrRubberbandable;
753     return frameView().isScrollable(defineScrollable);
754 }
755
756 void RenderView::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
757 {
758     rects.append(snappedIntRect(accumulatedOffset, layer()->size()));
759 }
760
761 void RenderView::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
762 {
763     if (wasFixed)
764         *wasFixed = false;
765     quads.append(FloatRect(FloatPoint(), layer()->size()));
766 }
767
768 static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset)
769 {
770     if (!object)
771         return nullptr;
772
773     RenderObject* child = object->childAt(offset);
774     return child ? child : object->nextInPreOrderAfterChildren();
775 }
776
777 IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
778 {
779     LayoutRect selRect = subtreeSelectionBounds(*this, clipToVisibleContent);
780
781     if (hasRenderNamedFlowThreads()) {
782         for (auto* namedFlowThread : *m_flowThreadController->renderNamedFlowThreadList()) {
783             LayoutRect currRect = subtreeSelectionBounds(*namedFlowThread, clipToVisibleContent);
784             selRect.unite(currRect);
785         }
786     }
787
788     return snappedIntRect(selRect);
789 }
790
791 LayoutRect RenderView::subtreeSelectionBounds(const SelectionSubtreeRoot& root, bool clipToVisibleContent) const
792 {
793     typedef HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>> SelectionMap;
794     SelectionMap selectedObjects;
795
796     RenderObject* os = root.selectionData().selectionStart();
797     auto* selectionEnd = root.selectionData().selectionEnd();
798     RenderObject* stop = nullptr;
799     if (selectionEnd)
800         stop = rendererAfterPosition(selectionEnd, root.selectionData().selectionEndPos().value());
801     SelectionIterator selectionIterator(os);
802     while (os && os != stop) {
803         if ((os->canBeSelectionLeaf() || os == root.selectionData().selectionStart() || os == root.selectionData().selectionEnd()) && os->selectionState() != SelectionNone) {
804             // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
805             selectedObjects.set(os, std::make_unique<RenderSelectionInfo>(*os, clipToVisibleContent));
806             RenderBlock* cb = os->containingBlock();
807             while (cb && !is<RenderView>(*cb)) {
808                 std::unique_ptr<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).iterator->value;
809                 if (blockInfo)
810                     break;
811                 blockInfo = std::make_unique<RenderSelectionInfo>(*cb, clipToVisibleContent);
812                 cb = cb->containingBlock();
813             }
814         }
815
816         os = selectionIterator.next();
817     }
818
819     // Now create a single bounding box rect that encloses the whole selection.
820     LayoutRect selRect;
821     SelectionMap::iterator end = selectedObjects.end();
822     for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
823         RenderSelectionInfo* info = i->value.get();
824         // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
825         LayoutRect currRect = info->rect();
826         if (RenderLayerModelObject* repaintContainer = info->repaintContainer()) {
827             FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));
828             currRect = absQuad.enclosingBoundingBox(); 
829         }
830         selRect.unite(currRect);
831     }
832     return selRect;
833 }
834
835 void RenderView::repaintSelection() const
836 {
837     repaintSubtreeSelection(*this);
838
839     if (hasRenderNamedFlowThreads()) {
840         for (auto* namedFlowThread : *m_flowThreadController->renderNamedFlowThreadList())
841             repaintSubtreeSelection(*namedFlowThread);
842     }
843 }
844
845 void RenderView::repaintSubtreeSelection(const SelectionSubtreeRoot& root) const
846 {
847     HashSet<RenderBlock*> processedBlocks;
848
849     auto* selectionEnd = root.selectionData().selectionEnd();
850     RenderObject* end = nullptr;
851     if (selectionEnd)
852         end = rendererAfterPosition(selectionEnd, root.selectionData().selectionEndPos().value());
853     SelectionIterator selectionIterator(root.selectionData().selectionStart());
854     for (RenderObject* o = selectionIterator.current(); o && o != end; o = selectionIterator.next()) {
855         if (!o->canBeSelectionLeaf() && o != root.selectionData().selectionStart() && o != root.selectionData().selectionEnd())
856             continue;
857         if (o->selectionState() == SelectionNone)
858             continue;
859
860         RenderSelectionInfo(*o, true).repaint();
861
862         // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
863         for (RenderBlock* block = o->containingBlock(); block && !is<RenderView>(*block); block = block->containingBlock()) {
864             if (!processedBlocks.add(block).isNewEntry)
865                 break;
866             RenderSelectionInfo(*block, true).repaint();
867         }
868     }
869 }
870
871 void RenderView::setSelection(RenderObject* start, std::optional<unsigned> startPos, RenderObject* end, std::optional<unsigned> endPos, SelectionRepaintMode blockRepaintMode)
872 {
873     // Make sure both our start and end objects are defined.
874     // Check www.msnbc.com and try clicking around to find the case where this happened.
875     if ((start && !end) || (end && !start))
876         return;
877
878     bool caretChanged = m_selectionWasCaret != frame().selection().isCaret();
879     m_selectionWasCaret = frame().selection().isCaret();
880     // Just return if the selection hasn't changed.
881     if (m_selectionUnsplitStart == start && m_selectionUnsplitStartPos == startPos
882         && m_selectionUnsplitEnd == end && m_selectionUnsplitEndPos == endPos && !caretChanged) {
883         return;
884     }
885
886 #if ENABLE(SERVICE_CONTROLS)
887     // Clear the current rects and create a notifier for the new rects we are about to gather.
888     // The Notifier updates the Editor when it goes out of scope and is destroyed.
889     std::unique_ptr<SelectionRectGatherer::Notifier> rectNotifier = m_selectionRectGatherer.clearAndCreateNotifier();
890 #endif // ENABLE(SERVICE_CONTROLS)
891     // Set global positions for new selection.
892     m_selectionUnsplitStart = start;
893     m_selectionUnsplitStartPos = startPos;
894     m_selectionUnsplitEnd = end;
895     m_selectionUnsplitEndPos = endPos;
896
897     // If there is no RenderNamedFlowThreads we follow the regular selection.
898     if (!hasRenderNamedFlowThreads()) {
899         RenderSubtreesMap singleSubtreeMap;
900         singleSubtreeMap.set(this, SelectionSubtreeData(start, startPos, end, endPos));
901         updateSelectionForSubtrees(singleSubtreeMap, blockRepaintMode);
902         return;
903     }
904
905     splitSelectionBetweenSubtrees(start, startPos, end, endPos, blockRepaintMode);
906 }
907
908 void RenderView::splitSelectionBetweenSubtrees(const RenderObject* start, std::optional<unsigned> startPos, const RenderObject* end, std::optional<unsigned> endPos, SelectionRepaintMode blockRepaintMode)
909 {
910     // Compute the visible selection end points for each of the subtrees.
911     RenderSubtreesMap renderSubtreesMap;
912
913     SelectionSubtreeData initialSelection;
914     renderSubtreesMap.set(this, initialSelection);
915     for (auto* namedFlowThread : *flowThreadController().renderNamedFlowThreadList())
916         renderSubtreesMap.set(namedFlowThread, initialSelection);
917
918     if (start && end) {
919         Node* startNode = start->node();
920         Node* endNode = end->node();
921         ASSERT(endNode);
922         Node* stopNode = NodeTraversal::nextSkippingChildren(*endNode);
923
924         for (Node* node = startNode; node != stopNode; node = NodeTraversal::next(*node)) {
925             RenderObject* renderer = node->renderer();
926             if (!renderer)
927                 continue;
928
929             SelectionSubtreeRoot& root = renderer->selectionRoot();
930             SelectionSubtreeData selectionData = renderSubtreesMap.get(&root);
931             if (selectionData.selectionClear()) {
932                 selectionData.setSelectionStart(node->renderer());
933                 selectionData.setSelectionStartPos(node == startNode ? startPos : std::optional<unsigned>(0));
934             }
935
936             selectionData.setSelectionEnd(node->renderer());
937             if (node == endNode)
938                 selectionData.setSelectionEndPos(endPos);
939             else {
940                 unsigned newEndPos = node->offsetInCharacters() ? node->maxCharacterOffset() : node->countChildNodes();
941                 selectionData.setSelectionEndPos(newEndPos);
942             }
943
944             renderSubtreesMap.set(&root, selectionData);
945         }
946     }
947     
948     updateSelectionForSubtrees(renderSubtreesMap, blockRepaintMode);
949 }
950
951 void RenderView::updateSelectionForSubtrees(RenderSubtreesMap& renderSubtreesMap, SelectionRepaintMode blockRepaintMode)
952 {
953     SubtreeOldSelectionDataMap oldSelectionDataMap;
954     for (auto& subtreeSelectionInfo : renderSubtreesMap) {
955         SelectionSubtreeRoot& root = *subtreeSelectionInfo.key;
956         std::unique_ptr<OldSelectionData> oldSelectionData = std::make_unique<OldSelectionData>();
957
958         clearSubtreeSelection(root, blockRepaintMode, *oldSelectionData);
959         oldSelectionDataMap.set(&root, WTFMove(oldSelectionData));
960
961         root.setSelectionData(subtreeSelectionInfo.value);
962         if (hasRenderNamedFlowThreads())
963             root.adjustForVisibleSelection(document());
964     }
965
966     // Update selection status for the objects inside the selection subtrees.
967     // This needs to be done after the previous loop updated the selectionStart/End
968     // parameters of all subtrees because we're going to be climbing up the containing
969     // block chain and we might end up in a different selection subtree.
970     for (const auto* subtreeSelectionRoot : renderSubtreesMap.keys()) {
971         OldSelectionData& oldSelectionData = *oldSelectionDataMap.get(subtreeSelectionRoot);
972         applySubtreeSelection(*subtreeSelectionRoot, blockRepaintMode, oldSelectionData);
973     }
974 }
975
976 static inline bool isValidObjectForNewSelection(const SelectionSubtreeRoot& root, const RenderObject& object)
977 {
978     return (object.canBeSelectionLeaf() || &object == root.selectionData().selectionStart() || &object == root.selectionData().selectionEnd()) && object.selectionState() != RenderObject::SelectionNone && object.containingBlock();
979 }
980
981 void RenderView::clearSubtreeSelection(const SelectionSubtreeRoot& root, SelectionRepaintMode blockRepaintMode, OldSelectionData& oldSelectionData) const
982 {
983     // Record the old selected objects.  These will be used later
984     // when we compare against the new selected objects.
985     oldSelectionData.selectionStartPos = root.selectionData().selectionStartPos();
986     oldSelectionData.selectionEndPos = root.selectionData().selectionEndPos();
987     
988     // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
989     // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
990     // the union of those rects might remain the same even when changes have occurred.
991
992     RenderObject* os = root.selectionData().selectionStart();
993     auto* selectionEnd = root.selectionData().selectionEnd();
994     RenderObject* stop = nullptr;
995     if (selectionEnd)
996         stop = rendererAfterPosition(selectionEnd, root.selectionData().selectionEndPos().value());
997     SelectionIterator selectionIterator(os);
998     while (os && os != stop) {
999         if (isValidObjectForNewSelection(root, *os)) {
1000             // Blocks are responsible for painting line gaps and margin gaps.  They must be examined as well.
1001             oldSelectionData.selectedObjects.set(os, std::make_unique<RenderSelectionInfo>(*os, true));
1002             if (blockRepaintMode == RepaintNewXOROld) {
1003                 RenderBlock* cb = os->containingBlock();
1004                 while (cb && !is<RenderView>(*cb)) {
1005                     std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = oldSelectionData.selectedBlocks.add(cb, nullptr).iterator->value;
1006                     if (blockInfo)
1007                         break;
1008                     blockInfo = std::make_unique<RenderBlockSelectionInfo>(*cb);
1009                     cb = cb->containingBlock();
1010                 }
1011             }
1012         }
1013
1014         os = selectionIterator.next();
1015     }
1016
1017     for (auto* selectedObject : oldSelectionData.selectedObjects.keys())
1018         selectedObject->setSelectionStateIfNeeded(SelectionNone);
1019 }
1020
1021 void RenderView::applySubtreeSelection(const SelectionSubtreeRoot& root, SelectionRepaintMode blockRepaintMode, const OldSelectionData& oldSelectionData)
1022 {
1023     // Update the selection status of all objects between selectionStart and selectionEnd
1024     if (root.selectionData().selectionStart() && root.selectionData().selectionStart() == root.selectionData().selectionEnd())
1025         root.selectionData().selectionStart()->setSelectionStateIfNeeded(SelectionBoth);
1026     else {
1027         if (root.selectionData().selectionStart())
1028             root.selectionData().selectionStart()->setSelectionStateIfNeeded(SelectionStart);
1029         if (root.selectionData().selectionEnd())
1030             root.selectionData().selectionEnd()->setSelectionStateIfNeeded(SelectionEnd);
1031     }
1032
1033     RenderObject* selectionStart = root.selectionData().selectionStart();
1034     auto* selectionDataEnd = root.selectionData().selectionEnd();
1035     RenderObject* selectionEnd = nullptr;
1036     if (selectionDataEnd)
1037         selectionEnd = rendererAfterPosition(selectionDataEnd, root.selectionData().selectionEndPos().value());
1038     SelectionIterator selectionIterator(selectionStart);
1039     for (RenderObject* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
1040         if (currentRenderer == root.selectionData().selectionStart() || currentRenderer == root.selectionData().selectionEnd())
1041             continue;
1042         if (!currentRenderer->canBeSelectionLeaf())
1043             continue;
1044         // FIXME: Move this logic to SelectionIterator::next()
1045         if (&currentRenderer->selectionRoot() != &root)
1046             continue;
1047         currentRenderer->setSelectionStateIfNeeded(SelectionInside);
1048     }
1049
1050     if (blockRepaintMode != RepaintNothing)
1051         layer()->clearBlockSelectionGapsBounds();
1052
1053     // Now that the selection state has been updated for the new objects, walk them again and
1054     // put them in the new objects list.
1055     SelectedObjectMap newSelectedObjects;
1056     SelectedBlockMap newSelectedBlocks;
1057     selectionIterator = SelectionIterator(selectionStart);
1058     for (RenderObject* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
1059         if (isValidObjectForNewSelection(root, *currentRenderer)) {
1060             std::unique_ptr<RenderSelectionInfo> selectionInfo = std::make_unique<RenderSelectionInfo>(*currentRenderer, true);
1061
1062 #if ENABLE(SERVICE_CONTROLS)
1063             for (auto& rect : selectionInfo->collectedSelectionRects())
1064                 m_selectionRectGatherer.addRect(selectionInfo->repaintContainer(), rect);
1065             if (!currentRenderer->isTextOrLineBreak())
1066                 m_selectionRectGatherer.setTextOnly(false);
1067 #endif
1068
1069             newSelectedObjects.set(currentRenderer, WTFMove(selectionInfo));
1070
1071             RenderBlock* containingBlock = currentRenderer->containingBlock();
1072             while (containingBlock && !is<RenderView>(*containingBlock)) {
1073                 std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(containingBlock, nullptr).iterator->value;
1074                 if (blockInfo)
1075                     break;
1076                 blockInfo = std::make_unique<RenderBlockSelectionInfo>(*containingBlock);
1077                 containingBlock = containingBlock->containingBlock();
1078
1079 #if ENABLE(SERVICE_CONTROLS)
1080                 m_selectionRectGatherer.addGapRects(blockInfo->repaintContainer(), blockInfo->rects());
1081 #endif
1082             }
1083         }
1084     }
1085
1086     if (blockRepaintMode == RepaintNothing)
1087         return;
1088
1089     // Have any of the old selected objects changed compared to the new selection?
1090     for (const auto& selectedObjectInfo : oldSelectionData.selectedObjects) {
1091         RenderObject* obj = selectedObjectInfo.key;
1092         RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);
1093         RenderSelectionInfo* oldInfo = selectedObjectInfo.value.get();
1094         if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state()
1095             || (root.selectionData().selectionStart() == obj && oldSelectionData.selectionStartPos != root.selectionData().selectionStartPos())
1096             || (root.selectionData().selectionEnd() == obj && oldSelectionData.selectionEndPos != root.selectionData().selectionEndPos())) {
1097             oldInfo->repaint();
1098             if (newInfo) {
1099                 newInfo->repaint();
1100                 newSelectedObjects.remove(obj);
1101             }
1102         }
1103     }
1104
1105     // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
1106     for (const auto& selectedObjectInfo : newSelectedObjects)
1107         selectedObjectInfo.value->repaint();
1108
1109     // Have any of the old blocks changed?
1110     for (const auto& selectedBlockInfo : oldSelectionData.selectedBlocks) {
1111         const RenderBlock* block = selectedBlockInfo.key;
1112         RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
1113         RenderBlockSelectionInfo* oldInfo = selectedBlockInfo.value.get();
1114         if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
1115             oldInfo->repaint();
1116             if (newInfo) {
1117                 newInfo->repaint();
1118                 newSelectedBlocks.remove(block);
1119             }
1120         }
1121     }
1122
1123     // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
1124     for (const auto& selectedBlockInfo : newSelectedBlocks)
1125         selectedBlockInfo.value->repaint();
1126 }
1127
1128 void RenderView::getSelection(RenderObject*& startRenderer, std::optional<unsigned>& startOffset, RenderObject*& endRenderer, std::optional<unsigned>& endOffset) const
1129 {
1130     startRenderer = m_selectionUnsplitStart;
1131     startOffset = m_selectionUnsplitStartPos;
1132     endRenderer = m_selectionUnsplitEnd;
1133     endOffset = m_selectionUnsplitEndPos;
1134 }
1135
1136 void RenderView::clearSelection()
1137 {
1138     layer()->repaintBlockSelectionGaps();
1139     setSelection(nullptr, std::nullopt, nullptr, std::nullopt, RepaintNewMinusOld);
1140 }
1141
1142 bool RenderView::printing() const
1143 {
1144     return document().printing();
1145 }
1146
1147 bool RenderView::shouldUsePrintingLayout() const
1148 {
1149     if (!printing())
1150         return false;
1151     return frameView().frame().shouldUsePrintingLayout();
1152 }
1153
1154 LayoutRect RenderView::viewRect() const
1155 {
1156     if (shouldUsePrintingLayout())
1157         return LayoutRect(LayoutPoint(), size());
1158     return frameView().visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect);
1159 }
1160
1161 IntRect RenderView::unscaledDocumentRect() const
1162 {
1163     LayoutRect overflowRect(layoutOverflowRect());
1164     flipForWritingMode(overflowRect);
1165     return snappedIntRect(overflowRect);
1166 }
1167
1168 bool RenderView::rootBackgroundIsEntirelyFixed() const
1169 {
1170     if (auto* rootBackgroundRenderer = rendererForRootBackground())
1171         return rootBackgroundRenderer->style().hasEntirelyFixedBackground();
1172     return false;
1173 }
1174     
1175 LayoutRect RenderView::unextendedBackgroundRect() const
1176 {
1177     // FIXME: What is this? Need to patch for new columns?
1178     return unscaledDocumentRect();
1179 }
1180     
1181 LayoutRect RenderView::backgroundRect() const
1182 {
1183     // FIXME: New columns care about this?
1184     if (frameView().hasExtendedBackgroundRectForPainting())
1185         return frameView().extendedBackgroundRectForPainting();
1186
1187     return unextendedBackgroundRect();
1188 }
1189
1190 IntRect RenderView::documentRect() const
1191 {
1192     FloatRect overflowRect(unscaledDocumentRect());
1193     if (hasTransform())
1194         overflowRect = layer()->currentTransform().mapRect(overflowRect);
1195     return IntRect(overflowRect);
1196 }
1197
1198 int RenderView::viewHeight() const
1199 {
1200     int height = 0;
1201     if (!shouldUsePrintingLayout()) {
1202         height = frameView().layoutHeight();
1203         height = frameView().useFixedLayout() ? ceilf(style().effectiveZoom() * float(height)) : height;
1204     }
1205     return height;
1206 }
1207
1208 int RenderView::viewWidth() const
1209 {
1210     int width = 0;
1211     if (!shouldUsePrintingLayout()) {
1212         width = frameView().layoutWidth();
1213         width = frameView().useFixedLayout() ? ceilf(style().effectiveZoom() * float(width)) : width;
1214     }
1215     return width;
1216 }
1217
1218 int RenderView::viewLogicalHeight() const
1219 {
1220     int height = style().isHorizontalWritingMode() ? viewHeight() : viewWidth();
1221     return height;
1222 }
1223
1224 float RenderView::zoomFactor() const
1225 {
1226     return frameView().frame().pageZoomFactor();
1227 }
1228
1229 void RenderView::pushLayoutState(RenderObject& root)
1230 {
1231     ASSERT(m_layoutStateDisableCount == 0);
1232     ASSERT(m_layoutState == 0);
1233
1234     m_layoutState = std::make_unique<LayoutState>(root);
1235     pushLayoutStateForCurrentFlowThread(root);
1236 }
1237
1238 IntSize RenderView::viewportSizeForCSSViewportUnits() const
1239 {
1240     return frameView().viewportSizeForCSSViewportUnits();
1241 }
1242
1243 void RenderView::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
1244 {
1245     if (result.innerNode())
1246         return;
1247
1248     if (multiColumnFlowThread() && multiColumnFlowThread()->firstMultiColumnSet())
1249         return multiColumnFlowThread()->firstMultiColumnSet()->updateHitTestResult(result, point);
1250
1251     Node* node = document().documentElement();
1252     if (node) {
1253         result.setInnerNode(node);
1254         if (!result.innerNonSharedNode())
1255             result.setInnerNonSharedNode(node);
1256
1257         LayoutPoint adjustedPoint = point;
1258         offsetForContents(adjustedPoint);
1259
1260         result.setLocalPoint(adjustedPoint);
1261     }
1262 }
1263
1264 // FIXME: This function is obsolete and only used by embedded WebViews inside AppKit NSViews.
1265 // Do not add callers of this function!
1266 // The idea here is to take into account what object is moving the pagination point, and
1267 // thus choose the best place to chop it.
1268 void RenderView::setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak)
1269 {
1270     // Nobody else can set a page break once we have a forced break.
1271     if (m_legacyPrinting.m_forcedPageBreak)
1272         return;
1273
1274     // Forced breaks always win over unforced breaks.
1275     if (forcedBreak) {
1276         m_legacyPrinting.m_forcedPageBreak = true;
1277         m_legacyPrinting.m_bestTruncatedAt = y;
1278         return;
1279     }
1280
1281     // Prefer the widest object that tries to move the pagination point
1282     LayoutRect boundingBox = forRenderer->borderBoundingBox();
1283     if (boundingBox.width() > m_legacyPrinting.m_truncatorWidth) {
1284         m_legacyPrinting.m_truncatorWidth = boundingBox.width();
1285         m_legacyPrinting.m_bestTruncatedAt = y;
1286     }
1287 }
1288
1289 bool RenderView::usesCompositing() const
1290 {
1291     return m_compositor && m_compositor->inCompositingMode();
1292 }
1293
1294 RenderLayerCompositor& RenderView::compositor()
1295 {
1296     if (!m_compositor)
1297         m_compositor = std::make_unique<RenderLayerCompositor>(*this);
1298
1299     return *m_compositor;
1300 }
1301
1302 void RenderView::setIsInWindow(bool isInWindow)
1303 {
1304     if (m_compositor)
1305         m_compositor->setIsInWindow(isInWindow);
1306 }
1307
1308 void RenderView::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
1309 {
1310     RenderBlockFlow::styleDidChange(diff, oldStyle);
1311     if (hasRenderNamedFlowThreads())
1312         flowThreadController().styleDidChange();
1313
1314     frameView().styleDidChange();
1315 }
1316
1317 bool RenderView::hasRenderNamedFlowThreads() const
1318 {
1319     return m_flowThreadController && m_flowThreadController->hasRenderNamedFlowThreads();
1320 }
1321
1322 bool RenderView::checkTwoPassLayoutForAutoHeightRegions() const
1323 {
1324     return hasRenderNamedFlowThreads() && m_flowThreadController->hasFlowThreadsWithAutoLogicalHeightRegions();
1325 }
1326
1327 FlowThreadController& RenderView::flowThreadController()
1328 {
1329     if (!m_flowThreadController)
1330         m_flowThreadController = std::make_unique<FlowThreadController>(this);
1331
1332     return *m_flowThreadController;
1333 }
1334
1335 void RenderView::pushLayoutStateForCurrentFlowThread(const RenderObject& object)
1336 {
1337     if (!m_flowThreadController)
1338         return;
1339
1340     RenderFlowThread* currentFlowThread = object.flowThreadContainingBlock();
1341     if (!currentFlowThread)
1342         return;
1343
1344     m_layoutState->setCurrentRenderFlowThread(currentFlowThread);
1345
1346     currentFlowThread->pushFlowThreadLayoutState(object);
1347 }
1348
1349 void RenderView::popLayoutStateForCurrentFlowThread()
1350 {
1351     if (!m_flowThreadController)
1352         return;
1353
1354     RenderFlowThread* currentFlowThread = m_layoutState->currentRenderFlowThread();
1355     if (!currentFlowThread)
1356         return;
1357
1358     currentFlowThread->popFlowThreadLayoutState();
1359 }
1360
1361 ImageQualityController& RenderView::imageQualityController()
1362 {
1363     if (!m_imageQualityController)
1364         m_imageQualityController = std::make_unique<ImageQualityController>(*this);
1365     return *m_imageQualityController;
1366 }
1367
1368 void RenderView::registerForVisibleInViewportCallback(RenderElement& renderer)
1369 {
1370     ASSERT(!m_visibleInViewportRenderers.contains(&renderer));
1371     m_visibleInViewportRenderers.add(&renderer);
1372 }
1373
1374 void RenderView::unregisterForVisibleInViewportCallback(RenderElement& renderer)
1375 {
1376     ASSERT(m_visibleInViewportRenderers.contains(&renderer));
1377     m_visibleInViewportRenderers.remove(&renderer);
1378 }
1379
1380 void RenderView::updateVisibleViewportRect(const IntRect& visibleRect)
1381 {
1382     resumePausedImageAnimationsIfNeeded(visibleRect);
1383
1384     for (auto* renderer : m_visibleInViewportRenderers)
1385         renderer->visibleInViewportStateChanged(visibleRect.intersects(enclosingIntRect(renderer->absoluteClippedOverflowRect())) ? RenderElement::VisibleInViewport : RenderElement::NotVisibleInViewport);
1386 }
1387
1388 void RenderView::addRendererWithPausedImageAnimations(RenderElement& renderer)
1389 {
1390     if (renderer.hasPausedImageAnimations()) {
1391         ASSERT(m_renderersWithPausedImageAnimation.contains(&renderer));
1392         return;
1393     }
1394     renderer.setHasPausedImageAnimations(true);
1395     m_renderersWithPausedImageAnimation.add(&renderer);
1396 }
1397
1398 void RenderView::removeRendererWithPausedImageAnimations(RenderElement& renderer)
1399 {
1400     ASSERT(renderer.hasPausedImageAnimations());
1401     ASSERT(m_renderersWithPausedImageAnimation.contains(&renderer));
1402
1403     renderer.setHasPausedImageAnimations(false);
1404     m_renderersWithPausedImageAnimation.remove(&renderer);
1405 }
1406
1407 void RenderView::resumePausedImageAnimationsIfNeeded(IntRect visibleRect)
1408 {
1409     Vector<RenderElement*, 10> toRemove;
1410     for (auto* renderer : m_renderersWithPausedImageAnimation) {
1411         if (renderer->repaintForPausedImageAnimationsIfNeeded(visibleRect))
1412             toRemove.append(renderer);
1413     }
1414     for (auto& renderer : toRemove)
1415         removeRendererWithPausedImageAnimations(*renderer);
1416 }
1417
1418 RenderView::RepaintRegionAccumulator::RepaintRegionAccumulator(RenderView* view)
1419     : m_rootView(view ? view->document().topDocument().renderView() : nullptr)
1420 {
1421     if (!m_rootView)
1422         return;
1423     m_wasAccumulatingRepaintRegion = !!m_rootView->m_accumulatedRepaintRegion;
1424     if (!m_wasAccumulatingRepaintRegion)
1425         m_rootView->m_accumulatedRepaintRegion = std::make_unique<Region>();
1426 }
1427
1428 RenderView::RepaintRegionAccumulator::~RepaintRegionAccumulator()
1429 {
1430     if (!m_rootView)
1431         return;
1432     if (m_wasAccumulatingRepaintRegion)
1433         return;
1434     m_rootView->flushAccumulatedRepaintRegion();
1435 }
1436
1437 unsigned RenderView::pageNumberForBlockProgressionOffset(int offset) const
1438 {
1439     int columnNumber = 0;
1440     const Pagination& pagination = frameView().frame().page()->pagination();
1441     if (pagination.mode == Pagination::Unpaginated)
1442         return columnNumber;
1443     
1444     bool progressionIsInline = false;
1445     bool progressionIsReversed = false;
1446     
1447     if (multiColumnFlowThread()) {
1448         progressionIsInline = multiColumnFlowThread()->progressionIsInline();
1449         progressionIsReversed = multiColumnFlowThread()->progressionIsReversed();
1450     } else
1451         return columnNumber;
1452     
1453     if (!progressionIsInline) {
1454         if (!progressionIsReversed)
1455             columnNumber = (pagination.pageLength + pagination.gap - offset) / (pagination.pageLength + pagination.gap);
1456         else
1457             columnNumber = offset / (pagination.pageLength + pagination.gap);
1458     }
1459
1460     return columnNumber;
1461 }
1462
1463 unsigned RenderView::pageCount() const
1464 {
1465     const Pagination& pagination = frameView().frame().page()->pagination();
1466     if (pagination.mode == Pagination::Unpaginated)
1467         return 0;
1468     
1469     if (multiColumnFlowThread() && multiColumnFlowThread()->firstMultiColumnSet())
1470         return multiColumnFlowThread()->firstMultiColumnSet()->columnCount();
1471
1472     return 0;
1473 }
1474
1475 #if ENABLE(CSS_SCROLL_SNAP)
1476 void RenderView::registerBoxWithScrollSnapPositions(const RenderBox& box)
1477 {
1478     m_boxesWithScrollSnapPositions.add(&box);
1479 }
1480
1481 void RenderView::unregisterBoxWithScrollSnapPositions(const RenderBox& box)
1482 {
1483     m_boxesWithScrollSnapPositions.remove(&box);
1484 }
1485 #endif
1486
1487 } // namespace WebCore