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

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

Issue 1159723003: Don't reuse HistoryItems for multiple navigations (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address comments Created 5 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/loader/FrameLoader.h ('k') | Source/core/loader/HistoryItem.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
5 * Copyright (C) 2008 Alp Toker <alp@atoker.com> 5 * Copyright (C) 2008 Alp Toker <alp@atoker.com>
6 * Copyright (C) Research In Motion Limited 2009. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2009. All rights reserved.
7 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> 7 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com>
8 * Copyright (C) 2011 Google Inc. All rights reserved. 8 * Copyright (C) 2011 Google Inc. All rights reserved.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 189
190 m_currentItem->setScrollPoint(m_frame->view()->scrollPosition()); 190 m_currentItem->setScrollPoint(m_frame->view()->scrollPosition());
191 m_currentItem->setPinchViewportScrollPoint(m_frame->host()->pinchViewport(). visibleRect().location()); 191 m_currentItem->setPinchViewportScrollPoint(m_frame->host()->pinchViewport(). visibleRect().location());
192 192
193 if (m_frame->isMainFrame()) 193 if (m_frame->isMainFrame())
194 m_currentItem->setPageScaleFactor(m_frame->page()->pageScaleFactor()); 194 m_currentItem->setPageScaleFactor(m_frame->page()->pageScaleFactor());
195 195
196 client()->didUpdateCurrentHistoryItem(); 196 client()->didUpdateCurrentHistoryItem();
197 } 197 }
198 198
199 void FrameLoader::clearScrollPositionAndViewState()
200 {
201 ASSERT(m_frame->isMainFrame());
202 if (!m_currentItem)
203 return;
204 m_currentItem->clearScrollPoint();
205 m_currentItem->setPageScaleFactor(0);
206 }
207
208 void FrameLoader::dispatchUnloadEvent() 199 void FrameLoader::dispatchUnloadEvent()
209 { 200 {
210 saveScrollState(); 201 saveScrollState();
211 202
212 if (m_frame->document() && !SVGImage::isInSVGImage(m_frame->document())) 203 if (m_frame->document() && !SVGImage::isInSVGImage(m_frame->document()))
213 m_frame->document()->dispatchUnloadEvents(); 204 m_frame->document()->dispatchUnloadEvents();
214 205
215 if (Page* page = m_frame->page()) 206 if (Page* page = m_frame->page())
216 page->undoStack().didUnloadFrame(*m_frame); 207 page->undoStack().didUnloadFrame(*m_frame);
217 } 208 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 clear(); 280 clear();
290 281
291 // detachChildren() potentially detaches the frame from the document. The 282 // detachChildren() potentially detaches the frame from the document. The
292 // loading cannot continue in that case. 283 // loading cannot continue in that case.
293 if (!m_frame->page()) 284 if (!m_frame->page())
294 return; 285 return;
295 286
296 documentLoader->replaceDocumentWhileExecutingJavaScriptURL(init, source, own erDocument); 287 documentLoader->replaceDocumentWhileExecutingJavaScriptURL(init, source, own erDocument);
297 } 288 }
298 289
299 void FrameLoader::setHistoryItemStateForCommit(HistoryCommitType historyCommitTy pe, bool isPushOrReplaceState, HistoryScrollRestorationType scrollRestorationTyp e, PassRefPtr<SerializedScriptValue> stateObject) 290 void FrameLoader::setHistoryItemStateForCommit(HistoryCommitType historyCommitTy pe, HistoryNavigationType navigationType)
300 { 291 {
301 if (m_provisionalItem) 292 RefPtrWillBeRawPtr<HistoryItem> oldItem = m_currentItem;
302 m_currentItem = m_provisionalItem.release(); 293 m_currentItem = historyCommitType == BackForwardCommit ? m_provisionalItem.r elease() : HistoryItem::create();
303
304 if (!m_currentItem || historyCommitType == StandardCommit) {
305 m_currentItem = HistoryItem::create();
306 } else if (!isPushOrReplaceState && m_documentLoader->url() != m_currentItem ->url()) {
307 m_currentItem->generateNewItemSequenceNumber();
308 if (!equalIgnoringFragmentIdentifier(m_documentLoader->url(), m_currentI tem->url()))
309 m_currentItem->generateNewDocumentSequenceNumber();
310 }
311
312 m_currentItem->setURL(m_documentLoader->urlForHistory()); 294 m_currentItem->setURL(m_documentLoader->urlForHistory());
313 m_currentItem->setDocumentState(m_frame->document()->formElementsState()); 295 m_currentItem->setDocumentState(m_frame->document()->formElementsState());
314 m_currentItem->setTarget(m_frame->tree().uniqueName()); 296 m_currentItem->setTarget(m_frame->tree().uniqueName());
315 if (isPushOrReplaceState) {
316 m_currentItem->setStateObject(stateObject);
317 m_currentItem->setScrollRestorationType(scrollRestorationType);
318 }
319 m_currentItem->setReferrer(SecurityPolicy::generateReferrer(m_documentLoader ->request().referrerPolicy(), m_currentItem->url(), m_documentLoader->request(). httpReferrer())); 297 m_currentItem->setReferrer(SecurityPolicy::generateReferrer(m_documentLoader ->request().referrerPolicy(), m_currentItem->url(), m_documentLoader->request(). httpReferrer()));
320 m_currentItem->setFormInfoFromRequest(m_documentLoader->request()); 298 m_currentItem->setFormInfoFromRequest(m_documentLoader->request());
299
300 // Don't propagate state from the old item to the new item if there isn't an old item (obviously),
301 // or if this is a back/forward navigation, since we explicitly want to rest ore the state we just
302 // committed.
303 if (!oldItem || historyCommitType == BackForwardCommit)
304 return;
305 // Don't propagate state from the old item if this is a different-document n avigation, unless the before
306 // and after pages are logically related. This means they have the same url (ignoring fragment) and
307 // the new item was loaded via reload or client redirect.
308 if (navigationType == HistoryNavigationType::DifferentDocument && (historyCo mmitType != HistoryInertCommit || !equalIgnoringFragmentIdentifier(oldItem->url( ), m_currentItem->url())))
309 return;
310 m_currentItem->setDocumentSequenceNumber(oldItem->documentSequenceNumber());
311 m_currentItem->setScrollPoint(oldItem->scrollPoint());
312 m_currentItem->setPinchViewportScrollPoint(oldItem->pinchViewportScrollPoint ());
313 m_currentItem->setPageScaleFactor(oldItem->pageScaleFactor());
314 m_currentItem->setFrameSequenceNumber(oldItem->frameSequenceNumber());
315 m_currentItem->setStateObject(oldItem->stateObject());
316 // The item sequence number determines whether items are "the same", such ba ck/forward navigation
317 // between items with the same item sequence number is a no-op. Only treat t his as identical if the
318 // navigation did not create a back/forward entry and the url is identical o r it was loaded via
319 // history.replaceState().
320 if (historyCommitType == HistoryInertCommit && (navigationType == HistoryNav igationType::HistoryApi || oldItem->url() == m_currentItem->url()))
321 m_currentItem->setItemSequenceNumber(oldItem->itemSequenceNumber());
321 } 322 }
322 323
323 static HistoryCommitType loadTypeToCommitType(FrameLoadType type) 324 static HistoryCommitType loadTypeToCommitType(FrameLoadType type)
324 { 325 {
325 switch (type) { 326 switch (type) {
326 case FrameLoadTypeStandard: 327 case FrameLoadTypeStandard:
327 return StandardCommit; 328 return StandardCommit;
328 case FrameLoadTypeInitialInChildFrame: 329 case FrameLoadTypeInitialInChildFrame:
329 case FrameLoadTypeInitialHistoryLoad: 330 case FrameLoadTypeInitialHistoryLoad:
330 return InitialCommitInChildFrame; 331 return InitialCommitInChildFrame;
331 case FrameLoadTypeBackForward: 332 case FrameLoadTypeBackForward:
332 return BackForwardCommit; 333 return BackForwardCommit;
333 default: 334 default:
334 break; 335 break;
335 } 336 }
336 return HistoryInertCommit; 337 return HistoryInertCommit;
337 } 338 }
338 339
339 void FrameLoader::receivedFirstData() 340 void FrameLoader::receivedFirstData()
340 { 341 {
341 if (m_stateMachine.creatingInitialEmptyDocument()) 342 if (m_stateMachine.creatingInitialEmptyDocument())
342 return; 343 return;
343 344
344 HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType); 345 HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType);
345 if (historyCommitType == StandardCommit && (m_documentLoader->urlForHistory( ).isEmpty() || (opener() && !m_currentItem && m_documentLoader->originalRequest( ).url().isEmpty()))) 346 if (historyCommitType == StandardCommit && (m_documentLoader->urlForHistory( ).isEmpty() || (opener() && !m_currentItem && m_documentLoader->originalRequest( ).url().isEmpty())))
346 historyCommitType = HistoryInertCommit; 347 historyCommitType = HistoryInertCommit;
347 else if (historyCommitType == InitialCommitInChildFrame && MixedContentCheck er::isMixedContent(m_frame->tree().top()->securityContext()->securityOrigin(), m _documentLoader->url())) 348 else if (historyCommitType == InitialCommitInChildFrame && MixedContentCheck er::isMixedContent(m_frame->tree().top()->securityContext()->securityOrigin(), m _documentLoader->url()))
348 historyCommitType = HistoryInertCommit; 349 historyCommitType = HistoryInertCommit;
349 setHistoryItemStateForCommit(historyCommitType); 350 setHistoryItemStateForCommit(historyCommitType, HistoryNavigationType::Diffe rentDocument);
350 351
351 if (!m_stateMachine.committedMultipleRealLoads() && m_loadType == FrameLoadT ypeStandard) 352 if (!m_stateMachine.committedMultipleRealLoads() && m_loadType == FrameLoadT ypeStandard)
352 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedMultipleRealL oads); 353 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedMultipleRealL oads);
353 354
354 client()->dispatchDidCommitLoad(m_currentItem.get(), historyCommitType); 355 client()->dispatchDidCommitLoad(m_currentItem.get(), historyCommitType);
355 356
356 TRACE_EVENT1("devtools.timeline", "CommitLoad", "data", InspectorCommitLoadE vent::data(m_frame)); 357 TRACE_EVENT1("devtools.timeline", "CommitLoad", "data", InspectorCommitLoadE vent::data(m_frame));
357 InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get()); 358 InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get());
358 m_frame->page()->didCommitLoad(m_frame); 359 m_frame->page()->didCommitLoad(m_frame);
359 dispatchDidClearDocumentOfWindowObject(); 360 dispatchDidClearDocumentOfWindowObject();
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 // Generate start and stop notifications only when loader is completed so th at we 575 // Generate start and stop notifications only when loader is completed so th at we
575 // don't fire them for fragment redirection that happens in window.onload ha ndler. 576 // don't fire them for fragment redirection that happens in window.onload ha ndler.
576 // See https://bugs.webkit.org/show_bug.cgi?id=31838 577 // See https://bugs.webkit.org/show_bug.cgi?id=31838
577 if (m_frame->document()->loadEventFinished()) 578 if (m_frame->document()->loadEventFinished())
578 client()->didStartLoading(NavigationWithinSameDocument); 579 client()->didStartLoading(NavigationWithinSameDocument);
579 580
580 HistoryCommitType historyCommitType = loadTypeToCommitType(type); 581 HistoryCommitType historyCommitType = loadTypeToCommitType(type);
581 if (!m_currentItem) 582 if (!m_currentItem)
582 historyCommitType = HistoryInertCommit; 583 historyCommitType = HistoryInertCommit;
583 584
584 setHistoryItemStateForCommit(historyCommitType, sameDocumentNavigationSource == SameDocumentNavigationHistoryApi, scrollRestorationType, data); 585 setHistoryItemStateForCommit(historyCommitType, sameDocumentNavigationSource == SameDocumentNavigationHistoryApi ? HistoryNavigationType::HistoryApi : Histo ryNavigationType::Fragment);
586 if (sameDocumentNavigationSource == SameDocumentNavigationHistoryApi) {
587 m_currentItem->setStateObject(data);
588 m_currentItem->setScrollRestorationType(scrollRestorationType);
589 }
585 client()->dispatchDidNavigateWithinPage(m_currentItem.get(), historyCommitTy pe); 590 client()->dispatchDidNavigateWithinPage(m_currentItem.get(), historyCommitTy pe);
586 client()->dispatchDidReceiveTitle(m_frame->document()->title()); 591 client()->dispatchDidReceiveTitle(m_frame->document()->title());
587 if (m_frame->document()->loadEventFinished()) 592 if (m_frame->document()->loadEventFinished())
588 client()->didStopLoading(); 593 client()->didStopLoading();
589 } 594 }
590 595
591 void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip tValue> stateObject, FrameLoadType type, ClientRedirectPolicy clientRedirect) 596 void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip tValue> stateObject, FrameLoadType type, ClientRedirectPolicy clientRedirect)
592 { 597 {
593 // If we have a state object, we cannot also be a new navigation. 598 // If we have a state object, we cannot also be a new navigation.
594 ASSERT(!stateObject || type == FrameLoadTypeBackForward); 599 ASSERT(!stateObject || type == FrameLoadTypeBackForward);
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 // This tries to balance 1. restoring as soon as possible, 2. detecting 1033 // This tries to balance 1. restoring as soon as possible, 2. detecting
1029 // clamping to avoid repeatedly popping the scroll position down as the 1034 // clamping to avoid repeatedly popping the scroll position down as the
1030 // page height increases, 3. ignore clamp detection after load completes 1035 // page height increases, 3. ignore clamp detection after load completes
1031 // because that may be because the page will never reach its previous 1036 // because that may be because the page will never reach its previous
1032 // height. 1037 // height.
1033 bool canRestoreWithoutClamping = view->clampOffsetAtScale(m_currentItem->scr ollPoint(), 1) == m_currentItem->scrollPoint(); 1038 bool canRestoreWithoutClamping = view->clampOffsetAtScale(m_currentItem->scr ollPoint(), 1) == m_currentItem->scrollPoint();
1034 bool canRestoreWithoutAnnoyingUser = !view->wasScrolledByUser() && (canResto reWithoutClamping || m_frame->isLoading()); 1039 bool canRestoreWithoutAnnoyingUser = !view->wasScrolledByUser() && (canResto reWithoutClamping || m_frame->isLoading());
1035 if (!canRestoreWithoutAnnoyingUser) 1040 if (!canRestoreWithoutAnnoyingUser)
1036 return; 1041 return;
1037 1042
1038 if (m_frame->isMainFrame() && m_currentItem->pageScaleFactor()) { 1043 if (m_frame->isMainFrame() && m_currentItem->pageScaleFactor() != 1.0f) {
bokan 2015/06/03 15:07:29 I don't think this is right. This check was added
1039 FloatPoint pinchViewportOffset(m_currentItem->pinchViewportScrollPoint() ); 1044 FloatPoint pinchViewportOffset(m_currentItem->pinchViewportScrollPoint() );
1040 IntPoint frameScrollOffset(m_currentItem->scrollPoint()); 1045 IntPoint frameScrollOffset(m_currentItem->scrollPoint());
1041 1046
1042 m_frame->page()->setPageScaleFactor(m_currentItem->pageScaleFactor(), fr ameScrollOffset); 1047 m_frame->page()->setPageScaleFactor(m_currentItem->pageScaleFactor(), fr ameScrollOffset);
1043 1048
1044 // If the pinch viewport's offset is (-1, -1) it means the history item 1049 // If the pinch viewport's offset is (-1, -1) it means the history item
1045 // is an old version of HistoryItem so distribute the scroll between 1050 // is an old version of HistoryItem so distribute the scroll between
1046 // the main frame and the pinch viewport as best as we can. 1051 // the main frame and the pinch viewport as best as we can.
1047 if (pinchViewportOffset.x() == -1 && pinchViewportOffset.y() == -1) 1052 if (pinchViewportOffset.x() == -1 && pinchViewportOffset.y() == -1)
1048 pinchViewportOffset = FloatPoint(frameScrollOffset - view->scrollPos ition()); 1053 pinchViewportOffset = FloatPoint(frameScrollOffset - view->scrollPos ition());
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 // FIXME: We need a way to propagate insecure requests policy flags to 1438 // FIXME: We need a way to propagate insecure requests policy flags to
1434 // out-of-process frames. For now, we'll always use default behavior. 1439 // out-of-process frames. For now, we'll always use default behavior.
1435 if (!parentFrame->isLocalFrame()) 1440 if (!parentFrame->isLocalFrame())
1436 return nullptr; 1441 return nullptr;
1437 1442
1438 ASSERT(toLocalFrame(parentFrame)->document()); 1443 ASSERT(toLocalFrame(parentFrame)->document());
1439 return toLocalFrame(parentFrame)->document()->insecureNavigationsToUpgrade() ; 1444 return toLocalFrame(parentFrame)->document()->insecureNavigationsToUpgrade() ;
1440 } 1445 }
1441 1446
1442 } // namespace blink 1447 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/loader/FrameLoader.h ('k') | Source/core/loader/HistoryItem.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698