| 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 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 if (history_item) | 584 if (history_item) |
| 585 document_loader_->SetItemForHistoryNavigation(history_item); | 585 document_loader_->SetItemForHistoryNavigation(history_item); |
| 586 UpdateForSameDocumentNavigation(url, kSameDocumentNavigationDefault, nullptr, | 586 UpdateForSameDocumentNavigation(url, kSameDocumentNavigationDefault, nullptr, |
| 587 kScrollRestorationAuto, frame_load_type, | 587 kScrollRestorationAuto, frame_load_type, |
| 588 initiating_document); | 588 initiating_document); |
| 589 | 589 |
| 590 document_loader_->GetInitialScrollState().was_scrolled_by_user = false; | 590 document_loader_->GetInitialScrollState().was_scrolled_by_user = false; |
| 591 | 591 |
| 592 frame_->GetDocument()->CheckCompleted(); | 592 frame_->GetDocument()->CheckCompleted(); |
| 593 | 593 |
| 594 // onpopstate might change view state, so stash for later restore. |
| 595 std::unique_ptr<HistoryItem::ViewState> view_state; |
| 596 if (history_item && history_item->GetViewState()) { |
| 597 view_state = |
| 598 WTF::MakeUnique<HistoryItem::ViewState>(*history_item->GetViewState()); |
| 599 } |
| 600 |
| 594 frame_->DomWindow()->StatePopped(state_object | 601 frame_->DomWindow()->StatePopped(state_object |
| 595 ? std::move(state_object) | 602 ? std::move(state_object) |
| 596 : SerializedScriptValue::NullValue()); | 603 : SerializedScriptValue::NullValue()); |
| 597 | 604 |
| 598 if (history_item) { | 605 if (history_item) { |
| 599 RestoreScrollPositionAndViewStateForLoadType(frame_load_type, | 606 RestoreScrollPositionAndViewState(frame_load_type, kHistorySameDocumentLoad, |
| 600 kHistorySameDocumentLoad); | 607 view_state.get(), |
| 608 history_item->ScrollRestorationType()); |
| 601 } | 609 } |
| 602 | 610 |
| 603 // We need to scroll to the fragment whether or not a hash change occurred, | 611 // We need to scroll to the fragment whether or not a hash change occurred, |
| 604 // since the user might have scrolled since the previous navigation. | 612 // since the user might have scrolled since the previous navigation. |
| 605 ProcessFragment(url, frame_load_type, kNavigationWithinSameDocument); | 613 ProcessFragment(url, frame_load_type, kNavigationWithinSameDocument); |
| 606 | 614 |
| 607 TakeObjectSnapshot(); | 615 TakeObjectSnapshot(); |
| 608 } | 616 } |
| 609 | 617 |
| 610 // static | 618 // static |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 Client()->TransitionToCommittedForNewPage(); | 1094 Client()->TransitionToCommittedForNewPage(); |
| 1087 | 1095 |
| 1088 frame_->GetNavigationScheduler().Cancel(); | 1096 frame_->GetNavigationScheduler().Cancel(); |
| 1089 } | 1097 } |
| 1090 | 1098 |
| 1091 bool FrameLoader::IsLoadingMainFrame() const { | 1099 bool FrameLoader::IsLoadingMainFrame() const { |
| 1092 return frame_->IsMainFrame(); | 1100 return frame_->IsMainFrame(); |
| 1093 } | 1101 } |
| 1094 | 1102 |
| 1095 void FrameLoader::RestoreScrollPositionAndViewState() { | 1103 void FrameLoader::RestoreScrollPositionAndViewState() { |
| 1096 if (!frame_->GetPage() || !GetDocumentLoader()) | 1104 if (!frame_->GetPage() || !GetDocumentLoader() || |
| 1105 !GetDocumentLoader()->GetHistoryItem()) |
| 1097 return; | 1106 return; |
| 1098 RestoreScrollPositionAndViewStateForLoadType(GetDocumentLoader()->LoadType(), | 1107 RestoreScrollPositionAndViewState( |
| 1099 kHistoryDifferentDocumentLoad); | 1108 GetDocumentLoader()->LoadType(), kHistoryDifferentDocumentLoad, |
| 1109 GetDocumentLoader()->GetHistoryItem()->GetViewState(), |
| 1110 GetDocumentLoader()->GetHistoryItem()->ScrollRestorationType()); |
| 1100 } | 1111 } |
| 1101 | 1112 |
| 1102 void FrameLoader::RestoreScrollPositionAndViewStateForLoadType( | 1113 void FrameLoader::RestoreScrollPositionAndViewState( |
| 1103 FrameLoadType load_type, | 1114 FrameLoadType load_type, |
| 1104 HistoryLoadType history_load_type) { | 1115 HistoryLoadType history_load_type, |
| 1116 HistoryItem::ViewState* view_state, |
| 1117 HistoryScrollRestorationType scroll_restoration_type) { |
| 1105 LocalFrameView* view = frame_->View(); | 1118 LocalFrameView* view = frame_->View(); |
| 1106 if (!view || !view->LayoutViewportScrollableArea() || | 1119 if (!view || !view->LayoutViewportScrollableArea() || |
| 1107 !state_machine_.CommittedFirstRealDocumentLoad() || | 1120 !state_machine_.CommittedFirstRealDocumentLoad() || |
| 1108 !frame_->IsAttached()) { | 1121 !frame_->IsAttached()) { |
| 1109 return; | 1122 return; |
| 1110 } | 1123 } |
| 1111 if (!NeedsHistoryItemRestore(load_type)) | 1124 if (!NeedsHistoryItemRestore(load_type) || !view_state) |
| 1112 return; | |
| 1113 HistoryItem* history_item = document_loader_->GetHistoryItem(); | |
| 1114 if (!history_item || !history_item->DidSaveScrollOrScaleState()) | |
| 1115 return; | 1125 return; |
| 1116 | 1126 |
| 1117 bool should_restore_scroll = | 1127 bool should_restore_scroll = |
| 1118 history_item->ScrollRestorationType() != kScrollRestorationManual; | 1128 scroll_restoration_type != kScrollRestorationManual; |
| 1119 bool should_restore_scale = history_item->PageScaleFactor(); | 1129 bool should_restore_scale = view_state->page_scale_factor_; |
| 1120 | 1130 |
| 1121 // This tries to balance: | 1131 // This tries to balance: |
| 1122 // 1. restoring as soon as possible. | 1132 // 1. restoring as soon as possible. |
| 1123 // 2. not overriding user scroll (TODO(majidvp): also respect user scale). | 1133 // 2. not overriding user scroll (TODO(majidvp): also respect user scale). |
| 1124 // 3. detecting clamping to avoid repeatedly popping the scroll position down | 1134 // 3. detecting clamping to avoid repeatedly popping the scroll position down |
| 1125 // as the page height increases. | 1135 // as the page height increases. |
| 1126 // 4. forcing a layout if necessary to avoid clamping. | 1136 // 4. forcing a layout if necessary to avoid clamping. |
| 1127 // 5. ignoring clamp detection if scroll state is not being restored, if load | 1137 // 5. ignoring clamp detection if scroll state is not being restored, if load |
| 1128 // is complete, or if the navigation is same-document (as the new page may | 1138 // is complete, or if the navigation is same-document (as the new page may |
| 1129 // be smaller than the previous page). | 1139 // be smaller than the previous page). |
| 1130 bool can_restore_without_clamping = | 1140 bool can_restore_without_clamping = |
| 1131 view->LayoutViewportScrollableArea()->ClampScrollOffset( | 1141 view->LayoutViewportScrollableArea()->ClampScrollOffset( |
| 1132 history_item->GetScrollOffset()) == history_item->GetScrollOffset(); | 1142 view_state->scroll_offset_) == view_state->scroll_offset_; |
| 1133 | 1143 |
| 1134 bool should_force_clamping = | 1144 bool should_force_clamping = |
| 1135 !frame_->IsLoading() || history_load_type == kHistorySameDocumentLoad; | 1145 !frame_->IsLoading() || history_load_type == kHistorySameDocumentLoad; |
| 1136 // Here |can_restore_without_clamping| is false, but layout might be necessary | 1146 // Here |can_restore_without_clamping| is false, but layout might be necessary |
| 1137 // to ensure correct content size. | 1147 // to ensure correct content size. |
| 1138 if (!can_restore_without_clamping && should_force_clamping) | 1148 if (!can_restore_without_clamping && should_force_clamping) |
| 1139 frame_->GetDocument()->UpdateStyleAndLayout(); | 1149 frame_->GetDocument()->UpdateStyleAndLayout(); |
| 1140 | 1150 |
| 1141 bool can_restore_without_annoying_user = | 1151 bool can_restore_without_annoying_user = |
| 1142 !GetDocumentLoader()->GetInitialScrollState().was_scrolled_by_user && | 1152 !GetDocumentLoader()->GetInitialScrollState().was_scrolled_by_user && |
| 1143 (can_restore_without_clamping || should_force_clamping || | 1153 (can_restore_without_clamping || should_force_clamping || |
| 1144 !should_restore_scroll); | 1154 !should_restore_scroll); |
| 1145 if (!can_restore_without_annoying_user) | 1155 if (!can_restore_without_annoying_user) |
| 1146 return; | 1156 return; |
| 1147 | 1157 |
| 1148 if (should_restore_scroll) { | 1158 if (should_restore_scroll) { |
| 1149 view->LayoutViewportScrollableArea()->SetScrollOffset( | 1159 view->LayoutViewportScrollableArea()->SetScrollOffset( |
| 1150 history_item->GetScrollOffset(), kProgrammaticScroll); | 1160 view_state->scroll_offset_, kProgrammaticScroll); |
| 1151 } | 1161 } |
| 1152 | 1162 |
| 1153 // For main frame restore scale and visual viewport position | 1163 // For main frame restore scale and visual viewport position |
| 1154 if (frame_->IsMainFrame()) { | 1164 if (frame_->IsMainFrame()) { |
| 1155 ScrollOffset visual_viewport_offset( | 1165 ScrollOffset visual_viewport_offset( |
| 1156 history_item->VisualViewportScrollOffset()); | 1166 view_state->visual_viewport_scroll_offset_); |
| 1157 | 1167 |
| 1158 // If the visual viewport's offset is (-1, -1) it means the history item | 1168 // If the visual viewport's offset is (-1, -1) it means the history item |
| 1159 // is an old version of HistoryItem so distribute the scroll between | 1169 // is an old version of HistoryItem so distribute the scroll between |
| 1160 // the main frame and the visual viewport as best as we can. | 1170 // the main frame and the visual viewport as best as we can. |
| 1161 if (visual_viewport_offset.Width() == -1 && | 1171 if (visual_viewport_offset.Width() == -1 && |
| 1162 visual_viewport_offset.Height() == -1) { | 1172 visual_viewport_offset.Height() == -1) { |
| 1163 visual_viewport_offset = | 1173 visual_viewport_offset = |
| 1164 history_item->GetScrollOffset() - | 1174 view_state->scroll_offset_ - |
| 1165 view->LayoutViewportScrollableArea()->GetScrollOffset(); | 1175 view->LayoutViewportScrollableArea()->GetScrollOffset(); |
| 1166 } | 1176 } |
| 1167 | 1177 |
| 1168 VisualViewport& visual_viewport = frame_->GetPage()->GetVisualViewport(); | 1178 VisualViewport& visual_viewport = frame_->GetPage()->GetVisualViewport(); |
| 1169 if (should_restore_scale && should_restore_scroll) { | 1179 if (should_restore_scale && should_restore_scroll) { |
| 1170 visual_viewport.SetScaleAndLocation(history_item->PageScaleFactor(), | 1180 visual_viewport.SetScaleAndLocation(view_state->page_scale_factor_, |
| 1171 FloatPoint(visual_viewport_offset)); | 1181 FloatPoint(visual_viewport_offset)); |
| 1172 } else if (should_restore_scale) { | 1182 } else if (should_restore_scale) { |
| 1173 visual_viewport.SetScale(history_item->PageScaleFactor()); | 1183 visual_viewport.SetScale(view_state->page_scale_factor_); |
| 1174 } else if (should_restore_scroll) { | 1184 } else if (should_restore_scroll) { |
| 1175 visual_viewport.SetLocation(FloatPoint(visual_viewport_offset)); | 1185 visual_viewport.SetLocation(FloatPoint(visual_viewport_offset)); |
| 1176 } | 1186 } |
| 1177 | 1187 |
| 1178 if (ScrollingCoordinator* scrolling_coordinator = | 1188 if (ScrollingCoordinator* scrolling_coordinator = |
| 1179 frame_->GetPage()->GetScrollingCoordinator()) | 1189 frame_->GetPage()->GetScrollingCoordinator()) |
| 1180 scrolling_coordinator->FrameViewRootLayerDidChange(view); | 1190 scrolling_coordinator->FrameViewRootLayerDidChange(view); |
| 1181 } | 1191 } |
| 1182 | 1192 |
| 1183 GetDocumentLoader()->GetInitialScrollState().did_restore_from_history = true; | 1193 GetDocumentLoader()->GetInitialScrollState().did_restore_from_history = true; |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1743 // TODO(japhet): This is needed because the browser process DCHECKs if the | 1753 // TODO(japhet): This is needed because the browser process DCHECKs if the |
| 1744 // first entry we commit in a new frame has replacement set. It's unclear | 1754 // first entry we commit in a new frame has replacement set. It's unclear |
| 1745 // whether the DCHECK is right, investigate removing this special case. | 1755 // whether the DCHECK is right, investigate removing this special case. |
| 1746 bool replace_current_item = load_type == kFrameLoadTypeReplaceCurrentItem && | 1756 bool replace_current_item = load_type == kFrameLoadTypeReplaceCurrentItem && |
| 1747 (!Opener() || !request.Url().IsEmpty()); | 1757 (!Opener() || !request.Url().IsEmpty()); |
| 1748 loader->SetReplacesCurrentHistoryItem(replace_current_item); | 1758 loader->SetReplacesCurrentHistoryItem(replace_current_item); |
| 1749 return loader; | 1759 return loader; |
| 1750 } | 1760 } |
| 1751 | 1761 |
| 1752 } // namespace blink | 1762 } // namespace blink |
| OLD | NEW |