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