Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights |
| 3 * reserved. | 3 * reserved. |
| 4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 5 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 5 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
| 6 * (http://www.torchmobile.com/) | 6 * (http://www.torchmobile.com/) |
| 7 * Copyright (C) 2008 Alp Toker <alp@atoker.com> | 7 * Copyright (C) 2008 Alp Toker <alp@atoker.com> |
| 8 * Copyright (C) Research In Motion Limited 2009. All rights reserved. | 8 * Copyright (C) Research In Motion Limited 2009. All rights reserved. |
| 9 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> | 9 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> |
| 10 * Copyright (C) 2011 Google Inc. All rights reserved. | 10 * Copyright (C) 2011 Google Inc. All rights reserved. |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 553 if (history_item) | 553 if (history_item) |
| 554 document_loader_->SetItemForHistoryNavigation(history_item); | 554 document_loader_->SetItemForHistoryNavigation(history_item); |
| 555 UpdateForSameDocumentNavigation(url, kSameDocumentNavigationDefault, nullptr, | 555 UpdateForSameDocumentNavigation(url, kSameDocumentNavigationDefault, nullptr, |
| 556 kScrollRestorationAuto, frame_load_type, | 556 kScrollRestorationAuto, frame_load_type, |
| 557 initiating_document); | 557 initiating_document); |
| 558 | 558 |
| 559 document_loader_->GetInitialScrollState().was_scrolled_by_user = false; | 559 document_loader_->GetInitialScrollState().was_scrolled_by_user = false; |
| 560 | 560 |
| 561 frame_->GetDocument()->CheckCompleted(); | 561 frame_->GetDocument()->CheckCompleted(); |
| 562 | 562 |
| 563 // onpopstate might change view state, so stash for later restore. | |
| 564 HistoryItem::ScrollAndViewState* scroll_and_view_state = | |
| 565 history_item ? history_item->CopyScrollAndViewState() : nullptr; | |
| 566 | |
|
majidvp
2017/06/26 16:19:26
This may be something that can be captured by a st
Nate Chapin
2017/07/11 22:17:59
I *hope* this will stay a one-off, so I'm disincli
| |
| 563 frame_->DomWindow()->StatePopped(state_object | 567 frame_->DomWindow()->StatePopped(state_object |
| 564 ? std::move(state_object) | 568 ? std::move(state_object) |
| 565 : SerializedScriptValue::NullValue()); | 569 : SerializedScriptValue::NullValue()); |
| 566 | 570 |
| 567 if (history_item) | 571 if (history_item) { |
| 568 RestoreScrollPositionAndViewStateForLoadType(frame_load_type); | 572 RestoreScrollPositionAndViewStateForLoadType( |
| 573 frame_load_type, scroll_and_view_state, | |
| 574 history_item->ScrollRestorationType()); | |
| 575 } | |
| 569 | 576 |
| 570 // We need to scroll to the fragment whether or not a hash change occurred, | 577 // We need to scroll to the fragment whether or not a hash change occurred, |
| 571 // since the user might have scrolled since the previous navigation. | 578 // since the user might have scrolled since the previous navigation. |
| 572 ProcessFragment(url, frame_load_type, kNavigationWithinSameDocument); | 579 ProcessFragment(url, frame_load_type, kNavigationWithinSameDocument); |
| 573 | 580 |
| 574 TakeObjectSnapshot(); | 581 TakeObjectSnapshot(); |
| 575 } | 582 } |
| 576 | 583 |
| 577 // static | 584 // static |
| 578 void FrameLoader::SetReferrerForFrameRequest(FrameLoadRequest& frame_request) { | 585 void FrameLoader::SetReferrerForFrameRequest(FrameLoadRequest& frame_request) { |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1053 Client()->TransitionToCommittedForNewPage(); | 1060 Client()->TransitionToCommittedForNewPage(); |
| 1054 | 1061 |
| 1055 frame_->GetNavigationScheduler().Cancel(); | 1062 frame_->GetNavigationScheduler().Cancel(); |
| 1056 } | 1063 } |
| 1057 | 1064 |
| 1058 bool FrameLoader::IsLoadingMainFrame() const { | 1065 bool FrameLoader::IsLoadingMainFrame() const { |
| 1059 return frame_->IsMainFrame(); | 1066 return frame_->IsMainFrame(); |
| 1060 } | 1067 } |
| 1061 | 1068 |
| 1062 void FrameLoader::RestoreScrollPositionAndViewState() { | 1069 void FrameLoader::RestoreScrollPositionAndViewState() { |
| 1063 if (!frame_->GetPage() || !GetDocumentLoader()) | 1070 if (!frame_->GetPage() || !GetDocumentLoader() || |
| 1071 !GetDocumentLoader()->GetHistoryItem()) | |
| 1064 return; | 1072 return; |
| 1065 RestoreScrollPositionAndViewStateForLoadType(GetDocumentLoader()->LoadType()); | 1073 RestoreScrollPositionAndViewStateForLoadType( |
| 1074 GetDocumentLoader()->LoadType(), | |
| 1075 GetDocumentLoader()->GetHistoryItem()->GetScrollAndViewState(), | |
| 1076 GetDocumentLoader()->GetHistoryItem()->ScrollRestorationType()); | |
| 1066 } | 1077 } |
| 1067 | 1078 |
| 1068 void FrameLoader::RestoreScrollPositionAndViewStateForLoadType( | 1079 void FrameLoader::RestoreScrollPositionAndViewStateForLoadType( |
| 1069 FrameLoadType load_type) { | 1080 FrameLoadType load_type, |
| 1081 HistoryItem::ScrollAndViewState* scroll_and_view_state, | |
| 1082 HistoryScrollRestorationType scroll_restoration_type) { | |
| 1070 LocalFrameView* view = frame_->View(); | 1083 LocalFrameView* view = frame_->View(); |
| 1071 if (!view || !view->LayoutViewportScrollableArea() || | 1084 if (!view || !view->LayoutViewportScrollableArea() || |
| 1072 !state_machine_.CommittedFirstRealDocumentLoad() || | 1085 !state_machine_.CommittedFirstRealDocumentLoad() || |
| 1073 !frame_->IsAttached()) { | 1086 !frame_->IsAttached()) { |
| 1074 return; | 1087 return; |
| 1075 } | 1088 } |
| 1076 if (!NeedsHistoryItemRestore(load_type)) | 1089 if (!NeedsHistoryItemRestore(load_type) || !scroll_and_view_state) |
| 1077 return; | |
| 1078 HistoryItem* history_item = document_loader_->GetHistoryItem(); | |
| 1079 if (!history_item || !history_item->DidSaveScrollOrScaleState()) | |
| 1080 return; | 1090 return; |
| 1081 | 1091 |
| 1082 bool should_restore_scroll = | 1092 bool should_restore_scroll = |
| 1083 history_item->ScrollRestorationType() != kScrollRestorationManual; | 1093 scroll_restoration_type != kScrollRestorationManual; |
| 1084 bool should_restore_scale = history_item->PageScaleFactor(); | 1094 bool should_restore_scale = scroll_and_view_state->page_scale_factor_; |
| 1085 | 1095 |
| 1086 // This tries to balance: | 1096 // This tries to balance: |
| 1087 // 1. restoring as soon as possible | 1097 // 1. restoring as soon as possible |
| 1088 // 2. not overriding user scroll (TODO(majidvp): also respect user scale) | 1098 // 2. not overriding user scroll (TODO(majidvp): also respect user scale) |
| 1089 // 3. detecting clamping to avoid repeatedly popping the scroll position down | 1099 // 3. detecting clamping to avoid repeatedly popping the scroll position down |
| 1090 // as the page height increases | 1100 // as the page height increases |
| 1091 // 4. ignore clamp detection if we are not restoring scroll or after load | 1101 // 4. ignore clamp detection if we are not restoring scroll or after load |
| 1092 // completes because that may be because the page will never reach its | 1102 // completes because that may be because the page will never reach its |
| 1093 // previous height | 1103 // previous height |
| 1094 bool can_restore_without_clamping = | 1104 bool can_restore_without_clamping = |
| 1095 view->LayoutViewportScrollableArea()->ClampScrollOffset( | 1105 view->LayoutViewportScrollableArea()->ClampScrollOffset( |
| 1096 history_item->GetScrollOffset()) == history_item->GetScrollOffset(); | 1106 scroll_and_view_state->scroll_offset_) == |
| 1107 scroll_and_view_state->scroll_offset_; | |
| 1097 bool can_restore_without_annoying_user = | 1108 bool can_restore_without_annoying_user = |
| 1098 !GetDocumentLoader()->GetInitialScrollState().was_scrolled_by_user && | 1109 !GetDocumentLoader()->GetInitialScrollState().was_scrolled_by_user && |
| 1099 (can_restore_without_clamping || !frame_->IsLoading() || | 1110 (can_restore_without_clamping || !frame_->IsLoading() || |
| 1100 !should_restore_scroll); | 1111 !should_restore_scroll); |
| 1101 if (!can_restore_without_annoying_user) | 1112 if (!can_restore_without_annoying_user) |
| 1102 return; | 1113 return; |
| 1103 | 1114 |
| 1104 if (should_restore_scroll) { | 1115 if (should_restore_scroll) { |
| 1105 view->LayoutViewportScrollableArea()->SetScrollOffset( | 1116 view->LayoutViewportScrollableArea()->SetScrollOffset( |
| 1106 history_item->GetScrollOffset(), kProgrammaticScroll); | 1117 scroll_and_view_state->scroll_offset_, kProgrammaticScroll); |
| 1107 } | 1118 } |
| 1108 | 1119 |
| 1109 // For main frame restore scale and visual viewport position | 1120 // For main frame restore scale and visual viewport position |
| 1110 if (frame_->IsMainFrame()) { | 1121 if (frame_->IsMainFrame()) { |
| 1111 ScrollOffset visual_viewport_offset( | 1122 ScrollOffset visual_viewport_offset( |
| 1112 history_item->VisualViewportScrollOffset()); | 1123 scroll_and_view_state->visual_viewport_scroll_offset_); |
| 1113 | 1124 |
| 1114 // If the visual viewport's offset is (-1, -1) it means the history item | 1125 // If the visual viewport's offset is (-1, -1) it means the history item |
| 1115 // is an old version of HistoryItem so distribute the scroll between | 1126 // is an old version of HistoryItem so distribute the scroll between |
| 1116 // the main frame and the visual viewport as best as we can. | 1127 // the main frame and the visual viewport as best as we can. |
| 1117 if (visual_viewport_offset.Width() == -1 && | 1128 if (visual_viewport_offset.Width() == -1 && |
| 1118 visual_viewport_offset.Height() == -1) { | 1129 visual_viewport_offset.Height() == -1) { |
| 1119 visual_viewport_offset = | 1130 visual_viewport_offset = |
| 1120 history_item->GetScrollOffset() - | 1131 scroll_and_view_state->scroll_offset_ - |
| 1121 view->LayoutViewportScrollableArea()->GetScrollOffset(); | 1132 view->LayoutViewportScrollableArea()->GetScrollOffset(); |
| 1122 } | 1133 } |
| 1123 | 1134 |
| 1124 VisualViewport& visual_viewport = frame_->GetPage()->GetVisualViewport(); | 1135 VisualViewport& visual_viewport = frame_->GetPage()->GetVisualViewport(); |
| 1125 if (should_restore_scale && should_restore_scroll) { | 1136 if (should_restore_scale && should_restore_scroll) { |
| 1126 visual_viewport.SetScaleAndLocation(history_item->PageScaleFactor(), | 1137 visual_viewport.SetScaleAndLocation( |
| 1127 FloatPoint(visual_viewport_offset)); | 1138 scroll_and_view_state->page_scale_factor_, |
| 1139 FloatPoint(visual_viewport_offset)); | |
| 1128 } else if (should_restore_scale) { | 1140 } else if (should_restore_scale) { |
| 1129 visual_viewport.SetScale(history_item->PageScaleFactor()); | 1141 visual_viewport.SetScale(scroll_and_view_state->page_scale_factor_); |
| 1130 } else if (should_restore_scroll) { | 1142 } else if (should_restore_scroll) { |
| 1131 visual_viewport.SetLocation(FloatPoint(visual_viewport_offset)); | 1143 visual_viewport.SetLocation(FloatPoint(visual_viewport_offset)); |
| 1132 } | 1144 } |
| 1133 | 1145 |
| 1134 if (ScrollingCoordinator* scrolling_coordinator = | 1146 if (ScrollingCoordinator* scrolling_coordinator = |
| 1135 frame_->GetPage()->GetScrollingCoordinator()) | 1147 frame_->GetPage()->GetScrollingCoordinator()) |
| 1136 scrolling_coordinator->FrameViewRootLayerDidChange(view); | 1148 scrolling_coordinator->FrameViewRootLayerDidChange(view); |
| 1137 } | 1149 } |
| 1138 | 1150 |
| 1139 GetDocumentLoader()->GetInitialScrollState().did_restore_from_history = true; | 1151 GetDocumentLoader()->GetInitialScrollState().did_restore_from_history = true; |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1698 // TODO(japhet): This is needed because the browser process DCHECKs if the | 1710 // TODO(japhet): This is needed because the browser process DCHECKs if the |
| 1699 // first entry we commit in a new frame has replacement set. It's unclear | 1711 // first entry we commit in a new frame has replacement set. It's unclear |
| 1700 // whether the DCHECK is right, investigate removing this special case. | 1712 // whether the DCHECK is right, investigate removing this special case. |
| 1701 bool replace_current_item = load_type == kFrameLoadTypeReplaceCurrentItem && | 1713 bool replace_current_item = load_type == kFrameLoadTypeReplaceCurrentItem && |
| 1702 (!Opener() || !request.Url().IsEmpty()); | 1714 (!Opener() || !request.Url().IsEmpty()); |
| 1703 loader->SetReplacesCurrentHistoryItem(replace_current_item); | 1715 loader->SetReplacesCurrentHistoryItem(replace_current_item); |
| 1704 return loader; | 1716 return loader; |
| 1705 } | 1717 } |
| 1706 | 1718 |
| 1707 } // namespace blink | 1719 } // namespace blink |
| OLD | NEW |