Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: third_party/WebKit/Source/core/loader/FrameLoader.cpp

Issue 2949073002: Changing scroll and view state in onpopstate shouldn't overwrite back/forward state restore (Closed)
Patch Set: +test Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698