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

Unified 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: Reset ViewState when trying to copy from a nullptr Created 3 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/loader/FrameLoader.cpp
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index f724ac4a45aadeca0790038d7424dad7a5e8968c..315a3dd67a2d25450da0ffe6e06b9174e1e94061 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -591,13 +591,21 @@ void FrameLoader::LoadInSameDocument(
frame_->GetDocument()->CheckCompleted();
+ // onpopstate might change view state, so stash for later restore.
+ std::unique_ptr<HistoryItem::ViewState> view_state;
+ if (history_item && history_item->GetViewState()) {
+ view_state =
+ WTF::MakeUnique<HistoryItem::ViewState>(*history_item->GetViewState());
+ }
+
frame_->DomWindow()->StatePopped(state_object
? std::move(state_object)
: SerializedScriptValue::NullValue());
if (history_item) {
- RestoreScrollPositionAndViewStateForLoadType(frame_load_type,
- kHistorySameDocumentLoad);
+ RestoreScrollPositionAndViewState(frame_load_type, kHistorySameDocumentLoad,
+ view_state.get(),
+ history_item->ScrollRestorationType());
}
// We need to scroll to the fragment whether or not a hash change occurred,
@@ -1093,30 +1101,32 @@ bool FrameLoader::IsLoadingMainFrame() const {
}
void FrameLoader::RestoreScrollPositionAndViewState() {
- if (!frame_->GetPage() || !GetDocumentLoader())
+ if (!frame_->GetPage() || !GetDocumentLoader() ||
+ !GetDocumentLoader()->GetHistoryItem())
return;
- RestoreScrollPositionAndViewStateForLoadType(GetDocumentLoader()->LoadType(),
- kHistoryDifferentDocumentLoad);
+ RestoreScrollPositionAndViewState(
+ GetDocumentLoader()->LoadType(), kHistoryDifferentDocumentLoad,
+ GetDocumentLoader()->GetHistoryItem()->GetViewState(),
+ GetDocumentLoader()->GetHistoryItem()->ScrollRestorationType());
}
-void FrameLoader::RestoreScrollPositionAndViewStateForLoadType(
+void FrameLoader::RestoreScrollPositionAndViewState(
FrameLoadType load_type,
- HistoryLoadType history_load_type) {
+ HistoryLoadType history_load_type,
+ HistoryItem::ViewState* view_state,
+ HistoryScrollRestorationType scroll_restoration_type) {
LocalFrameView* view = frame_->View();
if (!view || !view->LayoutViewportScrollableArea() ||
!state_machine_.CommittedFirstRealDocumentLoad() ||
!frame_->IsAttached()) {
return;
}
- if (!NeedsHistoryItemRestore(load_type))
- return;
- HistoryItem* history_item = document_loader_->GetHistoryItem();
- if (!history_item || !history_item->DidSaveScrollOrScaleState())
+ if (!NeedsHistoryItemRestore(load_type) || !view_state)
return;
bool should_restore_scroll =
- history_item->ScrollRestorationType() != kScrollRestorationManual;
- bool should_restore_scale = history_item->PageScaleFactor();
+ scroll_restoration_type != kScrollRestorationManual;
+ bool should_restore_scale = view_state->page_scale_factor_;
// This tries to balance:
// 1. restoring as soon as possible.
@@ -1129,7 +1139,7 @@ void FrameLoader::RestoreScrollPositionAndViewStateForLoadType(
// be smaller than the previous page).
bool can_restore_without_clamping =
view->LayoutViewportScrollableArea()->ClampScrollOffset(
- history_item->GetScrollOffset()) == history_item->GetScrollOffset();
+ view_state->scroll_offset_) == view_state->scroll_offset_;
bool should_force_clamping =
!frame_->IsLoading() || history_load_type == kHistorySameDocumentLoad;
@@ -1147,13 +1157,13 @@ void FrameLoader::RestoreScrollPositionAndViewStateForLoadType(
if (should_restore_scroll) {
view->LayoutViewportScrollableArea()->SetScrollOffset(
- history_item->GetScrollOffset(), kProgrammaticScroll);
+ view_state->scroll_offset_, kProgrammaticScroll);
}
// For main frame restore scale and visual viewport position
if (frame_->IsMainFrame()) {
ScrollOffset visual_viewport_offset(
- history_item->VisualViewportScrollOffset());
+ view_state->visual_viewport_scroll_offset_);
// If the visual viewport's offset is (-1, -1) it means the history item
// is an old version of HistoryItem so distribute the scroll between
@@ -1161,16 +1171,16 @@ void FrameLoader::RestoreScrollPositionAndViewStateForLoadType(
if (visual_viewport_offset.Width() == -1 &&
visual_viewport_offset.Height() == -1) {
visual_viewport_offset =
- history_item->GetScrollOffset() -
+ view_state->scroll_offset_ -
view->LayoutViewportScrollableArea()->GetScrollOffset();
}
VisualViewport& visual_viewport = frame_->GetPage()->GetVisualViewport();
if (should_restore_scale && should_restore_scroll) {
- visual_viewport.SetScaleAndLocation(history_item->PageScaleFactor(),
+ visual_viewport.SetScaleAndLocation(view_state->page_scale_factor_,
FloatPoint(visual_viewport_offset));
} else if (should_restore_scale) {
- visual_viewport.SetScale(history_item->PageScaleFactor());
+ visual_viewport.SetScale(view_state->page_scale_factor_);
} else if (should_restore_scroll) {
visual_viewport.SetLocation(FloatPoint(visual_viewport_offset));
}
« no previous file with comments | « third_party/WebKit/Source/core/loader/FrameLoader.h ('k') | third_party/WebKit/Source/core/loader/HistoryItem.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698