OLD | NEW |
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, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 , m_isTrackingRepaints(false) | 173 , m_isTrackingRepaints(false) |
174 , m_shouldUpdateWhileOffscreen(true) | 174 , m_shouldUpdateWhileOffscreen(true) |
175 , m_deferSetNeedsLayouts(0) | 175 , m_deferSetNeedsLayouts(0) |
176 , m_setNeedsLayoutWasDeferred(false) | 176 , m_setNeedsLayoutWasDeferred(false) |
177 , m_scrollCorner(0) | 177 , m_scrollCorner(0) |
178 , m_shouldAutoSize(false) | 178 , m_shouldAutoSize(false) |
179 , m_inAutoSize(false) | 179 , m_inAutoSize(false) |
180 , m_didRunAutosize(false) | 180 , m_didRunAutosize(false) |
181 , m_hasSoftwareFilters(false) | 181 , m_hasSoftwareFilters(false) |
182 , m_visibleContentScaleFactor(1) | 182 , m_visibleContentScaleFactor(1) |
| 183 , m_partialLayout() |
183 { | 184 { |
184 ASSERT(m_frame); | 185 ASSERT(m_frame); |
185 init(); | 186 init(); |
186 | 187 |
187 Page* page = m_frame->page(); | 188 Page* page = m_frame->page(); |
188 if (!page) | 189 if (!page) |
189 return; | 190 return; |
190 | 191 |
191 if (m_frame == page->mainFrame()) { | 192 if (m_frame == page->mainFrame()) { |
192 ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed); | 193 ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 m_trackedRepaintRects.clear(); | 271 m_trackedRepaintRects.clear(); |
271 m_lastPaintTime = 0; | 272 m_lastPaintTime = 0; |
272 m_paintBehavior = PaintBehaviorNormal; | 273 m_paintBehavior = PaintBehaviorNormal; |
273 m_isPainting = false; | 274 m_isPainting = false; |
274 m_visuallyNonEmptyCharacterCount = 0; | 275 m_visuallyNonEmptyCharacterCount = 0; |
275 m_visuallyNonEmptyPixelCount = 0; | 276 m_visuallyNonEmptyPixelCount = 0; |
276 m_isVisuallyNonEmpty = false; | 277 m_isVisuallyNonEmpty = false; |
277 m_firstVisuallyNonEmptyLayoutCallbackPending = true; | 278 m_firstVisuallyNonEmptyLayoutCallbackPending = true; |
278 m_maintainScrollPositionAnchor = 0; | 279 m_maintainScrollPositionAnchor = 0; |
279 m_disableRepaints = 0; | 280 m_disableRepaints = 0; |
| 281 m_partialLayout.reset(); |
280 } | 282 } |
281 | 283 |
282 void FrameView::removeFromAXObjectCache() | 284 void FrameView::removeFromAXObjectCache() |
283 { | 285 { |
284 if (AXObjectCache* cache = axObjectCache()) | 286 if (AXObjectCache* cache = axObjectCache()) |
285 cache->remove(this); | 287 cache->remove(this); |
286 } | 288 } |
287 | 289 |
288 void FrameView::resetScrollbars() | 290 void FrameView::resetScrollbars() |
289 { | 291 { |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 // the layout beats any sort of style recalc update that needs to occur. | 860 // the layout beats any sort of style recalc update that needs to occur. |
859 TemporaryChange<bool> changeDoingPreLayoutStyleUpdate(m_doingPreLayoutStyleU
pdate, true); | 861 TemporaryChange<bool> changeDoingPreLayoutStyleUpdate(m_doingPreLayoutStyleU
pdate, true); |
860 document->updateStyleIfNeeded(); | 862 document->updateStyleIfNeeded(); |
861 } | 863 } |
862 | 864 |
863 void FrameView::performLayout(RenderObject* rootForThisLayout, bool inSubtreeLay
out) | 865 void FrameView::performLayout(RenderObject* rootForThisLayout, bool inSubtreeLay
out) |
864 { | 866 { |
865 // performLayout is the actual guts of layout(). | 867 // performLayout is the actual guts of layout(). |
866 // FIXME: The 300 other lines in layout() probably belong in other helper fu
nctions | 868 // FIXME: The 300 other lines in layout() probably belong in other helper fu
nctions |
867 // so that a single human could understand what layout() is actually doing. | 869 // so that a single human could understand what layout() is actually doing. |
| 870 { |
| 871 bool disableLayoutState = false; |
| 872 if (inSubtreeLayout) { |
| 873 RenderView* view = rootForThisLayout->view(); |
| 874 disableLayoutState = view->shouldDisableLayoutStateForSubtree(rootFo
rThisLayout); |
| 875 view->pushLayoutState(rootForThisLayout); |
| 876 } |
| 877 LayoutStateDisabler layoutStateDisabler(disableLayoutState ? rootForThis
Layout->view() : 0); |
868 | 878 |
869 bool disableLayoutState = false; | 879 m_inLayout = true; |
870 if (inSubtreeLayout) { | 880 beginDeferredRepaints(); |
871 RenderView* view = rootForThisLayout->view(); | 881 forceLayoutParentViewIfNeeded(); |
872 disableLayoutState = view->shouldDisableLayoutStateForSubtree(rootForThi
sLayout); | 882 |
873 view->pushLayoutState(rootForThisLayout); | 883 // Text Autosizing requires two-pass layout which is incompatible with p
artial layout. |
| 884 // If enabled, only do partial layout for the second layout. |
| 885 // FIXME (crbug.com/256657): Do not do two layouts for text autosizing. |
| 886 PartialLayoutDisabler partialLayoutDisabler(partialLayout(), m_frame->se
ttings() && m_frame->settings()->textAutosizingEnabled()); |
| 887 rootForThisLayout->layout(); // THIS IS WHERE LAYOUT ACTUALLY HAPPENS. |
874 } | 888 } |
875 LayoutStateDisabler layoutStateDisabler(disableLayoutState ? rootForThisLayo
ut->view() : 0); | |
876 | |
877 m_inLayout = true; | |
878 beginDeferredRepaints(); | |
879 forceLayoutParentViewIfNeeded(); | |
880 | |
881 rootForThisLayout->layout(); // THIS IS WHERE LAYOUT ACTUALLY HAPPENS. | |
882 | 889 |
883 bool autosized = frame().document()->textAutosizer()->processSubtree(rootFor
ThisLayout); | 890 bool autosized = frame().document()->textAutosizer()->processSubtree(rootFor
ThisLayout); |
884 if (autosized && rootForThisLayout->needsLayout()) { | 891 if (autosized && rootForThisLayout->needsLayout()) { |
885 TRACE_EVENT0("webkit", "2nd layout due to Text Autosizing"); | 892 TRACE_EVENT0("webkit", "2nd layout due to Text Autosizing"); |
886 rootForThisLayout->layout(); | 893 rootForThisLayout->layout(); |
887 } | 894 } |
888 | 895 |
889 endDeferredRepaints(); | 896 endDeferredRepaints(); |
890 m_inLayout = false; | 897 m_inLayout = false; |
891 | 898 |
892 if (inSubtreeLayout) | 899 if (inSubtreeLayout) |
893 rootForThisLayout->view()->popLayoutState(rootForThisLayout); | 900 rootForThisLayout->view()->popLayoutState(rootForThisLayout); |
894 } | 901 } |
895 | 902 |
896 void FrameView::scheduleOrPerformPostLayoutTasks() | 903 void FrameView::scheduleOrPerformPostLayoutTasks() |
897 { | 904 { |
898 if (m_postLayoutTasksTimer.isActive()) { | 905 if (m_postLayoutTasksTimer.isActive()) { |
899 m_actionScheduler->resume(); | 906 m_actionScheduler->resume(); |
900 return; | 907 return; |
901 } | 908 } |
902 | 909 |
| 910 // Partial layouts should not happen with synchronous post layouts. |
| 911 ASSERT(!(m_inSynchronousPostLayout && partialLayout().isStopping())); |
| 912 |
903 if (!m_inSynchronousPostLayout) { | 913 if (!m_inSynchronousPostLayout) { |
904 if (frame().document()->shouldDisplaySeamlesslyWithParent()) { | 914 if (frame().document()->shouldDisplaySeamlesslyWithParent()) { |
905 if (RenderView* renderView = this->renderView()) | 915 if (RenderView* renderView = this->renderView()) |
906 renderView->updateWidgetPositions(); | 916 renderView->updateWidgetPositions(); |
907 } else { | 917 } else { |
908 m_inSynchronousPostLayout = true; | 918 m_inSynchronousPostLayout = true; |
909 // Calls resumeScheduledEvents() | 919 // Calls resumeScheduledEvents() |
910 performPostLayoutTasks(); | 920 performPostLayoutTasks(); |
911 m_inSynchronousPostLayout = false; | 921 m_inSynchronousPostLayout = false; |
912 } | 922 } |
913 } | 923 } |
914 | 924 |
915 if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousP
ostLayout || frame().document()->shouldDisplaySeamlesslyWithParent())) { | 925 if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousP
ostLayout || frame().document()->shouldDisplaySeamlesslyWithParent())) { |
916 // If we need layout or are already in a synchronous call to postLayoutT
asks(), | 926 // If we need layout or are already in a synchronous call to postLayoutT
asks(), |
917 // defer widget updates and event dispatch until after we return. postLa
youtTasks() | 927 // defer widget updates and event dispatch until after we return. postLa
youtTasks() |
918 // can make us need to update again, and we can get stuck in a nasty cyc
le unless | 928 // can make us need to update again, and we can get stuck in a nasty cyc
le unless |
919 // we call it through the timer here. | 929 // we call it through the timer here. |
920 m_postLayoutTasksTimer.startOneShot(0); | 930 m_postLayoutTasksTimer.startOneShot(0); |
921 if (needsLayout()) { | 931 if (!partialLayout().isStopping() && needsLayout()) { |
922 m_actionScheduler->pause(); | 932 m_actionScheduler->pause(); |
923 layout(); | 933 layout(); |
924 } | 934 } |
925 } | 935 } |
926 } | 936 } |
927 | 937 |
928 void FrameView::layout(bool allowSubtree) | 938 void FrameView::layout(bool allowSubtree) |
929 { | 939 { |
930 // We should never layout a Document which is not in a Frame. | 940 // We should never layout a Document which is not in a Frame. |
931 ASSERT(m_frame); | 941 ASSERT(m_frame); |
932 ASSERT(m_frame->view() == this); | 942 ASSERT(m_frame->view() == this); |
933 ASSERT(m_frame->page()); | 943 ASSERT(m_frame->page()); |
934 | 944 |
935 if (m_inLayout) | 945 if (m_inLayout) |
936 return; | 946 return; |
937 | 947 |
| 948 ASSERT(!partialLayout().isStopping()); |
| 949 |
938 TRACE_EVENT0("webkit", "FrameView::layout"); | 950 TRACE_EVENT0("webkit", "FrameView::layout"); |
939 TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "Layout"); | 951 TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "Layout"); |
940 | 952 |
941 // Protect the view from being deleted during layout (in recalcStyle) | 953 // Protect the view from being deleted during layout (in recalcStyle) |
942 RefPtr<FrameView> protector(this); | 954 RefPtr<FrameView> protector(this); |
943 | 955 |
944 // Every scroll that happens during layout is programmatic. | 956 // Every scroll that happens during layout is programmatic. |
945 TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, tru
e); | 957 TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, tru
e); |
946 | 958 |
947 m_layoutTimer.stop(); | 959 m_layoutTimer.stop(); |
(...skipping 21 matching lines...) Expand all Loading... |
969 | 981 |
970 Document* document = m_frame->document(); | 982 Document* document = m_frame->document(); |
971 bool inSubtreeLayout = m_layoutRoot; | 983 bool inSubtreeLayout = m_layoutRoot; |
972 RenderObject* rootForThisLayout = inSubtreeLayout ? m_layoutRoot : document-
>renderer(); | 984 RenderObject* rootForThisLayout = inSubtreeLayout ? m_layoutRoot : document-
>renderer(); |
973 if (!rootForThisLayout) { | 985 if (!rootForThisLayout) { |
974 // FIXME: Do we need to set m_size here? | 986 // FIXME: Do we need to set m_size here? |
975 ASSERT_NOT_REACHED(); | 987 ASSERT_NOT_REACHED(); |
976 return; | 988 return; |
977 } | 989 } |
978 | 990 |
| 991 bool isPartialLayout = partialLayout().isPartialLayout(); |
| 992 |
979 FontCachePurgePreventer fontCachePurgePreventer; | 993 FontCachePurgePreventer fontCachePurgePreventer; |
980 RenderLayer* layer; | 994 RenderLayer* layer; |
981 { | 995 { |
982 TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled,
false); | 996 TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled,
false); |
983 | 997 |
984 m_nestedLayoutCount++; | 998 m_nestedLayoutCount++; |
985 | 999 |
986 updateCounters(); | 1000 updateCounters(); |
987 autoSizeIfEnabled(); | 1001 autoSizeIfEnabled(); |
988 | 1002 |
989 ScrollbarMode hMode; | 1003 ScrollbarMode hMode; |
990 ScrollbarMode vMode; | 1004 ScrollbarMode vMode; |
991 calculateScrollbarModesForLayout(hMode, vMode); | 1005 calculateScrollbarModesForLayout(hMode, vMode); |
992 | 1006 |
993 m_doFullRepaint = !inSubtreeLayout && (m_firstLayout || toRenderView(roo
tForThisLayout)->printing()); | 1007 m_doFullRepaint = !inSubtreeLayout && !isPartialLayout && (m_firstLayout
|| toRenderView(rootForThisLayout)->printing()); |
994 | 1008 |
995 if (!inSubtreeLayout) { | 1009 if (!inSubtreeLayout && !isPartialLayout) { |
996 // Now set our scrollbar state for the layout. | 1010 // Now set our scrollbar state for the layout. |
997 ScrollbarMode currentHMode = horizontalScrollbarMode(); | 1011 ScrollbarMode currentHMode = horizontalScrollbarMode(); |
998 ScrollbarMode currentVMode = verticalScrollbarMode(); | 1012 ScrollbarMode currentVMode = verticalScrollbarMode(); |
999 | 1013 |
1000 if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode
)) { | 1014 if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode
)) { |
1001 if (m_firstLayout) { | 1015 if (m_firstLayout) { |
1002 setScrollbarsSuppressed(true); | 1016 setScrollbarsSuppressed(true); |
1003 | 1017 |
1004 m_firstLayout = false; | 1018 m_firstLayout = false; |
1005 m_firstLayoutCallbackPending = true; | 1019 m_firstLayoutCallbackPending = true; |
(...skipping 26 matching lines...) Expand all Loading... |
1032 bodyRenderer->setChildNeedsLayout(); | 1046 bodyRenderer->setChildNeedsLayout(); |
1033 else if (rootRenderer && rootRenderer->stretchesToViewport()
) | 1047 else if (rootRenderer && rootRenderer->stretchesToViewport()
) |
1034 rootRenderer->setChildNeedsLayout(); | 1048 rootRenderer->setChildNeedsLayout(); |
1035 } | 1049 } |
1036 } | 1050 } |
1037 } | 1051 } |
1038 | 1052 |
1039 layer = rootForThisLayout->enclosingLayer(); | 1053 layer = rootForThisLayout->enclosingLayer(); |
1040 | 1054 |
1041 m_actionScheduler->pause(); | 1055 m_actionScheduler->pause(); |
| 1056 |
1042 performLayout(rootForThisLayout, inSubtreeLayout); | 1057 performLayout(rootForThisLayout, inSubtreeLayout); |
1043 m_layoutRoot = 0; | 1058 m_layoutRoot = 0; |
1044 } // Reset m_layoutSchedulingEnabled to its previous value. | 1059 } // Reset m_layoutSchedulingEnabled to its previous value. |
1045 | 1060 |
1046 bool neededFullRepaint = m_doFullRepaint; | 1061 bool neededFullRepaint = m_doFullRepaint; |
1047 | 1062 |
1048 if (!inSubtreeLayout && !toRenderView(rootForThisLayout)->printing()) | 1063 if (!inSubtreeLayout && !isPartialLayout && !toRenderView(rootForThisLayout)
->printing()) |
1049 adjustViewSize(); | 1064 adjustViewSize(); |
1050 | 1065 |
1051 m_doFullRepaint = neededFullRepaint; | 1066 m_doFullRepaint = neededFullRepaint; |
1052 | 1067 |
1053 // Now update the positions of all layers. | 1068 // Now update the positions of all layers. |
1054 beginDeferredRepaints(); | 1069 beginDeferredRepaints(); |
1055 if (m_doFullRepaint) { | 1070 if (m_doFullRepaint) { |
1056 // FIXME: This isn't really right, since the RenderView doesn't fully en
compass | 1071 // FIXME: This isn't really right, since the RenderView doesn't fully en
compass |
1057 // the visibleContentRect(). It just happens to work out most of the tim
e, | 1072 // the visibleContentRect(). It just happens to work out most of the tim
e, |
1058 // since first layouts and printing don't have you scrolled anywhere. | 1073 // since first layouts and printing don't have you scrolled anywhere. |
1059 rootForThisLayout->view()->repaint(); | 1074 rootForThisLayout->view()->repaint(); |
1060 } | 1075 } |
1061 | 1076 |
1062 layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPos
itionFlags(layer, inSubtreeLayout, m_doFullRepaint)); | 1077 layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPos
itionFlags(layer, inSubtreeLayout, m_doFullRepaint)); |
1063 | 1078 |
1064 endDeferredRepaints(); | 1079 endDeferredRepaints(); |
1065 | 1080 |
1066 updateCompositingLayersAfterLayout(); | 1081 updateCompositingLayersAfterLayout(); |
1067 | 1082 |
1068 m_layoutCount++; | 1083 m_layoutCount++; |
1069 | 1084 |
1070 if (AXObjectCache* cache = rootForThisLayout->document().existingAXObjectCac
he()) | 1085 if (AXObjectCache* cache = rootForThisLayout->document().existingAXObjectCac
he()) |
1071 cache->postNotification(rootForThisLayout, AXObjectCache::AXLayoutComple
te, true); | 1086 cache->postNotification(rootForThisLayout, AXObjectCache::AXLayoutComple
te, true); |
1072 updateAnnotatedRegions(); | 1087 updateAnnotatedRegions(); |
1073 | 1088 |
1074 ASSERT(!rootForThisLayout->needsLayout()); | 1089 ASSERT(partialLayout().isStopping() || !rootForThisLayout->needsLayout()); |
1075 | 1090 |
1076 updateCanBlitOnScrollRecursively(); | 1091 updateCanBlitOnScrollRecursively(); |
1077 | 1092 |
1078 if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER)) | 1093 if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER)) |
1079 updateOverflowStatus(layoutWidth() < contentsWidth(), layoutHeight() < c
ontentsHeight()); | 1094 updateOverflowStatus(layoutWidth() < contentsWidth(), layoutHeight() < c
ontentsHeight()); |
1080 | 1095 |
1081 // Resume scheduled events (FrameActionScheduler m_actionScheduler) | 1096 // Resume scheduled events (FrameActionScheduler m_actionScheduler) |
1082 // and ensure post layout tasks are executed or scheduled to be. | 1097 // and ensure post layout tasks are executed or scheduled to be. |
1083 scheduleOrPerformPostLayoutTasks(); | 1098 scheduleOrPerformPostLayoutTasks(); |
1084 | 1099 |
1085 InspectorInstrumentation::didLayout(cookie, rootForThisLayout); | 1100 InspectorInstrumentation::didLayout(cookie, rootForThisLayout); |
1086 | 1101 |
1087 m_nestedLayoutCount--; | 1102 m_nestedLayoutCount--; |
1088 if (m_nestedLayoutCount) | 1103 if (m_nestedLayoutCount) |
1089 return; | 1104 return; |
1090 | 1105 |
| 1106 if (partialLayout().isStopping()) |
| 1107 return; |
| 1108 |
1091 #ifndef NDEBUG | 1109 #ifndef NDEBUG |
1092 // Post-layout assert that nobody was re-marked as needing layout during lay
out. | 1110 // Post-layout assert that nobody was re-marked as needing layout during lay
out. |
1093 for (RenderObject* renderer = document->renderer(); renderer; renderer = ren
derer->nextInPreOrder()) | 1111 for (RenderObject* renderer = document->renderer(); renderer; renderer = ren
derer->nextInPreOrder()) |
1094 ASSERT_WITH_SECURITY_IMPLICATION(!renderer->needsLayout()); | 1112 ASSERT_WITH_SECURITY_IMPLICATION(!renderer->needsLayout()); |
1095 #endif | 1113 #endif |
1096 | 1114 |
1097 // FIXME: It should be not possible to remove the FrameView from the frame/p
age during layout | 1115 // FIXME: It should be not possible to remove the FrameView from the frame/p
age during layout |
1098 // however m_inLayout is not set for most of this function, so none of our R
ELEASE_ASSERTS | 1116 // however m_inLayout is not set for most of this function, so none of our R
ELEASE_ASSERTS |
1099 // in Frame/Page will fire. One of the post-layout tasks is disconnecting th
e Frame from | 1117 // in Frame/Page will fire. One of the post-layout tasks is disconnecting th
e Frame from |
1100 // the page in fast/frames/crash-remove-iframe-during-object-beforeload-2.ht
ml | 1118 // the page in fast/frames/crash-remove-iframe-during-object-beforeload-2.ht
ml |
(...skipping 2253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3354 } | 3372 } |
3355 | 3373 |
3356 AXObjectCache* FrameView::axObjectCache() const | 3374 AXObjectCache* FrameView::axObjectCache() const |
3357 { | 3375 { |
3358 if (frame().document()) | 3376 if (frame().document()) |
3359 return frame().document()->existingAXObjectCache(); | 3377 return frame().document()->existingAXObjectCache(); |
3360 return 0; | 3378 return 0; |
3361 } | 3379 } |
3362 | 3380 |
3363 } // namespace WebCore | 3381 } // namespace WebCore |
OLD | NEW |