LEFT | RIGHT |
1 /* | 1 /* |
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> | 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> |
3 * 1999 Lars Knoll <knoll@kde.org> | 3 * 1999 Lars Knoll <knoll@kde.org> |
4 * 1999 Antti Koivisto <koivisto@kde.org> | 4 * 1999 Antti Koivisto <koivisto@kde.org> |
5 * 2000 Dirk Mueller <mueller@kde.org> | 5 * 2000 Dirk Mueller <mueller@kde.org> |
6 * Copyright (C) 2004-2017 Apple Inc. All rights reserved. | 6 * Copyright (C) 2004-2017 Apple Inc. All rights reserved. |
7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) | 7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) |
8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
9 * Copyright (C) 2009 Google Inc. All rights reserved. | 9 * Copyright (C) 2009 Google Inc. All rights reserved. |
10 * | 10 * |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 111 |
112 #if ENABLE(CSS_SCROLL_SNAP) | 112 #if ENABLE(CSS_SCROLL_SNAP) |
113 #include "AxisScrollSnapOffsets.h" | 113 #include "AxisScrollSnapOffsets.h" |
114 #endif | 114 #endif |
115 | 115 |
116 #if PLATFORM(IOS) | 116 #if PLATFORM(IOS) |
117 #include "DocumentLoader.h" | 117 #include "DocumentLoader.h" |
118 #include "LegacyTileCache.h" | 118 #include "LegacyTileCache.h" |
119 #endif | 119 #endif |
120 | 120 |
| 121 #define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(frame().page() && frame(
).page()->isAlwaysOnLoggingAllowed(), Layout, "%p - FrameView::" fmt, this, ##__
VA_ARGS__) |
| 122 |
121 namespace WebCore { | 123 namespace WebCore { |
122 | 124 |
123 using namespace HTMLNames; | 125 using namespace HTMLNames; |
124 | 126 |
125 WTF_MAKE_ISO_ALLOCATED_IMPL(FrameView); | 127 WTF_MAKE_ISO_ALLOCATED_IMPL(FrameView); |
126 | 128 |
127 MonotonicTime FrameView::sCurrentPaintTimeStamp { }; | 129 MonotonicTime FrameView::sCurrentPaintTimeStamp { }; |
128 | 130 |
129 // The maximum number of updateEmbeddedObjects iterations that should be done be
fore returning. | 131 // The maximum number of updateEmbeddedObjects iterations that should be done be
fore returning. |
130 static const unsigned maxUpdateEmbeddedObjectsIterations = 2; | 132 static const unsigned maxUpdateEmbeddedObjectsIterations = 2; |
| 133 |
| 134 static constexpr unsigned defaultSignificantRenderedTextCharacterThreshold = 300
0; |
| 135 static constexpr float defaultSignificantRenderedTextMeanLength = 50; |
| 136 static constexpr unsigned mainArticleSignificantRenderedTextCharacterThreshold =
1500; |
| 137 static constexpr float mainArticleSignificantRenderedTextMeanLength = 25; |
131 | 138 |
132 static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLay
er* layer, bool isRelayoutingSubtree, bool didFullRepaint) | 139 static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLay
er* layer, bool isRelayoutingSubtree, bool didFullRepaint) |
133 { | 140 { |
134 RenderLayer::UpdateLayerPositionsFlags flags = RenderLayer::defaultFlags; | 141 RenderLayer::UpdateLayerPositionsFlags flags = RenderLayer::defaultFlags; |
135 if (didFullRepaint) { | 142 if (didFullRepaint) { |
136 flags &= ~RenderLayer::CheckForRepaint; | 143 flags &= ~RenderLayer::CheckForRepaint; |
137 flags |= RenderLayer::NeedsFullRepaintInBacking; | 144 flags |= RenderLayer::NeedsFullRepaintInBacking; |
138 } | 145 } |
139 if (isRelayoutingSubtree && layer->enclosingPaginationLayer(RenderLayer::Inc
ludeCompositedPaginatedLayers)) | 146 if (isRelayoutingSubtree && layer->enclosingPaginationLayer(RenderLayer::Inc
ludeCompositedPaginatedLayers)) |
140 flags |= RenderLayer::UpdatePagination; | 147 flags |= RenderLayer::UpdatePagination; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 m_firstLayoutCallbackPending = false; | 270 m_firstLayoutCallbackPending = false; |
264 m_wasScrolledByUser = false; | 271 m_wasScrolledByUser = false; |
265 m_delayedScrollEventTimer.stop(); | 272 m_delayedScrollEventTimer.stop(); |
266 m_shouldScrollToFocusedElement = false; | 273 m_shouldScrollToFocusedElement = false; |
267 m_delayedScrollToFocusedElementTimer.stop(); | 274 m_delayedScrollToFocusedElementTimer.stop(); |
268 m_lastViewportSize = IntSize(); | 275 m_lastViewportSize = IntSize(); |
269 m_lastZoomFactor = 1.0f; | 276 m_lastZoomFactor = 1.0f; |
270 m_isTrackingRepaints = false; | 277 m_isTrackingRepaints = false; |
271 m_trackedRepaintRects.clear(); | 278 m_trackedRepaintRects.clear(); |
272 m_lastPaintTime = MonotonicTime(); | 279 m_lastPaintTime = MonotonicTime(); |
273 m_paintBehavior = PaintBehaviorNormal; | 280 m_paintBehavior = PaintBehavior::Normal; |
274 m_isPainting = false; | 281 m_isPainting = false; |
275 m_visuallyNonEmptyCharacterCount = 0; | 282 m_visuallyNonEmptyCharacterCount = 0; |
276 m_visuallyNonEmptyPixelCount = 0; | 283 m_visuallyNonEmptyPixelCount = 0; |
277 m_isVisuallyNonEmpty = false; | 284 m_isVisuallyNonEmpty = false; |
278 m_firstVisuallyNonEmptyLayoutCallbackPending = true; | 285 m_firstVisuallyNonEmptyLayoutCallbackPending = true; |
| 286 m_renderTextCountForVisuallyNonEmptyCharacters = 0; |
| 287 m_renderedSignificantAmountOfText = false; |
| 288 m_significantRenderedTextMilestonePending = true; |
279 m_needsDeferredScrollbarsUpdate = false; | 289 m_needsDeferredScrollbarsUpdate = false; |
280 m_maintainScrollPositionAnchor = nullptr; | 290 m_maintainScrollPositionAnchor = nullptr; |
281 layoutContext().reset(); | 291 layoutContext().reset(); |
282 } | 292 } |
283 | 293 |
284 void FrameView::removeFromAXObjectCache() | 294 void FrameView::removeFromAXObjectCache() |
285 { | 295 { |
286 if (AXObjectCache* cache = axObjectCache()) { | 296 if (AXObjectCache* cache = axObjectCache()) { |
287 if (HTMLFrameOwnerElement* owner = frame().ownerElement()) | 297 if (HTMLFrameOwnerElement* owner = frame().ownerElement()) |
288 cache->childrenChanged(owner->renderer()); | 298 cache->childrenChanged(owner->renderer()); |
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 { | 1386 { |
1377 if (printing) { | 1387 if (printing) { |
1378 if (m_mediaTypeWhenNotPrinting.isNull()) | 1388 if (m_mediaTypeWhenNotPrinting.isNull()) |
1379 m_mediaTypeWhenNotPrinting = mediaType(); | 1389 m_mediaTypeWhenNotPrinting = mediaType(); |
1380 setMediaType("print"); | 1390 setMediaType("print"); |
1381 } else { | 1391 } else { |
1382 if (!m_mediaTypeWhenNotPrinting.isNull()) | 1392 if (!m_mediaTypeWhenNotPrinting.isNull()) |
1383 setMediaType(m_mediaTypeWhenNotPrinting); | 1393 setMediaType(m_mediaTypeWhenNotPrinting); |
1384 m_mediaTypeWhenNotPrinting = String(); | 1394 m_mediaTypeWhenNotPrinting = String(); |
1385 } | 1395 } |
1386 | |
1387 RenderTheme::singleton().platformColorsDidChange(); | |
1388 } | 1396 } |
1389 | 1397 |
1390 bool FrameView::useSlowRepaints(bool considerOverlap) const | 1398 bool FrameView::useSlowRepaints(bool considerOverlap) const |
1391 { | 1399 { |
1392 bool mustBeSlow = hasSlowRepaintObjects() || (platformWidget() && hasViewpor
tConstrainedObjects()); | 1400 bool mustBeSlow = hasSlowRepaintObjects() || (platformWidget() && hasViewpor
tConstrainedObjects()); |
1393 | 1401 |
1394 // FIXME: WidgetMac.mm makes the assumption that useSlowRepaints == | 1402 // FIXME: WidgetMac.mm makes the assumption that useSlowRepaints == |
1395 // m_contentIsOpaque, so don't take the fast path for composited layers | 1403 // m_contentIsOpaque, so don't take the fast path for composited layers |
1396 // if they are a platform widget in order to get painting correctness | 1404 // if they are a platform widget in order to get painting correctness |
1397 // for transparent layers. See the comment in WidgetMac::paint. | 1405 // for transparent layers. See the comment in WidgetMac::paint. |
(...skipping 1813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3211 Vector<Function<void()>> queue = WTFMove(m_postLayoutCallbackQueue); | 3219 Vector<Function<void()>> queue = WTFMove(m_postLayoutCallbackQueue); |
3212 for (auto& task : queue) | 3220 for (auto& task : queue) |
3213 task(); | 3221 task(); |
3214 } | 3222 } |
3215 | 3223 |
3216 void FrameView::performPostLayoutTasks() | 3224 void FrameView::performPostLayoutTasks() |
3217 { | 3225 { |
3218 // FIXME: We should not run any JavaScript code in this function. | 3226 // FIXME: We should not run any JavaScript code in this function. |
3219 LOG(Layout, "FrameView %p performPostLayoutTasks", this); | 3227 LOG(Layout, "FrameView %p performPostLayoutTasks", this); |
3220 | 3228 |
| 3229 frame().document()->updateMainArticleElementAfterLayout(); |
3221 frame().selection().updateAppearanceAfterLayout(); | 3230 frame().selection().updateAppearanceAfterLayout(); |
3222 | 3231 |
3223 flushPostLayoutTasksQueue(); | 3232 flushPostLayoutTasksQueue(); |
3224 | 3233 |
3225 if (!layoutContext().isLayoutNested() && frame().document()->documentElement
()) | 3234 if (!layoutContext().isLayoutNested() && frame().document()->documentElement
()) |
3226 fireLayoutRelatedMilestonesIfNeeded(); | 3235 fireLayoutRelatedMilestonesIfNeeded(); |
3227 | 3236 |
3228 #if PLATFORM(IOS) | 3237 #if PLATFORM(IOS) |
3229 // Only send layout-related delegate callbacks synchronously for the main fr
ame to | 3238 // Only send layout-related delegate callbacks synchronously for the main fr
ame to |
3230 // avoid re-entering layout for the main frame while delivering a layout-rel
ated delegate | 3239 // avoid re-entering layout for the main frame while delivering a layout-rel
ated delegate |
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3858 m_scrollCorner = createRenderer<RenderScrollbarPart>(renderer->docum
ent(), WTFMove(*cornerStyle)); | 3867 m_scrollCorner = createRenderer<RenderScrollbarPart>(renderer->docum
ent(), WTFMove(*cornerStyle)); |
3859 m_scrollCorner->initializeStyle(); | 3868 m_scrollCorner->initializeStyle(); |
3860 } else | 3869 } else |
3861 m_scrollCorner->setStyle(WTFMove(*cornerStyle)); | 3870 m_scrollCorner->setStyle(WTFMove(*cornerStyle)); |
3862 invalidateScrollCorner(cornerRect); | 3871 invalidateScrollCorner(cornerRect); |
3863 } | 3872 } |
3864 } | 3873 } |
3865 | 3874 |
3866 void FrameView::paintScrollCorner(GraphicsContext& context, const IntRect& corne
rRect) | 3875 void FrameView::paintScrollCorner(GraphicsContext& context, const IntRect& corne
rRect) |
3867 { | 3876 { |
3868 if (context.updatingControlTints()) { | 3877 if (context.invalidatingControlTints()) { |
3869 updateScrollCorner(); | 3878 updateScrollCorner(); |
3870 return; | 3879 return; |
3871 } | 3880 } |
3872 | 3881 |
3873 if (m_scrollCorner) { | 3882 if (m_scrollCorner) { |
3874 if (frame().isMainFrame()) | 3883 if (frame().isMainFrame()) |
3875 context.fillRect(cornerRect, baseBackgroundColor()); | 3884 context.fillRect(cornerRect, baseBackgroundColor()); |
3876 m_scrollCorner->paintIntoRect(context, cornerRect.location(), cornerRect
); | 3885 m_scrollCorner->paintIntoRect(context, cornerRect.location(), cornerRect
); |
3877 return; | 3886 return; |
3878 } | 3887 } |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3995 // As noted above, this is a "fake" paint, so we should pause counting relev
ant repainted objects. | 4004 // As noted above, this is a "fake" paint, so we should pause counting relev
ant repainted objects. |
3996 Page* page = frame().page(); | 4005 Page* page = frame().page(); |
3997 bool isCurrentlyCountingRelevantRepaintedObject = false; | 4006 bool isCurrentlyCountingRelevantRepaintedObject = false; |
3998 if (page) { | 4007 if (page) { |
3999 isCurrentlyCountingRelevantRepaintedObject = page->isCountingRelevantRep
aintedObjects(); | 4008 isCurrentlyCountingRelevantRepaintedObject = page->isCountingRelevantRep
aintedObjects(); |
4000 page->setIsCountingRelevantRepaintedObjects(false); | 4009 page->setIsCountingRelevantRepaintedObjects(false); |
4001 } | 4010 } |
4002 | 4011 |
4003 RenderView* renderView = this->renderView(); | 4012 RenderView* renderView = this->renderView(); |
4004 if ((renderView && renderView->theme().supportsControlTints()) || hasCustomS
crollbars()) | 4013 if ((renderView && renderView->theme().supportsControlTints()) || hasCustomS
crollbars()) |
4005 paintControlTints(); | 4014 invalidateControlTints(); |
4006 | 4015 |
4007 if (page) | 4016 if (page) |
4008 page->setIsCountingRelevantRepaintedObjects(isCurrentlyCountingRelevantR
epaintedObject); | 4017 page->setIsCountingRelevantRepaintedObjects(isCurrentlyCountingRelevantR
epaintedObject); |
4009 } | 4018 } |
4010 | 4019 |
4011 void FrameView::paintControlTints() | 4020 void FrameView::traverseForPaintInvalidation(GraphicsContext::PaintInvalidationR
easons paintInvalidationReasons) |
4012 { | 4021 { |
4013 if (needsLayout()) | 4022 if (needsLayout()) |
4014 layoutContext().layout(); | 4023 layoutContext().layout(); |
4015 | 4024 |
4016 GraphicsContext context(GraphicsContext::NonPaintingReasons::UpdatingControl
Tints); | 4025 GraphicsContext context(paintInvalidationReasons); |
4017 if (platformWidget()) { | 4026 if (platformWidget()) { |
4018 // FIXME: consult paintsEntireContents(). | 4027 // FIXME: consult paintsEntireContents(). |
4019 paintContents(context, visibleContentRect(LegacyIOSDocumentVisibleRect))
; | 4028 paintContents(context, visibleContentRect(LegacyIOSDocumentVisibleRect))
; |
4020 } else | 4029 } else |
4021 paint(context, frameRect()); | 4030 paint(context, frameRect()); |
4022 } | 4031 } |
4023 | 4032 |
4024 bool FrameView::wasScrolledByUser() const | 4033 bool FrameView::wasScrolledByUser() const |
4025 { | 4034 { |
4026 return m_wasScrolledByUser; | 4035 return m_wasScrolledByUser; |
(...skipping 24 matching lines...) Expand all Loading... |
4051 InspectorInstrumentation::willPaint(*renderView()); | 4060 InspectorInstrumentation::willPaint(*renderView()); |
4052 | 4061 |
4053 paintingState.isTopLevelPainter = !sCurrentPaintTimeStamp; | 4062 paintingState.isTopLevelPainter = !sCurrentPaintTimeStamp; |
4054 | 4063 |
4055 if (paintingState.isTopLevelPainter) | 4064 if (paintingState.isTopLevelPainter) |
4056 sCurrentPaintTimeStamp = MonotonicTime::now(); | 4065 sCurrentPaintTimeStamp = MonotonicTime::now(); |
4057 | 4066 |
4058 paintingState.paintBehavior = m_paintBehavior; | 4067 paintingState.paintBehavior = m_paintBehavior; |
4059 ···· | 4068 ···· |
4060 if (FrameView* parentView = parentFrameView()) { | 4069 if (FrameView* parentView = parentFrameView()) { |
4061 if (parentView->paintBehavior() & PaintBehaviorFlattenCompositingLayers) | 4070 if (parentView->paintBehavior() & PaintBehavior::FlattenCompositingLayer
s) |
4062 m_paintBehavior |= PaintBehaviorFlattenCompositingLayers; | 4071 m_paintBehavior |= PaintBehavior::FlattenCompositingLayers; |
4063 ········ | 4072 ········ |
4064 if (parentView->paintBehavior() & PaintBehaviorSnapshotting) | 4073 if (parentView->paintBehavior() & PaintBehavior::Snapshotting) |
4065 m_paintBehavior |= PaintBehaviorSnapshotting; | 4074 m_paintBehavior |= PaintBehavior::Snapshotting; |
4066 ········ | 4075 ········ |
4067 if (parentView->paintBehavior() & PaintBehaviorTileFirstPaint) | 4076 if (parentView->paintBehavior() & PaintBehavior::TileFirstPaint) |
4068 m_paintBehavior |= PaintBehaviorTileFirstPaint; | 4077 m_paintBehavior |= PaintBehavior::TileFirstPaint; |
4069 } | 4078 } |
4070 | 4079 |
4071 if (document->printing()) | 4080 if (document->printing()) { |
4072 m_paintBehavior |= (PaintBehaviorFlattenCompositingLayers | PaintBehavio
rSnapshotting); | 4081 m_paintBehavior |= PaintBehavior::FlattenCompositingLayers; |
4073 | 4082 m_paintBehavior |= PaintBehavior::Snapshotting; |
4074 paintingState.isFlatteningPaintOfRootFrame = (m_paintBehavior & PaintBehavio
rFlattenCompositingLayers) && !frame().ownerElement(); | 4083 } |
| 4084 |
| 4085 paintingState.isFlatteningPaintOfRootFrame = (m_paintBehavior & PaintBehavio
r::FlattenCompositingLayers) && !frame().ownerElement(); |
4075 if (paintingState.isFlatteningPaintOfRootFrame) | 4086 if (paintingState.isFlatteningPaintOfRootFrame) |
4076 notifyWidgetsInAllFrames(WillPaintFlattened); | 4087 notifyWidgetsInAllFrames(WillPaintFlattened); |
4077 | 4088 |
4078 ASSERT(!m_isPainting); | 4089 ASSERT(!m_isPainting); |
4079 m_isPainting = true; | 4090 m_isPainting = true; |
4080 } | 4091 } |
4081 | 4092 |
4082 void FrameView::didPaintContents(GraphicsContext& context, const IntRect& dirtyR
ect, PaintingState& paintingState) | 4093 void FrameView::didPaintContents(GraphicsContext& context, const IntRect& dirtyR
ect, PaintingState& paintingState) |
4083 { | 4094 { |
4084 m_isPainting = false; | 4095 m_isPainting = false; |
(...skipping 23 matching lines...) Expand all Loading... |
4108 void FrameView::paintContents(GraphicsContext& context, const IntRect& dirtyRect
, SecurityOriginPaintPolicy securityOriginPaintPolicy) | 4119 void FrameView::paintContents(GraphicsContext& context, const IntRect& dirtyRect
, SecurityOriginPaintPolicy securityOriginPaintPolicy) |
4109 { | 4120 { |
4110 #ifndef NDEBUG | 4121 #ifndef NDEBUG |
4111 bool fillWithWarningColor; | 4122 bool fillWithWarningColor; |
4112 if (frame().document()->printing()) | 4123 if (frame().document()->printing()) |
4113 fillWithWarningColor = false; // Printing, don't fill with red (can't re
member why). | 4124 fillWithWarningColor = false; // Printing, don't fill with red (can't re
member why). |
4114 else if (frame().ownerElement()) | 4125 else if (frame().ownerElement()) |
4115 fillWithWarningColor = false; // Subframe, don't fill with red. | 4126 fillWithWarningColor = false; // Subframe, don't fill with red. |
4116 else if (isTransparent()) | 4127 else if (isTransparent()) |
4117 fillWithWarningColor = false; // Transparent, don't fill with red. | 4128 fillWithWarningColor = false; // Transparent, don't fill with red. |
4118 else if (m_paintBehavior & PaintBehaviorSelectionOnly) | 4129 else if (m_paintBehavior & PaintBehavior::SelectionOnly) |
4119 fillWithWarningColor = false; // Selections are transparent, don't fill
with red. | 4130 fillWithWarningColor = false; // Selections are transparent, don't fill
with red. |
4120 else if (m_nodeToDraw) | 4131 else if (m_nodeToDraw) |
4121 fillWithWarningColor = false; // Element images are transparent, don't f
ill with red. | 4132 fillWithWarningColor = false; // Element images are transparent, don't f
ill with red. |
4122 else | 4133 else |
4123 fillWithWarningColor = true; | 4134 fillWithWarningColor = true; |
4124 ···· | 4135 ···· |
4125 if (fillWithWarningColor) | 4136 if (fillWithWarningColor) |
4126 context.fillRect(dirtyRect, Color(255, 64, 255)); | 4137 context.fillRect(dirtyRect, Color(255, 64, 255)); |
4127 #endif | 4138 #endif |
4128 | 4139 |
4129 RenderView* renderView = this->renderView(); | 4140 RenderView* renderView = this->renderView(); |
4130 if (!renderView) { | 4141 if (!renderView) { |
4131 LOG_ERROR("called FrameView::paint with nil renderer"); | 4142 LOG_ERROR("called FrameView::paint with nil renderer"); |
4132 return; | 4143 return; |
4133 } | 4144 } |
4134 | 4145 |
4135 if (!layoutContext().inPaintableState()) | 4146 if (!layoutContext().inPaintableState()) |
4136 return; | 4147 return; |
4137 | 4148 |
4138 ASSERT(!needsLayout()); | 4149 ASSERT(!needsLayout()); |
4139 if (needsLayout()) | 4150 if (needsLayout()) { |
4140 return; | 4151 RELEASE_LOG_IF_ALLOWED("FrameView::paintContents() - not painting becaus
e render tree needs layout (is main frame %d)", frame().isMainFrame()); |
| 4152 return; |
| 4153 } |
4141 | 4154 |
4142 PaintingState paintingState; | 4155 PaintingState paintingState; |
4143 willPaintContents(context, dirtyRect, paintingState); | 4156 willPaintContents(context, dirtyRect, paintingState); |
4144 | 4157 |
4145 // m_nodeToDraw is used to draw only one element (and its descendants) | 4158 // m_nodeToDraw is used to draw only one element (and its descendants) |
4146 RenderObject* renderer = m_nodeToDraw ? m_nodeToDraw->renderer() : nullptr; | 4159 RenderObject* renderer = m_nodeToDraw ? m_nodeToDraw->renderer() : nullptr; |
4147 RenderLayer* rootLayer = renderView->layer(); | 4160 RenderLayer* rootLayer = renderView->layer(); |
4148 | 4161 |
4149 #ifndef NDEBUG | 4162 #ifndef NDEBUG |
4150 RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&rootLayer
->renderer()); | 4163 RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&rootLayer
->renderer()); |
4151 #endif | 4164 #endif |
4152 | 4165 |
4153 // To work around http://webkit.org/b/135106, ensure that the paint root isn
't an inline with culled line boxes. | 4166 // To work around http://webkit.org/b/135106, ensure that the paint root isn
't an inline with culled line boxes. |
4154 // FIXME: This can cause additional content to be included in the snapshot,
so remove this once that bug is fixed. | 4167 // FIXME: This can cause additional content to be included in the snapshot,
so remove this once that bug is fixed. |
4155 while (is<RenderInline>(renderer) && !downcast<RenderInline>(*renderer).firs
tLineBox()) | 4168 while (is<RenderInline>(renderer) && !downcast<RenderInline>(*renderer).firs
tLineBox()) |
4156 renderer = renderer->parent(); | 4169 renderer = renderer->parent(); |
4157 | 4170 |
4158 rootLayer->paint(context, dirtyRect, LayoutSize(), m_paintBehavior, renderer
, 0, securityOriginPaintPolicy == SecurityOriginPaintPolicy::AnyOrigin ? RenderL
ayer::SecurityOriginPaintPolicy::AnyOrigin : RenderLayer::SecurityOriginPaintPol
icy::AccessibleOriginOnly); | 4171 rootLayer->paint(context, dirtyRect, LayoutSize(), m_paintBehavior, renderer
, 0, securityOriginPaintPolicy == SecurityOriginPaintPolicy::AnyOrigin ? RenderL
ayer::SecurityOriginPaintPolicy::AnyOrigin : RenderLayer::SecurityOriginPaintPol
icy::AccessibleOriginOnly); |
4159 if (rootLayer->containsDirtyOverlayScrollbars()) | 4172 if (rootLayer->containsDirtyOverlayScrollbars()) |
4160 rootLayer->paintOverlayScrollbars(context, dirtyRect, m_paintBehavior, r
enderer); | 4173 rootLayer->paintOverlayScrollbars(context, dirtyRect, m_paintBehavior, r
enderer); |
4161 | 4174 |
4162 didPaintContents(context, dirtyRect, paintingState); | 4175 didPaintContents(context, dirtyRect, paintingState); |
4163 } | 4176 } |
4164 | 4177 |
4165 void FrameView::setPaintBehavior(PaintBehavior behavior) | 4178 void FrameView::setPaintBehavior(OptionSet<PaintBehavior> behavior) |
4166 { | 4179 { |
4167 m_paintBehavior = behavior; | 4180 m_paintBehavior = behavior; |
4168 } | 4181 } |
4169 | 4182 |
4170 PaintBehavior FrameView::paintBehavior() const | 4183 OptionSet<PaintBehavior> FrameView::paintBehavior() const |
4171 { | 4184 { |
4172 return m_paintBehavior; | 4185 return m_paintBehavior; |
4173 } | 4186 } |
4174 | 4187 |
4175 bool FrameView::isPainting() const | 4188 bool FrameView::isPainting() const |
4176 { | 4189 { |
4177 return m_isPainting; | 4190 return m_isPainting; |
4178 } | 4191 } |
4179 | 4192 |
4180 // FIXME: change this to use the subtreePaint terminology. | 4193 // FIXME: change this to use the subtreePaint terminology. |
4181 void FrameView::setNodeToDraw(Node* node) | 4194 void FrameView::setNodeToDraw(Node* node) |
4182 { | 4195 { |
4183 m_nodeToDraw = node; | 4196 m_nodeToDraw = node; |
4184 } | 4197 } |
4185 | 4198 |
4186 void FrameView::paintContentsForSnapshot(GraphicsContext& context, const IntRect
& imageRect, SelectionInSnapshot shouldPaintSelection, CoordinateSpaceForSnapsho
t coordinateSpace) | 4199 void FrameView::paintContentsForSnapshot(GraphicsContext& context, const IntRect
& imageRect, SelectionInSnapshot shouldPaintSelection, CoordinateSpaceForSnapsho
t coordinateSpace) |
4187 { | 4200 { |
4188 updateLayoutAndStyleIfNeededRecursive(); | 4201 updateLayoutAndStyleIfNeededRecursive(); |
4189 | 4202 |
4190 // Cache paint behavior and set a new behavior appropriate for snapshots. | 4203 // Cache paint behavior and set a new behavior appropriate for snapshots. |
4191 PaintBehavior oldBehavior = paintBehavior(); | 4204 auto oldBehavior = paintBehavior(); |
4192 setPaintBehavior(oldBehavior | (PaintBehaviorFlattenCompositingLayers | Pain
tBehaviorSnapshotting)); | 4205 setPaintBehavior(oldBehavior | PaintBehavior::FlattenCompositingLayers | Pai
ntBehavior::Snapshotting); |
4193 | 4206 |
4194 // If the snapshot should exclude selection, then we'll clear the current se
lection | 4207 // If the snapshot should exclude selection, then we'll clear the current se
lection |
4195 // in the render tree only. This will allow us to restore the selection from
the DOM | 4208 // in the render tree only. This will allow us to restore the selection from
the DOM |
4196 // after we paint the snapshot. | 4209 // after we paint the snapshot. |
4197 if (shouldPaintSelection == ExcludeSelection) { | 4210 if (shouldPaintSelection == ExcludeSelection) { |
4198 for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseN
ext(m_frame.ptr())) { | 4211 for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseN
ext(m_frame.ptr())) { |
4199 if (auto* renderView = frame->contentRenderer()) | 4212 if (auto* renderView = frame->contentRenderer()) |
4200 renderView->selection().clear(); | 4213 renderView->selection().clear(); |
4201 } | 4214 } |
4202 } | 4215 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4299 return true; | 4312 return true; |
4300 } | 4313 } |
4301 return false; | 4314 return false; |
4302 }; | 4315 }; |
4303 #endif | 4316 #endif |
4304 | 4317 |
4305 ASSERT(!needsStyleRecalc()); | 4318 ASSERT(!needsStyleRecalc()); |
4306 ASSERT(!needsLayout()); | 4319 ASSERT(!needsLayout()); |
4307 } | 4320 } |
4308 | 4321 |
| 4322 static bool elementOverflowRectIsLargerThanThreshold(const Element& element) |
| 4323 { |
| 4324 // Require the document to grow a bit. |
| 4325 // Using a value of 48 allows the header on Google's search page to render i
mmediately before search results populate later. |
| 4326 static const int documentHeightThreshold = 48; |
| 4327 if (auto* elementRenderBox = element.renderBox()) |
| 4328 return snappedIntRect(elementRenderBox->layoutOverflowRect()).height() >
= documentHeightThreshold; |
| 4329 |
| 4330 return false; |
| 4331 } |
| 4332 |
4309 bool FrameView::qualifiesAsVisuallyNonEmpty() const | 4333 bool FrameView::qualifiesAsVisuallyNonEmpty() const |
4310 { | 4334 { |
4311 // No content yet. | 4335 // No content yet. |
4312 Element* documentElement = frame().document()->documentElement(); | 4336 Element* documentElement = frame().document()->documentElement(); |
4313 if (!documentElement || !documentElement->renderer()) | 4337 if (!documentElement || !documentElement->renderer()) |
4314 return false; | 4338 return false; |
4315 | 4339 |
4316 // Ensure that we always get marked visually non-empty eventually. | 4340 // Ensure that we always get marked visually non-empty eventually. |
4317 if (!frame().document()->parsing() && frame().loader().stateMachine().commit
tedFirstRealDocumentLoad()) | 4341 if (!frame().document()->parsing() && frame().loader().stateMachine().commit
tedFirstRealDocumentLoad()) |
4318 return true; | 4342 return true; |
4319 | 4343 |
4320 // FIXME: We should also ignore renderers with non-final style. | 4344 // FIXME: We should also ignore renderers with non-final style. |
4321 if (frame().document()->styleScope().hasPendingSheetsBeforeBody()) | 4345 if (frame().document()->styleScope().hasPendingSheetsBeforeBody()) |
4322 return false; | 4346 return false; |
4323 | 4347 |
4324 // Require the document to grow a bit. | 4348 if (!elementOverflowRectIsLargerThanThreshold(*documentElement)) |
4325 // Using a value of 48 allows the header on Google's search page to render i
mmediately before search results populate later. | |
4326 static const int documentHeightThreshold = 48; | |
4327 LayoutRect overflowRect = documentElement->renderBox()->layoutOverflowRect()
; | |
4328 if (snappedIntRect(overflowRect).height() < documentHeightThreshold) | |
4329 return false; | 4349 return false; |
4330 | 4350 |
4331 // The first few hundred characters rarely contain the interesting content o
f the page. | 4351 // The first few hundred characters rarely contain the interesting content o
f the page. |
4332 if (m_visuallyNonEmptyCharacterCount > visualCharacterThreshold) | 4352 if (m_visuallyNonEmptyCharacterCount > visualCharacterThreshold) |
4333 return true; | 4353 return true; |
4334 // Use a threshold value to prevent very small amounts of visible content fr
om triggering didFirstVisuallyNonEmptyLayout | 4354 // Use a threshold value to prevent very small amounts of visible content fr
om triggering didFirstVisuallyNonEmptyLayout |
4335 if (m_visuallyNonEmptyPixelCount > visualPixelThreshold) | 4355 if (m_visuallyNonEmptyPixelCount > visualPixelThreshold) |
4336 return true; | 4356 return true; |
4337 return false; | 4357 return false; |
| 4358 } |
| 4359 |
| 4360 void FrameView::updateSignificantRenderedTextMilestoneIfNeeded() |
| 4361 { |
| 4362 if (m_renderedSignificantAmountOfText) |
| 4363 return; |
| 4364 |
| 4365 auto* document = frame().document(); |
| 4366 if (!document || document->styleScope().hasPendingSheetsBeforeBody()) |
| 4367 return; |
| 4368 |
| 4369 auto* documentElement = document->documentElement(); |
| 4370 if (!documentElement || !elementOverflowRectIsLargerThanThreshold(*documentE
lement)) |
| 4371 return; |
| 4372 |
| 4373 auto characterThreshold = document->hasMainArticleElement() ? mainArticleSig
nificantRenderedTextCharacterThreshold : defaultSignificantRenderedTextCharacter
Threshold; |
| 4374 auto meanLength = document->hasMainArticleElement() ? mainArticleSignificant
RenderedTextMeanLength : defaultSignificantRenderedTextMeanLength; |
| 4375 |
| 4376 if (m_visuallyNonEmptyCharacterCount < characterThreshold) |
| 4377 return; |
| 4378 |
| 4379 if (!m_renderTextCountForVisuallyNonEmptyCharacters || m_visuallyNonEmptyCha
racterCount / static_cast<float>(m_renderTextCountForVisuallyNonEmptyCharacters)
< meanLength) |
| 4380 return; |
| 4381 |
| 4382 m_renderedSignificantAmountOfText = true; |
4338 } | 4383 } |
4339 | 4384 |
4340 void FrameView::updateIsVisuallyNonEmpty() | 4385 void FrameView::updateIsVisuallyNonEmpty() |
4341 { | 4386 { |
4342 if (m_isVisuallyNonEmpty) | 4387 if (m_isVisuallyNonEmpty) |
4343 return; | 4388 return; |
4344 if (!qualifiesAsVisuallyNonEmpty()) | 4389 if (!qualifiesAsVisuallyNonEmpty()) |
4345 return; | 4390 return; |
4346 m_isVisuallyNonEmpty = true; | 4391 m_isVisuallyNonEmpty = true; |
4347 adjustTiledBackingCoverage(); | 4392 adjustTiledBackingCoverage(); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4443 | 4488 |
4444 void FrameView::adjustPageHeightDeprecated(float *newBottom, float oldTop, float
oldBottom, float /*bottomLimit*/) | 4489 void FrameView::adjustPageHeightDeprecated(float *newBottom, float oldTop, float
oldBottom, float /*bottomLimit*/) |
4445 { | 4490 { |
4446 RenderView* renderView = this->renderView(); | 4491 RenderView* renderView = this->renderView(); |
4447 if (!renderView) { | 4492 if (!renderView) { |
4448 *newBottom = oldBottom; | 4493 *newBottom = oldBottom; |
4449 return; | 4494 return; |
4450 | 4495 |
4451 } | 4496 } |
4452 // Use a context with painting disabled. | 4497 // Use a context with painting disabled. |
4453 GraphicsContext context(GraphicsContext::NonPaintingReasons::NoReasons); | 4498 GraphicsContext context(GraphicsContext::PaintInvalidationReasons::None); |
4454 renderView->setTruncatedAt(static_cast<int>(floorf(oldBottom))); | 4499 renderView->setTruncatedAt(static_cast<int>(floorf(oldBottom))); |
4455 IntRect dirtyRect(0, static_cast<int>(floorf(oldTop)), renderView->layoutOve
rflowRect().maxX(), static_cast<int>(ceilf(oldBottom - oldTop))); | 4500 IntRect dirtyRect(0, static_cast<int>(floorf(oldTop)), renderView->layoutOve
rflowRect().maxX(), static_cast<int>(ceilf(oldBottom - oldTop))); |
4456 renderView->setPrintRect(dirtyRect); | 4501 renderView->setPrintRect(dirtyRect); |
4457 renderView->layer()->paint(context, dirtyRect); | 4502 renderView->layer()->paint(context, dirtyRect); |
4458 *newBottom = renderView->bestTruncatedAt(); | 4503 *newBottom = renderView->bestTruncatedAt(); |
4459 if (!*newBottom) | 4504 if (!*newBottom) |
4460 *newBottom = oldBottom; | 4505 *newBottom = oldBottom; |
4461 renderView->setPrintRect(IntRect()); | 4506 renderView->setPrintRect(IntRect()); |
4462 } | 4507 } |
4463 | 4508 |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4927 | 4972 |
4928 if (m_firstLayoutCallbackPending) { | 4973 if (m_firstLayoutCallbackPending) { |
4929 m_firstLayoutCallbackPending = false; | 4974 m_firstLayoutCallbackPending = false; |
4930 frame().loader().didFirstLayout(); | 4975 frame().loader().didFirstLayout(); |
4931 if (requestedMilestones & DidFirstLayout) | 4976 if (requestedMilestones & DidFirstLayout) |
4932 milestonesAchieved |= DidFirstLayout; | 4977 milestonesAchieved |= DidFirstLayout; |
4933 if (frame().isMainFrame()) | 4978 if (frame().isMainFrame()) |
4934 page->startCountingRelevantRepaintedObjects(); | 4979 page->startCountingRelevantRepaintedObjects(); |
4935 } | 4980 } |
4936 updateIsVisuallyNonEmpty(); | 4981 updateIsVisuallyNonEmpty(); |
| 4982 updateSignificantRenderedTextMilestoneIfNeeded(); |
4937 | 4983 |
4938 // If the layout was done with pending sheets, we are not in fact visually n
on-empty yet. | 4984 // If the layout was done with pending sheets, we are not in fact visually n
on-empty yet. |
4939 if (m_isVisuallyNonEmpty &&m_firstVisuallyNonEmptyLayoutCallbackPending) { | 4985 if (m_isVisuallyNonEmpty && m_firstVisuallyNonEmptyLayoutCallbackPending) { |
4940 m_firstVisuallyNonEmptyLayoutCallbackPending = false; | 4986 m_firstVisuallyNonEmptyLayoutCallbackPending = false; |
4941 if (requestedMilestones & DidFirstVisuallyNonEmptyLayout) | 4987 if (requestedMilestones & DidFirstVisuallyNonEmptyLayout) |
4942 milestonesAchieved |= DidFirstVisuallyNonEmptyLayout; | 4988 milestonesAchieved |= DidFirstVisuallyNonEmptyLayout; |
| 4989 } |
| 4990 |
| 4991 if (m_renderedSignificantAmountOfText && m_significantRenderedTextMilestoneP
ending) { |
| 4992 m_significantRenderedTextMilestonePending = false; |
| 4993 if (requestedMilestones & DidRenderSignificantAmountOfText) |
| 4994 milestonesAchieved |= DidRenderSignificantAmountOfText; |
4943 } | 4995 } |
4944 | 4996 |
4945 if (milestonesAchieved && frame().isMainFrame()) | 4997 if (milestonesAchieved && frame().isMainFrame()) |
4946 frame().loader().didReachLayoutMilestone(milestonesAchieved); | 4998 frame().loader().didReachLayoutMilestone(milestonesAchieved); |
4947 } | 4999 } |
4948 | 5000 |
4949 void FrameView::firePaintRelatedMilestonesIfNeeded() | 5001 void FrameView::firePaintRelatedMilestonesIfNeeded() |
4950 { | 5002 { |
4951 Page* page = frame().page(); | 5003 Page* page = frame().page(); |
4952 if (!page) | 5004 if (!page) |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5140 viewportSize.height = viewportSize.height.value_or(visibleContentSizeIncludi
ngScrollbars.height()); | 5192 viewportSize.height = viewportSize.height.value_or(visibleContentSizeIncludi
ngScrollbars.height()); |
5141 return { *viewportSize.width, *viewportSize.height }; | 5193 return { *viewportSize.width, *viewportSize.height }; |
5142 } | 5194 } |
5143 | 5195 |
5144 bool FrameView::shouldPlaceBlockDirectionScrollbarOnLeft() const | 5196 bool FrameView::shouldPlaceBlockDirectionScrollbarOnLeft() const |
5145 { | 5197 { |
5146 return renderView() && renderView()->shouldPlaceBlockDirectionScrollbarOnLef
t(); | 5198 return renderView() && renderView()->shouldPlaceBlockDirectionScrollbarOnLef
t(); |
5147 } | 5199 } |
5148 ···· | 5200 ···· |
5149 } // namespace WebCore | 5201 } // namespace WebCore |
LEFT | RIGHT |