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

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: Rebase 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->setStateObject(oldItem->stateObject());
315 // The item sequence number determines whether items are "the same", such ba ck/forward navigation
316 // between items with the same item sequence number is a no-op. Only treat t his as identical if the
317 // navigation did not create a back/forward entry and the url is identical o r it was loaded via
318 // history.replaceState().
319 if (historyCommitType == HistoryInertCommit && (navigationType == HistoryNav igationType::HistoryApi || oldItem->url() == m_currentItem->url()))
320 m_currentItem->setItemSequenceNumber(oldItem->itemSequenceNumber());
321 } 321 }
322 322
323 static HistoryCommitType loadTypeToCommitType(FrameLoadType type) 323 static HistoryCommitType loadTypeToCommitType(FrameLoadType type)
324 { 324 {
325 switch (type) { 325 switch (type) {
326 case FrameLoadTypeStandard: 326 case FrameLoadTypeStandard:
327 return StandardCommit; 327 return StandardCommit;
328 case FrameLoadTypeInitialInChildFrame: 328 case FrameLoadTypeInitialInChildFrame:
329 case FrameLoadTypeInitialHistoryLoad: 329 case FrameLoadTypeInitialHistoryLoad:
330 return InitialCommitInChildFrame; 330 return InitialCommitInChildFrame;
331 case FrameLoadTypeBackForward: 331 case FrameLoadTypeBackForward:
332 return BackForwardCommit; 332 return BackForwardCommit;
333 default: 333 default:
334 break; 334 break;
335 } 335 }
336 return HistoryInertCommit; 336 return HistoryInertCommit;
337 } 337 }
338 338
339 void FrameLoader::receivedFirstData() 339 void FrameLoader::receivedFirstData()
340 { 340 {
341 if (m_stateMachine.creatingInitialEmptyDocument()) 341 if (m_stateMachine.creatingInitialEmptyDocument())
342 return; 342 return;
343 343
344 HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType); 344 HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType);
345 if (historyCommitType == StandardCommit && (m_documentLoader->urlForHistory( ).isEmpty() || (opener() && !m_currentItem && m_documentLoader->originalRequest( ).url().isEmpty()))) 345 if (historyCommitType == StandardCommit && (m_documentLoader->urlForHistory( ).isEmpty() || (opener() && !m_currentItem && m_documentLoader->originalRequest( ).url().isEmpty())))
346 historyCommitType = HistoryInertCommit; 346 historyCommitType = HistoryInertCommit;
347 else if (historyCommitType == InitialCommitInChildFrame && MixedContentCheck er::isMixedContent(m_frame->tree().top()->securityContext()->securityOrigin(), m _documentLoader->url())) 347 else if (historyCommitType == InitialCommitInChildFrame && MixedContentCheck er::isMixedContent(m_frame->tree().top()->securityContext()->securityOrigin(), m _documentLoader->url()))
348 historyCommitType = HistoryInertCommit; 348 historyCommitType = HistoryInertCommit;
349 setHistoryItemStateForCommit(historyCommitType); 349 setHistoryItemStateForCommit(historyCommitType, HistoryNavigationType::Diffe rentDocument);
350 350
351 if (!m_stateMachine.committedMultipleRealLoads() && m_loadType == FrameLoadT ypeStandard) 351 if (!m_stateMachine.committedMultipleRealLoads() && m_loadType == FrameLoadT ypeStandard)
352 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedMultipleRealL oads); 352 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedMultipleRealL oads);
353 353
354 client()->dispatchDidCommitLoad(m_currentItem.get(), historyCommitType); 354 client()->dispatchDidCommitLoad(m_currentItem.get(), historyCommitType);
355 355
356 TRACE_EVENT1("devtools.timeline", "CommitLoad", "data", InspectorCommitLoadE vent::data(m_frame)); 356 TRACE_EVENT1("devtools.timeline", "CommitLoad", "data", InspectorCommitLoadE vent::data(m_frame));
357 InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get()); 357 InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get());
358 m_frame->page()->didCommitLoad(m_frame); 358 m_frame->page()->didCommitLoad(m_frame);
359 dispatchDidClearDocumentOfWindowObject(); 359 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 574 // 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. 575 // 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 576 // See https://bugs.webkit.org/show_bug.cgi?id=31838
577 if (m_frame->document()->loadEventFinished()) 577 if (m_frame->document()->loadEventFinished())
578 client()->didStartLoading(NavigationWithinSameDocument); 578 client()->didStartLoading(NavigationWithinSameDocument);
579 579
580 HistoryCommitType historyCommitType = loadTypeToCommitType(type); 580 HistoryCommitType historyCommitType = loadTypeToCommitType(type);
581 if (!m_currentItem) 581 if (!m_currentItem)
582 historyCommitType = HistoryInertCommit; 582 historyCommitType = HistoryInertCommit;
583 583
584 setHistoryItemStateForCommit(historyCommitType, sameDocumentNavigationSource == SameDocumentNavigationHistoryApi, scrollRestorationType, data); 584 setHistoryItemStateForCommit(historyCommitType, sameDocumentNavigationSource == SameDocumentNavigationHistoryApi ? HistoryNavigationType::HistoryApi : Histo ryNavigationType::Fragment);
585 if (sameDocumentNavigationSource == SameDocumentNavigationHistoryApi) {
586 m_currentItem->setStateObject(data);
587 m_currentItem->setScrollRestorationType(scrollRestorationType);
588 }
585 client()->dispatchDidNavigateWithinPage(m_currentItem.get(), historyCommitTy pe); 589 client()->dispatchDidNavigateWithinPage(m_currentItem.get(), historyCommitTy pe);
586 client()->dispatchDidReceiveTitle(m_frame->document()->title()); 590 client()->dispatchDidReceiveTitle(m_frame->document()->title());
587 if (m_frame->document()->loadEventFinished()) 591 if (m_frame->document()->loadEventFinished())
588 client()->didStopLoading(); 592 client()->didStopLoading();
589 } 593 }
590 594
591 void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip tValue> stateObject, FrameLoadType type, ClientRedirectPolicy clientRedirect) 595 void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip tValue> stateObject, FrameLoadType type, ClientRedirectPolicy clientRedirect)
592 { 596 {
593 // If we have a state object, we cannot also be a new navigation. 597 // If we have a state object, we cannot also be a new navigation.
594 ASSERT(!stateObject || type == FrameLoadTypeBackForward); 598 ASSERT(!stateObject || type == FrameLoadTypeBackForward);
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 // FIXME: We need a way to propagate insecure requests policy flags to 1441 // FIXME: We need a way to propagate insecure requests policy flags to
1438 // out-of-process frames. For now, we'll always use default behavior. 1442 // out-of-process frames. For now, we'll always use default behavior.
1439 if (!parentFrame->isLocalFrame()) 1443 if (!parentFrame->isLocalFrame())
1440 return nullptr; 1444 return nullptr;
1441 1445
1442 ASSERT(toLocalFrame(parentFrame)->document()); 1446 ASSERT(toLocalFrame(parentFrame)->document());
1443 return toLocalFrame(parentFrame)->document()->insecureNavigationsToUpgrade() ; 1447 return toLocalFrame(parentFrame)->document()->insecureNavigationsToUpgrade() ;
1444 } 1448 }
1445 1449
1446 } // namespace blink 1450 } // 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