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

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: 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
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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 if (!m_currentItem || !m_frame->view()) 183 if (!m_currentItem || !m_frame->view())
184 return; 184 return;
185 185
186 // Shouldn't clobber anything if we might still restore later. 186 // Shouldn't clobber anything if we might still restore later.
187 if (needsHistoryItemRestore(m_loadType) && !m_frame->view()->wasScrolledByUs er()) 187 if (needsHistoryItemRestore(m_loadType) && !m_frame->view()->wasScrolledByUs er())
188 return; 188 return;
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 float scaleFactor = m_frame->page()->pageScaleFactor();
195 m_currentItem->setPageScaleFactor(scaleFactor == 1.0f ? 0 : scaleFactor) ;
dcheng 2015/06/02 19:11:35 Does 0 have some special meaning here? Why don't w
Nate Chapin 2015/06/02 21:18:57 0 is a magic value that means "we don't know, so d
196 }
195 197
196 client()->didUpdateCurrentHistoryItem(); 198 client()->didUpdateCurrentHistoryItem();
197 } 199 }
198 200
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() 201 void FrameLoader::dispatchUnloadEvent()
209 { 202 {
210 saveScrollState(); 203 saveScrollState();
211 204
212 if (m_frame->document() && !SVGImage::isInSVGImage(m_frame->document())) 205 if (m_frame->document() && !SVGImage::isInSVGImage(m_frame->document()))
213 m_frame->document()->dispatchUnloadEvents(); 206 m_frame->document()->dispatchUnloadEvents();
214 207
215 if (Page* page = m_frame->page()) 208 if (Page* page = m_frame->page())
216 page->undoStack().didUnloadFrame(*m_frame); 209 page->undoStack().didUnloadFrame(*m_frame);
217 } 210 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 clear(); 282 clear();
290 283
291 // detachChildren() potentially detaches the frame from the document. The 284 // detachChildren() potentially detaches the frame from the document. The
292 // loading cannot continue in that case. 285 // loading cannot continue in that case.
293 if (!m_frame->page()) 286 if (!m_frame->page())
294 return; 287 return;
295 288
296 documentLoader->replaceDocumentWhileExecutingJavaScriptURL(init, source, own erDocument); 289 documentLoader->replaceDocumentWhileExecutingJavaScriptURL(init, source, own erDocument);
297 } 290 }
298 291
299 void FrameLoader::setHistoryItemStateForCommit(HistoryCommitType historyCommitTy pe, bool isPushOrReplaceState, HistoryScrollRestorationType scrollRestorationTyp e, PassRefPtr<SerializedScriptValue> stateObject) 292 void FrameLoader::setHistoryItemStateForCommit(HistoryCommitType historyCommitTy pe, bool isSameDocument, bool isPushOrReplaceState)
300 { 293 {
301 if (m_provisionalItem) 294 RefPtr<HistoryItem> oldItem = m_currentItem;
dcheng 2015/06/02 19:11:35 I think this needs to be a RefPtrWillBeRawPtr, sin
Nate Chapin 2015/06/02 21:18:57 Done.
302 m_currentItem = m_provisionalItem.release(); 295 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()); 296 m_currentItem->setURL(m_documentLoader->urlForHistory());
313 m_currentItem->setDocumentState(m_frame->document()->formElementsState()); 297 m_currentItem->setDocumentState(m_frame->document()->formElementsState());
314 m_currentItem->setTarget(m_frame->tree().uniqueName()); 298 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())); 299 m_currentItem->setReferrer(SecurityPolicy::generateReferrer(m_documentLoader ->request().referrerPolicy(), m_currentItem->url(), m_documentLoader->request(). httpReferrer()));
320 m_currentItem->setFormInfoFromRequest(m_documentLoader->request()); 300 m_currentItem->setFormInfoFromRequest(m_documentLoader->request());
301
302 // Don't propagate state from the old item to the new item if there isn't an old item (obviously),
303 // or if this is a back/forward navigation, since we explicitly want to rest ore the state we just
304 // committed.
305 if (!oldItem || historyCommitType == BackForwardCommit)
306 return;
307 // Don't propagate state from the old item if this isn't a same-document nav igation unless the before
308 // and after pages are logically related. This means they have the same url (ignoring fragment) and
309 // the new item was loaded via reload or client redirect.
310 if (!isSameDocument && (historyCommitType != HistoryInertCommit || !equalIgn oringFragmentIdentifier(oldItem->url(), m_currentItem->url())))
311 return;
312 m_currentItem->setDocumentSequenceNumber(oldItem->documentSequenceNumber());
313 m_currentItem->setScrollPoint(oldItem->scrollPoint());
314 m_currentItem->setPinchViewportScrollPoint(oldItem->pinchViewportScrollPoint ());
315 m_currentItem->setPageScaleFactor(oldItem->pageScaleFactor());
316 m_currentItem->setFrameSequenceNumber(oldItem->frameSequenceNumber());
317 m_currentItem->setStateObject(oldItem->stateObject());
318 // The item sequence number determines whether items are "the same", such ba ck/forward navigation
319 // between items with the same item sequence number is a no-op. Only treat t his as identical if the
320 // navigation did not create a back/forward entry and the url is identical o r it was loaded via
321 // history.replaceState().
322 if (historyCommitType == HistoryInertCommit && (isPushOrReplaceState || oldI tem->url() == m_currentItem->url()))
323 m_currentItem->setItemSequenceNumber(oldItem->itemSequenceNumber());
321 } 324 }
322 325
323 static HistoryCommitType loadTypeToCommitType(FrameLoadType type) 326 static HistoryCommitType loadTypeToCommitType(FrameLoadType type)
324 { 327 {
325 switch (type) { 328 switch (type) {
326 case FrameLoadTypeStandard: 329 case FrameLoadTypeStandard:
327 return StandardCommit; 330 return StandardCommit;
328 case FrameLoadTypeInitialInChildFrame: 331 case FrameLoadTypeInitialInChildFrame:
329 case FrameLoadTypeInitialHistoryLoad: 332 case FrameLoadTypeInitialHistoryLoad:
330 return InitialCommitInChildFrame; 333 return InitialCommitInChildFrame;
331 case FrameLoadTypeBackForward: 334 case FrameLoadTypeBackForward:
332 return BackForwardCommit; 335 return BackForwardCommit;
333 default: 336 default:
334 break; 337 break;
335 } 338 }
336 return HistoryInertCommit; 339 return HistoryInertCommit;
337 } 340 }
338 341
339 void FrameLoader::receivedFirstData() 342 void FrameLoader::receivedFirstData()
340 { 343 {
341 if (m_stateMachine.creatingInitialEmptyDocument()) 344 if (m_stateMachine.creatingInitialEmptyDocument())
342 return; 345 return;
343 346
344 HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType); 347 HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType);
345 if (historyCommitType == StandardCommit && (m_documentLoader->urlForHistory( ).isEmpty() || (opener() && !m_currentItem && m_documentLoader->originalRequest( ).url().isEmpty()))) 348 if (historyCommitType == StandardCommit && (m_documentLoader->urlForHistory( ).isEmpty() || (opener() && !m_currentItem && m_documentLoader->originalRequest( ).url().isEmpty())))
346 historyCommitType = HistoryInertCommit; 349 historyCommitType = HistoryInertCommit;
347 else if (historyCommitType == InitialCommitInChildFrame && MixedContentCheck er::isMixedContent(m_frame->tree().top()->securityContext()->securityOrigin(), m _documentLoader->url())) 350 else if (historyCommitType == InitialCommitInChildFrame && MixedContentCheck er::isMixedContent(m_frame->tree().top()->securityContext()->securityOrigin(), m _documentLoader->url()))
348 historyCommitType = HistoryInertCommit; 351 historyCommitType = HistoryInertCommit;
349 setHistoryItemStateForCommit(historyCommitType); 352 setHistoryItemStateForCommit(historyCommitType, false);
350 353
351 if (!m_stateMachine.committedMultipleRealLoads() && m_loadType == FrameLoadT ypeStandard) 354 if (!m_stateMachine.committedMultipleRealLoads() && m_loadType == FrameLoadT ypeStandard)
352 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedMultipleRealL oads); 355 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedMultipleRealL oads);
353 356
354 client()->dispatchDidCommitLoad(m_currentItem.get(), historyCommitType); 357 client()->dispatchDidCommitLoad(m_currentItem.get(), historyCommitType);
355 358
356 TRACE_EVENT1("devtools.timeline", "CommitLoad", "data", InspectorCommitLoadE vent::data(m_frame)); 359 TRACE_EVENT1("devtools.timeline", "CommitLoad", "data", InspectorCommitLoadE vent::data(m_frame));
357 InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get()); 360 InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get());
358 m_frame->page()->didCommitLoad(m_frame); 361 m_frame->page()->didCommitLoad(m_frame);
359 dispatchDidClearDocumentOfWindowObject(); 362 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 577 // 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. 578 // 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 579 // See https://bugs.webkit.org/show_bug.cgi?id=31838
577 if (m_frame->document()->loadEventFinished()) 580 if (m_frame->document()->loadEventFinished())
578 client()->didStartLoading(NavigationWithinSameDocument); 581 client()->didStartLoading(NavigationWithinSameDocument);
579 582
580 HistoryCommitType historyCommitType = loadTypeToCommitType(type); 583 HistoryCommitType historyCommitType = loadTypeToCommitType(type);
581 if (!m_currentItem) 584 if (!m_currentItem)
582 historyCommitType = HistoryInertCommit; 585 historyCommitType = HistoryInertCommit;
583 586
584 setHistoryItemStateForCommit(historyCommitType, sameDocumentNavigationSource == SameDocumentNavigationHistoryApi, scrollRestorationType, data); 587 setHistoryItemStateForCommit(historyCommitType, true, sameDocumentNavigation Source == SameDocumentNavigationHistoryApi);
588 if (sameDocumentNavigationSource == SameDocumentNavigationHistoryApi) {
589 m_currentItem->setStateObject(data);
590 m_currentItem->setScrollRestorationType(scrollRestorationType);
591 }
585 client()->dispatchDidNavigateWithinPage(m_currentItem.get(), historyCommitTy pe); 592 client()->dispatchDidNavigateWithinPage(m_currentItem.get(), historyCommitTy pe);
586 client()->dispatchDidReceiveTitle(m_frame->document()->title()); 593 client()->dispatchDidReceiveTitle(m_frame->document()->title());
587 if (m_frame->document()->loadEventFinished()) 594 if (m_frame->document()->loadEventFinished())
588 client()->didStopLoading(); 595 client()->didStopLoading();
589 } 596 }
590 597
591 void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip tValue> stateObject, FrameLoadType type, ClientRedirectPolicy clientRedirect) 598 void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip tValue> stateObject, FrameLoadType type, ClientRedirectPolicy clientRedirect)
592 { 599 {
593 // If we have a state object, we cannot also be a new navigation. 600 // If we have a state object, we cannot also be a new navigation.
594 ASSERT(!stateObject || type == FrameLoadTypeBackForward); 601 ASSERT(!stateObject || type == FrameLoadTypeBackForward);
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 // FIXME: We need a way to propagate insecure requests policy flags to 1436 // FIXME: We need a way to propagate insecure requests policy flags to
1430 // out-of-process frames. For now, we'll always use default behavior. 1437 // out-of-process frames. For now, we'll always use default behavior.
1431 if (!parentFrame->isLocalFrame()) 1438 if (!parentFrame->isLocalFrame())
1432 return nullptr; 1439 return nullptr;
1433 1440
1434 ASSERT(toLocalFrame(parentFrame)->document()); 1441 ASSERT(toLocalFrame(parentFrame)->document());
1435 return toLocalFrame(parentFrame)->document()->insecureNavigationsToUpgrade() ; 1442 return toLocalFrame(parentFrame)->document()->insecureNavigationsToUpgrade() ;
1436 } 1443 }
1437 1444
1438 } // namespace blink 1445 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698