| OLD | NEW |
| 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 |
| 3 * reserved. |
| 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 4 * 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/) | 5 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
| 6 * (http://www.torchmobile.com/) |
| 5 * Copyright (C) 2008 Alp Toker <alp@atoker.com> | 7 * Copyright (C) 2008 Alp Toker <alp@atoker.com> |
| 6 * Copyright (C) Research In Motion Limited 2009. All rights reserved. | 8 * Copyright (C) Research In Motion Limited 2009. All rights reserved. |
| 7 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> | 9 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> |
| 8 * Copyright (C) 2011 Google Inc. All rights reserved. | 10 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 9 * | 11 * |
| 10 * Redistribution and use in source and binary forms, with or without | 12 * Redistribution and use in source and binary forms, with or without |
| 11 * modification, are permitted provided that the following conditions | 13 * modification, are permitted provided that the following conditions |
| 12 * are met: | 14 * are met: |
| 13 * | 15 * |
| 14 * 1. Redistributions of source code must retain the above copyright | 16 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 return type == FrameLoadTypeReload || | 117 return type == FrameLoadTypeReload || |
| 116 type == FrameLoadTypeReloadMainResource || | 118 type == FrameLoadTypeReloadMainResource || |
| 117 type == FrameLoadTypeReloadBypassingCache; | 119 type == FrameLoadTypeReloadBypassingCache; |
| 118 } | 120 } |
| 119 | 121 |
| 120 static bool needsHistoryItemRestore(FrameLoadType type) { | 122 static bool needsHistoryItemRestore(FrameLoadType type) { |
| 121 if (!RuntimeEnabledFeatures:: | 123 if (!RuntimeEnabledFeatures:: |
| 122 reloadwithoutSubResourceCacheRevalidationEnabled() && | 124 reloadwithoutSubResourceCacheRevalidationEnabled() && |
| 123 type == FrameLoadTypeReloadMainResource) | 125 type == FrameLoadTypeReloadMainResource) |
| 124 return false; | 126 return false; |
| 125 // TODO(toyoshim): Shall we return true for FrameLoadTypeInitialHistoryLoad to
o? | 127 // TODO(toyoshim): Shall we return true for FrameLoadTypeInitialHistoryLoad |
| 128 // too? |
| 126 return type == FrameLoadTypeBackForward || isReloadLoadType(type); | 129 return type == FrameLoadTypeBackForward || isReloadLoadType(type); |
| 127 } | 130 } |
| 128 | 131 |
| 129 // static | 132 // static |
| 130 ResourceRequest FrameLoader::resourceRequestFromHistoryItem( | 133 ResourceRequest FrameLoader::resourceRequestFromHistoryItem( |
| 131 HistoryItem* item, | 134 HistoryItem* item, |
| 132 WebCachePolicy cachePolicy) { | 135 WebCachePolicy cachePolicy) { |
| 133 RefPtr<EncodedFormData> formData = item->formData(); | 136 RefPtr<EncodedFormData> formData = item->formData(); |
| 134 ResourceRequest request(item->url()); | 137 ResourceRequest request(item->url()); |
| 135 request.setHTTPReferrer(item->referrer()); | 138 request.setHTTPReferrer(item->referrer()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 152 DCHECK(isReloadLoadType(frameLoadType)); | 155 DCHECK(isReloadLoadType(frameLoadType)); |
| 153 WebCachePolicy cachePolicy = | 156 WebCachePolicy cachePolicy = |
| 154 frameLoadType == FrameLoadTypeReloadBypassingCache | 157 frameLoadType == FrameLoadTypeReloadBypassingCache |
| 155 ? WebCachePolicy::BypassingCache | 158 ? WebCachePolicy::BypassingCache |
| 156 : WebCachePolicy::ValidatingCacheData; | 159 : WebCachePolicy::ValidatingCacheData; |
| 157 if (!m_currentItem) | 160 if (!m_currentItem) |
| 158 return ResourceRequest(); | 161 return ResourceRequest(); |
| 159 ResourceRequest request = | 162 ResourceRequest request = |
| 160 resourceRequestFromHistoryItem(m_currentItem.get(), cachePolicy); | 163 resourceRequestFromHistoryItem(m_currentItem.get(), cachePolicy); |
| 161 | 164 |
| 162 // ClientRedirectPolicy is an indication that this load was triggered by | 165 // ClientRedirectPolicy is an indication that this load was triggered by some |
| 163 // some direct interaction with the page. If this reload is not a client | 166 // direct interaction with the page. If this reload is not a client redirect, |
| 164 // redirect, we should reuse the referrer from the original load of the | 167 // we should reuse the referrer from the original load of the current |
| 165 // current document. If this reload is a client redirect (e.g., location.reloa
d()), | 168 // document. If this reload is a client redirect (e.g., location.reload()), it |
| 166 // it was initiated by something in the current document and should | 169 // was initiated by something in the current document and should therefore |
| 167 // therefore show the current document's url as the referrer. | 170 // show the current document's url as the referrer. |
| 168 if (clientRedirectPolicy == ClientRedirectPolicy::ClientRedirect) { | 171 if (clientRedirectPolicy == ClientRedirectPolicy::ClientRedirect) { |
| 169 request.setHTTPReferrer(Referrer(m_frame->document()->outgoingReferrer(), | 172 request.setHTTPReferrer(Referrer(m_frame->document()->outgoingReferrer(), |
| 170 m_frame->document()->getReferrerPolicy())); | 173 m_frame->document()->getReferrerPolicy())); |
| 171 } | 174 } |
| 172 | 175 |
| 173 if (!overrideURL.isEmpty()) { | 176 if (!overrideURL.isEmpty()) { |
| 174 request.setURL(overrideURL); | 177 request.setURL(overrideURL); |
| 175 request.clearHTTPReferrer(); | 178 request.clearHTTPReferrer(); |
| 176 } | 179 } |
| 177 request.setSkipServiceWorker(frameLoadType == | 180 request.setSkipServiceWorker(frameLoadType == |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 | 295 |
| 293 if (m_frame->document() && !SVGImage::isInSVGImage(m_frame->document())) | 296 if (m_frame->document() && !SVGImage::isInSVGImage(m_frame->document())) |
| 294 m_frame->document()->dispatchUnloadEvents(); | 297 m_frame->document()->dispatchUnloadEvents(); |
| 295 } | 298 } |
| 296 | 299 |
| 297 void FrameLoader::didExplicitOpen() { | 300 void FrameLoader::didExplicitOpen() { |
| 298 // Calling document.open counts as committing the first real document load. | 301 // Calling document.open counts as committing the first real document load. |
| 299 if (!m_stateMachine.committedFirstRealDocumentLoad()) | 302 if (!m_stateMachine.committedFirstRealDocumentLoad()) |
| 300 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad); | 303 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad); |
| 301 | 304 |
| 302 // Only model a document.open() as part of a navigation if its parent is not d
one | 305 // Only model a document.open() as part of a navigation if its parent is not |
| 303 // or in the process of completing. | 306 // done or in the process of completing. |
| 304 if (Frame* parent = m_frame->tree().parent()) { | 307 if (Frame* parent = m_frame->tree().parent()) { |
| 305 if ((parent->isLocalFrame() && | 308 if ((parent->isLocalFrame() && |
| 306 toLocalFrame(parent)->document()->loadEventStillNeeded()) || | 309 toLocalFrame(parent)->document()->loadEventStillNeeded()) || |
| 307 (parent->isRemoteFrame() && parent->isLoading())) { | 310 (parent->isRemoteFrame() && parent->isLoading())) { |
| 308 m_progressTracker->progressStarted(); | 311 m_progressTracker->progressStarted(); |
| 309 } | 312 } |
| 310 } | 313 } |
| 311 | 314 |
| 312 // Prevent window.open(url) -- eg window.open("about:blank") -- from blowing a
way results | 315 // Prevent window.open(url) -- eg window.open("about:blank") -- from blowing |
| 313 // from a subsequent window.document.open / window.document.write call. | 316 // away results from a subsequent window.document.open / window.document.write |
| 314 // Canceling redirection here works for all cases because document.open | 317 // call. Canceling redirection here works for all cases because document.open |
| 315 // implicitly precedes document.write. | 318 // implicitly precedes document.write. |
| 316 m_frame->navigationScheduler().cancel(); | 319 m_frame->navigationScheduler().cancel(); |
| 317 } | 320 } |
| 318 | 321 |
| 319 void FrameLoader::clear() { | 322 void FrameLoader::clear() { |
| 320 // clear() is called during (Local)Frame detachment or when | 323 // clear() is called during (Local)Frame detachment or when reusing a |
| 321 // reusing a FrameLoader by putting a new Document within it | 324 // FrameLoader by putting a new Document within it |
| 322 // (DocumentLoader::ensureWriter().) | 325 // (DocumentLoader::ensureWriter().) |
| 323 if (m_stateMachine.creatingInitialEmptyDocument()) | 326 if (m_stateMachine.creatingInitialEmptyDocument()) |
| 324 return; | 327 return; |
| 325 | 328 |
| 326 m_frame->editor().clear(); | 329 m_frame->editor().clear(); |
| 327 m_frame->document()->removeFocusedElementOfSubtree(m_frame->document()); | 330 m_frame->document()->removeFocusedElementOfSubtree(m_frame->document()); |
| 328 m_frame->eventHandler().clear(); | 331 m_frame->eventHandler().clear(); |
| 329 if (m_frame->view()) | 332 if (m_frame->view()) |
| 330 m_frame->view()->clear(); | 333 m_frame->view()->clear(); |
| 331 | 334 |
| 332 m_frame->script().enableEval(); | 335 m_frame->script().enableEval(); |
| 333 | 336 |
| 334 m_frame->navigationScheduler().cancel(); | 337 m_frame->navigationScheduler().cancel(); |
| 335 | 338 |
| 336 m_checkTimer.stop(); | 339 m_checkTimer.stop(); |
| 337 | 340 |
| 338 if (m_stateMachine.isDisplayingInitialEmptyDocument()) | 341 if (m_stateMachine.isDisplayingInitialEmptyDocument()) |
| 339 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad); | 342 m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad); |
| 340 | 343 |
| 341 takeObjectSnapshot(); | 344 takeObjectSnapshot(); |
| 342 } | 345 } |
| 343 | 346 |
| 344 // This is only called by ScriptController::executeScriptIfJavaScriptURL | 347 // This is only called by ScriptController::executeScriptIfJavaScriptURL and |
| 345 // and always contains the result of evaluating a javascript: url. | 348 // always contains the result of evaluating a javascript: url. This is the |
| 346 // This is the <iframe src="javascript:'html'"> case. | 349 // <iframe src="javascript:'html'"> case. |
| 347 void FrameLoader::replaceDocumentWhileExecutingJavaScriptURL( | 350 void FrameLoader::replaceDocumentWhileExecutingJavaScriptURL( |
| 348 const String& source, | 351 const String& source, |
| 349 Document* ownerDocument) { | 352 Document* ownerDocument) { |
| 350 if (!m_frame->document()->loader() || | 353 if (!m_frame->document()->loader() || |
| 351 m_frame->document()->pageDismissalEventBeingDispatched() != | 354 m_frame->document()->pageDismissalEventBeingDispatched() != |
| 352 Document::NoDismissal) | 355 Document::NoDismissal) |
| 353 return; | 356 return; |
| 354 | 357 |
| 355 // DocumentLoader::replaceDocumentWhileExecutingJavaScriptURL can cause the Do
cumentLoader to get deref'ed and possible destroyed, | 358 // DocumentLoader::replaceDocumentWhileExecutingJavaScriptURL can cause the |
| 356 // so protect it with a RefPtr. | 359 // DocumentLoader to get deref'ed and possible destroyed, so protect it with a |
| 360 // RefPtr. |
| 357 DocumentLoader* documentLoader(m_frame->document()->loader()); | 361 DocumentLoader* documentLoader(m_frame->document()->loader()); |
| 358 | 362 |
| 359 UseCounter::count(*m_frame->document(), | 363 UseCounter::count(*m_frame->document(), |
| 360 UseCounter::ReplaceDocumentViaJavaScriptURL); | 364 UseCounter::ReplaceDocumentViaJavaScriptURL); |
| 361 | 365 |
| 362 // Prepare a DocumentInit before clearing the frame, because it may need to | 366 // Prepare a DocumentInit before clearing the frame, because it may need to |
| 363 // inherit an aliased security context. | 367 // inherit an aliased security context. |
| 364 DocumentInit init(ownerDocument, m_frame->document()->url(), m_frame); | 368 DocumentInit init(ownerDocument, m_frame->document()->url(), m_frame); |
| 365 init.withNewRegistrationContext(); | 369 init.withNewRegistrationContext(); |
| 366 | 370 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 else | 404 else |
| 401 m_currentItem = HistoryItem::create(); | 405 m_currentItem = HistoryItem::create(); |
| 402 m_currentItem->setURL(m_documentLoader->urlForHistory()); | 406 m_currentItem->setURL(m_documentLoader->urlForHistory()); |
| 403 m_currentItem->setDocumentState(m_frame->document()->formElementsState()); | 407 m_currentItem->setDocumentState(m_frame->document()->formElementsState()); |
| 404 m_currentItem->setTarget(m_frame->tree().uniqueName()); | 408 m_currentItem->setTarget(m_frame->tree().uniqueName()); |
| 405 m_currentItem->setReferrer(SecurityPolicy::generateReferrer( | 409 m_currentItem->setReferrer(SecurityPolicy::generateReferrer( |
| 406 m_documentLoader->request().getReferrerPolicy(), m_currentItem->url(), | 410 m_documentLoader->request().getReferrerPolicy(), m_currentItem->url(), |
| 407 m_documentLoader->request().httpReferrer())); | 411 m_documentLoader->request().httpReferrer())); |
| 408 m_currentItem->setFormInfoFromRequest(m_documentLoader->request()); | 412 m_currentItem->setFormInfoFromRequest(m_documentLoader->request()); |
| 409 | 413 |
| 410 // Don't propagate state from the old item to the new item if there isn't an o
ld item (obviously), | 414 // Don't propagate state from the old item to the new item if there isn't an |
| 411 // or if this is a back/forward navigation, since we explicitly want to restor
e the state we just | 415 // old item (obviously), or if this is a back/forward navigation, since we |
| 412 // committed. | 416 // explicitly want to restore the state we just committed. |
| 413 if (!oldItem || isBackForwardLoadType(loadType)) | 417 if (!oldItem || isBackForwardLoadType(loadType)) |
| 414 return; | 418 return; |
| 415 // Don't propagate state from the old item if this is a different-document nav
igation, unless the before | 419 // Don't propagate state from the old item if this is a different-document |
| 416 // and after pages are logically related. This means they have the same url (i
gnoring fragment) and | 420 // navigation, unless the before and after pages are logically related. This |
| 417 // the new item was loaded via reload or client redirect. | 421 // means they have the same url (ignoring fragment) and the new item was |
| 422 // loaded via reload or client redirect. |
| 418 if (navigationType == HistoryNavigationType::DifferentDocument && | 423 if (navigationType == HistoryNavigationType::DifferentDocument && |
| 419 (historyCommitType != HistoryInertCommit || | 424 (historyCommitType != HistoryInertCommit || |
| 420 !equalIgnoringFragmentIdentifier(oldItem->url(), m_currentItem->url()))) | 425 !equalIgnoringFragmentIdentifier(oldItem->url(), m_currentItem->url()))) |
| 421 return; | 426 return; |
| 422 m_currentItem->setDocumentSequenceNumber(oldItem->documentSequenceNumber()); | 427 m_currentItem->setDocumentSequenceNumber(oldItem->documentSequenceNumber()); |
| 423 m_currentItem->setScrollPoint(oldItem->scrollPoint()); | 428 m_currentItem->setScrollPoint(oldItem->scrollPoint()); |
| 424 m_currentItem->setVisualViewportScrollPoint( | 429 m_currentItem->setVisualViewportScrollPoint( |
| 425 oldItem->visualViewportScrollPoint()); | 430 oldItem->visualViewportScrollPoint()); |
| 426 m_currentItem->setPageScaleFactor(oldItem->pageScaleFactor()); | 431 m_currentItem->setPageScaleFactor(oldItem->pageScaleFactor()); |
| 427 m_currentItem->setScrollRestorationType(oldItem->scrollRestorationType()); | 432 m_currentItem->setScrollRestorationType(oldItem->scrollRestorationType()); |
| 428 | 433 |
| 429 // The item sequence number determines whether items are "the same", such back
/forward navigation | 434 // The item sequence number determines whether items are "the same", such |
| 430 // between items with the same item sequence number is a no-op. Only treat thi
s as identical if the | 435 // back/forward navigation between items with the same item sequence number is |
| 431 // navigation did not create a back/forward entry and the url is identical or
it was loaded via | 436 // a no-op. Only treat this as identical if the navigation did not create a |
| 437 // back/forward entry and the url is identical or it was loaded via |
| 432 // history.replaceState(). | 438 // history.replaceState(). |
| 433 if (historyCommitType == HistoryInertCommit && | 439 if (historyCommitType == HistoryInertCommit && |
| 434 (navigationType == HistoryNavigationType::HistoryApi || | 440 (navigationType == HistoryNavigationType::HistoryApi || |
| 435 oldItem->url() == m_currentItem->url())) { | 441 oldItem->url() == m_currentItem->url())) { |
| 436 m_currentItem->setStateObject(oldItem->stateObject()); | 442 m_currentItem->setStateObject(oldItem->stateObject()); |
| 437 m_currentItem->setItemSequenceNumber(oldItem->itemSequenceNumber()); | 443 m_currentItem->setItemSequenceNumber(oldItem->itemSequenceNumber()); |
| 438 } | 444 } |
| 439 } | 445 } |
| 440 | 446 |
| 441 static HistoryCommitType loadTypeToCommitType(FrameLoadType type) { | 447 static HistoryCommitType loadTypeToCommitType(FrameLoadType type) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 468 | 474 |
| 469 if (!m_stateMachine.committedMultipleRealLoads() && | 475 if (!m_stateMachine.committedMultipleRealLoads() && |
| 470 m_loadType == FrameLoadTypeStandard) | 476 m_loadType == FrameLoadTypeStandard) |
| 471 m_stateMachine.advanceTo( | 477 m_stateMachine.advanceTo( |
| 472 FrameLoaderStateMachine::CommittedMultipleRealLoads); | 478 FrameLoaderStateMachine::CommittedMultipleRealLoads); |
| 473 | 479 |
| 474 client()->dispatchDidCommitLoad(m_currentItem.get(), historyCommitType); | 480 client()->dispatchDidCommitLoad(m_currentItem.get(), historyCommitType); |
| 475 | 481 |
| 476 // When the embedder gets notified (above) that the new navigation has | 482 // When the embedder gets notified (above) that the new navigation has |
| 477 // committed, the embedder will drop the old Content Security Policy and | 483 // committed, the embedder will drop the old Content Security Policy and |
| 478 // therefore now is a good time to report to the embedder the Content | 484 // therefore now is a good time to report to the embedder the Content Security |
| 479 // Security Policies that have accumulated so far for the new navigation. | 485 // Policies that have accumulated so far for the new navigation. |
| 480 m_frame->securityContext()->contentSecurityPolicy()->reportAccumulatedHeaders( | 486 m_frame->securityContext()->contentSecurityPolicy()->reportAccumulatedHeaders( |
| 481 client()); | 487 client()); |
| 482 | 488 |
| 483 // didObserveLoadingBehavior() must be called after dispatchDidCommitLoad() is
called for the metrics tracking logic to handle it properly. | 489 // didObserveLoadingBehavior() must be called after dispatchDidCommitLoad() is |
| 490 // called for the metrics tracking logic to handle it properly. |
| 484 if (client()->isControlledByServiceWorker(*m_documentLoader)) | 491 if (client()->isControlledByServiceWorker(*m_documentLoader)) |
| 485 client()->didObserveLoadingBehavior( | 492 client()->didObserveLoadingBehavior( |
| 486 WebLoadingBehaviorServiceWorkerControlled); | 493 WebLoadingBehaviorServiceWorkerControlled); |
| 487 | 494 |
| 488 // Links with media values need more information (like viewport | 495 // Links with media values need more information (like viewport information). |
| 489 // information). This happens after the first chunk is parsed in | 496 // This happens after the first chunk is parsed in HTMLDocumentParser. |
| 490 // HTMLDocumentParser. | |
| 491 m_documentLoader->dispatchLinkHeaderPreloads(nullptr, | 497 m_documentLoader->dispatchLinkHeaderPreloads(nullptr, |
| 492 LinkLoader::OnlyLoadNonMedia); | 498 LinkLoader::OnlyLoadNonMedia); |
| 493 | 499 |
| 494 TRACE_EVENT1("devtools.timeline", "CommitLoad", "data", | 500 TRACE_EVENT1("devtools.timeline", "CommitLoad", "data", |
| 495 InspectorCommitLoadEvent::data(m_frame)); | 501 InspectorCommitLoadEvent::data(m_frame)); |
| 496 InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get()); | 502 InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get()); |
| 497 m_frame->page()->didCommitLoad(m_frame); | 503 m_frame->page()->didCommitLoad(m_frame); |
| 498 dispatchDidClearDocumentOfWindowObject(); | 504 dispatchDidClearDocumentOfWindowObject(); |
| 499 | 505 |
| 500 takeObjectSnapshot(); | 506 takeObjectSnapshot(); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 | 604 |
| 599 if (client()) | 605 if (client()) |
| 600 client()->runScriptsAtDocumentReady( | 606 client()->runScriptsAtDocumentReady( |
| 601 m_documentLoader ? m_documentLoader->isCommittedButEmpty() : true); | 607 m_documentLoader ? m_documentLoader->isCommittedButEmpty() : true); |
| 602 | 608 |
| 603 checkCompleted(); | 609 checkCompleted(); |
| 604 | 610 |
| 605 if (!m_frame->view()) | 611 if (!m_frame->view()) |
| 606 return; // We are being destroyed by something checkCompleted called. | 612 return; // We are being destroyed by something checkCompleted called. |
| 607 | 613 |
| 608 // Check if the scrollbars are really needed for the content. | 614 // Check if the scrollbars are really needed for the content. If not, remove |
| 609 // If not, remove them, relayout, and repaint. | 615 // them, relayout, and repaint. |
| 610 m_frame->view()->restoreScrollbar(); | 616 m_frame->view()->restoreScrollbar(); |
| 611 processFragment(m_frame->document()->url(), NavigationToDifferentDocument); | 617 processFragment(m_frame->document()->url(), NavigationToDifferentDocument); |
| 612 } | 618 } |
| 613 | 619 |
| 614 static bool allDescendantsAreComplete(Frame* frame) { | 620 static bool allDescendantsAreComplete(Frame* frame) { |
| 615 for (Frame* child = frame->tree().firstChild(); child; | 621 for (Frame* child = frame->tree().firstChild(); child; |
| 616 child = child->tree().traverseNext(frame)) { | 622 child = child->tree().traverseNext(frame)) { |
| 617 if (child->isLoading()) | 623 if (child->isLoading()) |
| 618 return false; | 624 return false; |
| 619 } | 625 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 637 if (!document->haveImportsLoaded()) | 643 if (!document->haveImportsLoaded()) |
| 638 return false; | 644 return false; |
| 639 if (document->fetcher()->requestCount()) | 645 if (document->fetcher()->requestCount()) |
| 640 return false; | 646 return false; |
| 641 if (document->isDelayingLoadEvent()) | 647 if (document->isDelayingLoadEvent()) |
| 642 return false; | 648 return false; |
| 643 return allDescendantsAreComplete(document->frame()); | 649 return allDescendantsAreComplete(document->frame()); |
| 644 } | 650 } |
| 645 | 651 |
| 646 static bool shouldSendFinishNotification(LocalFrame* frame) { | 652 static bool shouldSendFinishNotification(LocalFrame* frame) { |
| 647 // Don't send stop notifications for inital empty documents, since they don't
generate start notifications. | 653 // Don't send stop notifications for inital empty documents, since they don't |
| 654 // generate start notifications. |
| 648 if (!frame->loader().stateMachine()->committedFirstRealDocumentLoad()) | 655 if (!frame->loader().stateMachine()->committedFirstRealDocumentLoad()) |
| 649 return false; | 656 return false; |
| 650 | 657 |
| 651 // Don't send didFinishLoad more than once per DocumentLoader. | 658 // Don't send didFinishLoad more than once per DocumentLoader. |
| 652 if (frame->loader().documentLoader()->sentDidFinishLoad()) | 659 if (frame->loader().documentLoader()->sentDidFinishLoad()) |
| 653 return false; | 660 return false; |
| 654 | 661 |
| 655 // We might have declined to run the load event due to an imminent content-ini
tiated navigation. | 662 // We might have declined to run the load event due to an imminent |
| 663 // content-initiated navigation. |
| 656 if (!frame->document()->loadEventFinished()) | 664 if (!frame->document()->loadEventFinished()) |
| 657 return false; | 665 return false; |
| 658 | 666 |
| 659 // An event might have restarted a child frame. | 667 // An event might have restarted a child frame. |
| 660 if (!allDescendantsAreComplete(frame)) | 668 if (!allDescendantsAreComplete(frame)) |
| 661 return false; | 669 return false; |
| 662 return true; | 670 return true; |
| 663 } | 671 } |
| 664 | 672 |
| 665 static bool shouldSendCompleteNotification(LocalFrame* frame, | 673 static bool shouldSendCompleteNotification(LocalFrame* frame, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 686 m_frame->navigationScheduler().startTimer(); | 694 m_frame->navigationScheduler().startTimer(); |
| 687 | 695 |
| 688 if (m_frame->view()) | 696 if (m_frame->view()) |
| 689 m_frame->view()->handleLoadCompleted(); | 697 m_frame->view()->handleLoadCompleted(); |
| 690 | 698 |
| 691 // The readystatechanged or load event may have disconnected this frame. | 699 // The readystatechanged or load event may have disconnected this frame. |
| 692 if (!m_frame->client()) | 700 if (!m_frame->client()) |
| 693 return; | 701 return; |
| 694 | 702 |
| 695 if (shouldSendFinishNotification(m_frame)) { | 703 if (shouldSendFinishNotification(m_frame)) { |
| 696 // Report mobile vs. desktop page statistics. This will only report on Andro
id. | 704 // Report mobile vs. desktop page statistics. This will only report on |
| 705 // Android. |
| 697 if (m_frame->isMainFrame()) | 706 if (m_frame->isMainFrame()) |
| 698 m_frame->document()->viewportDescription().reportMobilePageStats(m_frame); | 707 m_frame->document()->viewportDescription().reportMobilePageStats(m_frame); |
| 699 m_documentLoader->setSentDidFinishLoad(); | 708 m_documentLoader->setSentDidFinishLoad(); |
| 700 client()->dispatchDidFinishLoad(); | 709 client()->dispatchDidFinishLoad(); |
| 701 // Finishing the load can detach the frame when running layout tests. | 710 // Finishing the load can detach the frame when running layout tests. |
| 702 if (!m_frame->client()) | 711 if (!m_frame->client()) |
| 703 return; | 712 return; |
| 704 } | 713 } |
| 705 | 714 |
| 706 if (shouldSendCompleteNotification(m_frame, m_isNavigationHandledByClient)) { | 715 if (shouldSendCompleteNotification(m_frame, m_isNavigationHandledByClient)) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 735 return client() ? client()->opener() : 0; | 744 return client() ? client()->opener() : 0; |
| 736 } | 745 } |
| 737 | 746 |
| 738 void FrameLoader::setOpener(LocalFrame* opener) { | 747 void FrameLoader::setOpener(LocalFrame* opener) { |
| 739 // If the frame is already detached, the opener has already been cleared. | 748 // If the frame is already detached, the opener has already been cleared. |
| 740 if (client()) | 749 if (client()) |
| 741 client()->setOpener(opener); | 750 client()->setOpener(opener); |
| 742 } | 751 } |
| 743 | 752 |
| 744 bool FrameLoader::allowPlugins(ReasonForCallingAllowPlugins reason) { | 753 bool FrameLoader::allowPlugins(ReasonForCallingAllowPlugins reason) { |
| 745 // With Oilpan, a FrameLoader might be accessed after the | 754 // With Oilpan, a FrameLoader might be accessed after the FrameHost has been |
| 746 // FrameHost has been detached. FrameClient will not be | 755 // detached. FrameClient will not be accessible, so bail early. |
| 747 // accessible, so bail early. | |
| 748 if (!client()) | 756 if (!client()) |
| 749 return false; | 757 return false; |
| 750 Settings* settings = m_frame->settings(); | 758 Settings* settings = m_frame->settings(); |
| 751 bool allowed = client()->allowPlugins(settings && settings->pluginsEnabled()); | 759 bool allowed = client()->allowPlugins(settings && settings->pluginsEnabled()); |
| 752 if (!allowed && reason == AboutToInstantiatePlugin) | 760 if (!allowed && reason == AboutToInstantiatePlugin) |
| 753 client()->didNotAllowPlugins(); | 761 client()->didNotAllowPlugins(); |
| 754 return allowed; | 762 return allowed; |
| 755 } | 763 } |
| 756 | 764 |
| 757 void FrameLoader::updateForSameDocumentNavigation( | 765 void FrameLoader::updateForSameDocumentNavigation( |
| 758 const KURL& newURL, | 766 const KURL& newURL, |
| 759 SameDocumentNavigationSource sameDocumentNavigationSource, | 767 SameDocumentNavigationSource sameDocumentNavigationSource, |
| 760 PassRefPtr<SerializedScriptValue> data, | 768 PassRefPtr<SerializedScriptValue> data, |
| 761 HistoryScrollRestorationType scrollRestorationType, | 769 HistoryScrollRestorationType scrollRestorationType, |
| 762 FrameLoadType type, | 770 FrameLoadType type, |
| 763 Document* initiatingDocument) { | 771 Document* initiatingDocument) { |
| 764 // Update the data source's request with the new URL to fake the URL change | 772 // Update the data source's request with the new URL to fake the URL change |
| 765 m_frame->document()->setURL(newURL); | 773 m_frame->document()->setURL(newURL); |
| 766 documentLoader()->setReplacesCurrentHistoryItem(type != | 774 documentLoader()->setReplacesCurrentHistoryItem(type != |
| 767 FrameLoadTypeStandard); | 775 FrameLoadTypeStandard); |
| 768 documentLoader()->updateForSameDocumentNavigation( | 776 documentLoader()->updateForSameDocumentNavigation( |
| 769 newURL, sameDocumentNavigationSource); | 777 newURL, sameDocumentNavigationSource); |
| 770 | 778 |
| 771 // Generate start and stop notifications only when loader is completed so that
we | 779 // Generate start and stop notifications only when loader is completed so that |
| 772 // don't fire them for fragment redirection that happens in window.onload hand
ler. | 780 // we don't fire them for fragment redirection that happens in window.onload |
| 773 // See https://bugs.webkit.org/show_bug.cgi?id=31838 | 781 // handler. See https://bugs.webkit.org/show_bug.cgi?id=31838 |
| 774 if (m_frame->document()->loadEventFinished()) | 782 if (m_frame->document()->loadEventFinished()) |
| 775 client()->didStartLoading(NavigationWithinSameDocument); | 783 client()->didStartLoading(NavigationWithinSameDocument); |
| 776 | 784 |
| 777 HistoryCommitType historyCommitType = loadTypeToCommitType(type); | 785 HistoryCommitType historyCommitType = loadTypeToCommitType(type); |
| 778 if (!m_currentItem) | 786 if (!m_currentItem) |
| 779 historyCommitType = HistoryInertCommit; | 787 historyCommitType = HistoryInertCommit; |
| 780 if (m_frame->settings()->historyEntryRequiresUserGesture() && | 788 if (m_frame->settings()->historyEntryRequiresUserGesture() && |
| 781 !UserGestureIndicator::processedUserGestureSinceLoad() && | 789 !UserGestureIndicator::processedUserGestureSinceLoad() && |
| 782 initiatingDocument) | 790 initiatingDocument) |
| 783 historyCommitType = HistoryInertCommit; | 791 historyCommitType = HistoryInertCommit; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 810 void FrameLoader::loadInSameDocument( | 818 void FrameLoader::loadInSameDocument( |
| 811 const KURL& url, | 819 const KURL& url, |
| 812 PassRefPtr<SerializedScriptValue> stateObject, | 820 PassRefPtr<SerializedScriptValue> stateObject, |
| 813 FrameLoadType frameLoadType, | 821 FrameLoadType frameLoadType, |
| 814 HistoryLoadType historyLoadType, | 822 HistoryLoadType historyLoadType, |
| 815 ClientRedirectPolicy clientRedirect, | 823 ClientRedirectPolicy clientRedirect, |
| 816 Document* initiatingDocument) { | 824 Document* initiatingDocument) { |
| 817 // If we have a state object, we cannot also be a new navigation. | 825 // If we have a state object, we cannot also be a new navigation. |
| 818 DCHECK(!stateObject || frameLoadType == FrameLoadTypeBackForward); | 826 DCHECK(!stateObject || frameLoadType == FrameLoadTypeBackForward); |
| 819 | 827 |
| 820 // If we have a provisional request for a different document, a fragment scrol
l should cancel it. | 828 // If we have a provisional request for a different document, a fragment |
| 829 // scroll should cancel it. |
| 821 detachDocumentLoader(m_provisionalDocumentLoader); | 830 detachDocumentLoader(m_provisionalDocumentLoader); |
| 822 if (!m_frame->host()) | 831 if (!m_frame->host()) |
| 823 return; | 832 return; |
| 824 AutoReset<FrameLoadType> loadTypeChange(&m_loadType, frameLoadType); | 833 AutoReset<FrameLoadType> loadTypeChange(&m_loadType, frameLoadType); |
| 825 saveScrollState(); | 834 saveScrollState(); |
| 826 | 835 |
| 827 KURL oldURL = m_frame->document()->url(); | 836 KURL oldURL = m_frame->document()->url(); |
| 828 bool hashChange = equalIgnoringFragmentIdentifier(url, oldURL) && | 837 bool hashChange = equalIgnoringFragmentIdentifier(url, oldURL) && |
| 829 url.fragmentIdentifier() != oldURL.fragmentIdentifier(); | 838 url.fragmentIdentifier() != oldURL.fragmentIdentifier(); |
| 830 if (hashChange) { | 839 if (hashChange) { |
| 831 // If we were in the autoscroll/middleClickAutoscroll mode we want to stop i
t before following the link to the anchor | 840 // If we were in the autoscroll/middleClickAutoscroll mode we want to stop |
| 841 // it before following the link to the anchor |
| 832 m_frame->eventHandler().stopAutoscroll(); | 842 m_frame->eventHandler().stopAutoscroll(); |
| 833 m_frame->localDOMWindow()->enqueueHashchangeEvent(oldURL, url); | 843 m_frame->localDOMWindow()->enqueueHashchangeEvent(oldURL, url); |
| 834 } | 844 } |
| 835 m_documentLoader->setIsClientRedirect(clientRedirect == | 845 m_documentLoader->setIsClientRedirect(clientRedirect == |
| 836 ClientRedirectPolicy::ClientRedirect); | 846 ClientRedirectPolicy::ClientRedirect); |
| 837 updateForSameDocumentNavigation(url, SameDocumentNavigationDefault, nullptr, | 847 updateForSameDocumentNavigation(url, SameDocumentNavigationDefault, nullptr, |
| 838 ScrollRestorationAuto, frameLoadType, | 848 ScrollRestorationAuto, frameLoadType, |
| 839 initiatingDocument); | 849 initiatingDocument); |
| 840 | 850 |
| 841 m_documentLoader->initialScrollState().wasScrolledByUser = false; | 851 m_documentLoader->initialScrollState().wasScrolledByUser = false; |
| 842 | 852 |
| 843 checkCompleted(); | 853 checkCompleted(); |
| 844 | 854 |
| 845 m_frame->localDOMWindow()->statePopped( | 855 m_frame->localDOMWindow()->statePopped( |
| 846 stateObject ? std::move(stateObject) | 856 stateObject ? std::move(stateObject) |
| 847 : SerializedScriptValue::nullValue()); | 857 : SerializedScriptValue::nullValue()); |
| 848 | 858 |
| 849 if (historyLoadType == HistorySameDocumentLoad) | 859 if (historyLoadType == HistorySameDocumentLoad) |
| 850 restoreScrollPositionAndViewState(); | 860 restoreScrollPositionAndViewState(); |
| 851 | 861 |
| 852 // We need to scroll to the fragment whether or not a hash change occurred, si
nce | 862 // We need to scroll to the fragment whether or not a hash change occurred, |
| 853 // the user might have scrolled since the previous navigation. | 863 // since the user might have scrolled since the previous navigation. |
| 854 processFragment(url, NavigationWithinSameDocument); | 864 processFragment(url, NavigationWithinSameDocument); |
| 855 takeObjectSnapshot(); | 865 takeObjectSnapshot(); |
| 856 } | 866 } |
| 857 | 867 |
| 858 // static | 868 // static |
| 859 void FrameLoader::setReferrerForFrameRequest(FrameLoadRequest& frameRequest) { | 869 void FrameLoader::setReferrerForFrameRequest(FrameLoadRequest& frameRequest) { |
| 860 ResourceRequest& request = frameRequest.resourceRequest(); | 870 ResourceRequest& request = frameRequest.resourceRequest(); |
| 861 Document* originDocument = frameRequest.originDocument(); | 871 Document* originDocument = frameRequest.originDocument(); |
| 862 | 872 |
| 863 if (!originDocument) | 873 if (!originDocument) |
| 864 return; | 874 return; |
| 865 // Anchor elements with the 'referrerpolicy' attribute will have | 875 // Anchor elements with the 'referrerpolicy' attribute will have already set |
| 866 // already set the referrer on the request. | 876 // the referrer on the request. |
| 867 if (request.didSetHTTPReferrer()) | 877 if (request.didSetHTTPReferrer()) |
| 868 return; | 878 return; |
| 869 if (frameRequest.getShouldSendReferrer() == NeverSendReferrer) | 879 if (frameRequest.getShouldSendReferrer() == NeverSendReferrer) |
| 870 return; | 880 return; |
| 871 | 881 |
| 872 // Always use the initiating document to generate the referrer. | 882 // Always use the initiating document to generate the referrer. We need to |
| 873 // We need to generateReferrer(), because we haven't enforced ReferrerPolicy o
r https->http | 883 // generateReferrer(), because we haven't enforced ReferrerPolicy or |
| 874 // referrer suppression yet. | 884 // https->http referrer suppression yet. |
| 875 Referrer referrer = SecurityPolicy::generateReferrer( | 885 Referrer referrer = SecurityPolicy::generateReferrer( |
| 876 originDocument->getReferrerPolicy(), request.url(), | 886 originDocument->getReferrerPolicy(), request.url(), |
| 877 originDocument->outgoingReferrer()); | 887 originDocument->outgoingReferrer()); |
| 878 | 888 |
| 879 request.setHTTPReferrer(referrer); | 889 request.setHTTPReferrer(referrer); |
| 880 RefPtr<SecurityOrigin> referrerOrigin = | 890 RefPtr<SecurityOrigin> referrerOrigin = |
| 881 SecurityOrigin::createFromString(referrer.referrer); | 891 SecurityOrigin::createFromString(referrer.referrer); |
| 882 request.addHTTPOriginIfNeeded(referrerOrigin.get()); | 892 request.addHTTPOriginIfNeeded(referrerOrigin.get()); |
| 883 } | 893 } |
| 884 | 894 |
| 885 FrameLoadType FrameLoader::determineFrameLoadType( | 895 FrameLoadType FrameLoader::determineFrameLoadType( |
| 886 const FrameLoadRequest& request) { | 896 const FrameLoadRequest& request) { |
| 887 if (m_frame->tree().parent() && | 897 if (m_frame->tree().parent() && |
| 888 !m_stateMachine.committedFirstRealDocumentLoad()) | 898 !m_stateMachine.committedFirstRealDocumentLoad()) |
| 889 return FrameLoadTypeInitialInChildFrame; | 899 return FrameLoadTypeInitialInChildFrame; |
| 890 if (!m_frame->tree().parent() && !client()->backForwardLength()) | 900 if (!m_frame->tree().parent() && !client()->backForwardLength()) |
| 891 return FrameLoadTypeStandard; | 901 return FrameLoadTypeStandard; |
| 892 if (m_provisionalDocumentLoader && | 902 if (m_provisionalDocumentLoader && |
| 893 request.substituteData().failingURL() == | 903 request.substituteData().failingURL() == |
| 894 m_provisionalDocumentLoader->url() && | 904 m_provisionalDocumentLoader->url() && |
| 895 m_loadType == FrameLoadTypeBackForward) | 905 m_loadType == FrameLoadTypeBackForward) |
| 896 return FrameLoadTypeBackForward; | 906 return FrameLoadTypeBackForward; |
| 897 if (request.resourceRequest().getCachePolicy() == | 907 if (request.resourceRequest().getCachePolicy() == |
| 898 WebCachePolicy::ValidatingCacheData) | 908 WebCachePolicy::ValidatingCacheData) |
| 899 return FrameLoadTypeReload; | 909 return FrameLoadTypeReload; |
| 900 if (request.resourceRequest().getCachePolicy() == | 910 if (request.resourceRequest().getCachePolicy() == |
| 901 WebCachePolicy::BypassingCache) | 911 WebCachePolicy::BypassingCache) |
| 902 return FrameLoadTypeReloadBypassingCache; | 912 return FrameLoadTypeReloadBypassingCache; |
| 903 // From the HTML5 spec for location.assign(): | 913 // From the HTML5 spec for location.assign(): |
| 904 // "If the browsing context's session history contains only one Document, | 914 // "If the browsing context's session history contains only one Document, |
| 905 // and that was the about:blank Document created when the browsing context | 915 // and that was the about:blank Document created when the browsing context |
| 906 // was created, then the navigation must be done with replacement enabled." | 916 // was created, then the navigation must be done with replacement enabled." |
| 907 if (request.replacesCurrentItem() || | 917 if (request.replacesCurrentItem() || |
| 908 (!m_stateMachine.committedMultipleRealLoads() && | 918 (!m_stateMachine.committedMultipleRealLoads() && |
| 909 equalIgnoringCase(m_frame->document()->url(), blankURL()))) | 919 equalIgnoringCase(m_frame->document()->url(), blankURL()))) |
| 910 return FrameLoadTypeReplaceCurrentItem; | 920 return FrameLoadTypeReplaceCurrentItem; |
| 911 | 921 |
| 912 if (request.resourceRequest().url() == m_documentLoader->urlForHistory()) { | 922 if (request.resourceRequest().url() == m_documentLoader->urlForHistory()) { |
| 913 if (!request.originDocument()) | 923 if (!request.originDocument()) |
| 914 return FrameLoadTypeReloadMainResource; | 924 return FrameLoadTypeReloadMainResource; |
| 915 return request.resourceRequest().httpMethod() == HTTPNames::POST | 925 return request.resourceRequest().httpMethod() == HTTPNames::POST |
| 916 ? FrameLoadTypeStandard | 926 ? FrameLoadTypeStandard |
| 917 : FrameLoadTypeReplaceCurrentItem; | 927 : FrameLoadTypeReplaceCurrentItem; |
| 918 } | 928 } |
| 919 | 929 |
| 920 if (request.substituteData().failingURL() == | 930 if (request.substituteData().failingURL() == |
| 921 m_documentLoader->urlForHistory() && | 931 m_documentLoader->urlForHistory() && |
| 922 m_loadType == FrameLoadTypeReload) | 932 m_loadType == FrameLoadTypeReload) |
| 923 return FrameLoadTypeReload; | 933 return FrameLoadTypeReload; |
| 924 | 934 |
| 925 if (m_frame->settings()->historyEntryRequiresUserGesture() && | 935 if (m_frame->settings()->historyEntryRequiresUserGesture() && |
| 926 !UserGestureIndicator::processedUserGestureSinceLoad() && | 936 !UserGestureIndicator::processedUserGestureSinceLoad() && |
| 927 request.originDocument()) | 937 request.originDocument()) |
| 928 return FrameLoadTypeReplaceCurrentItem; | 938 return FrameLoadTypeReplaceCurrentItem; |
| 929 | 939 |
| 930 return FrameLoadTypeStandard; | 940 return FrameLoadTypeStandard; |
| 931 } | 941 } |
| 932 | 942 |
| 933 bool FrameLoader::prepareRequestForThisFrame(FrameLoadRequest& request) { | 943 bool FrameLoader::prepareRequestForThisFrame(FrameLoadRequest& request) { |
| 934 // If no origin Document* was specified, skip remaining security checks and as
sume the caller has fully initialized the FrameLoadRequest. | 944 // If no origin Document* was specified, skip remaining security checks and |
| 945 // assume the caller has fully initialized the FrameLoadRequest. |
| 935 if (!request.originDocument()) | 946 if (!request.originDocument()) |
| 936 return true; | 947 return true; |
| 937 | 948 |
| 938 KURL url = request.resourceRequest().url(); | 949 KURL url = request.resourceRequest().url(); |
| 939 if (m_frame->script().executeScriptIfJavaScriptURL(url)) | 950 if (m_frame->script().executeScriptIfJavaScriptURL(url)) |
| 940 return false; | 951 return false; |
| 941 | 952 |
| 942 if (!request.originDocument()->getSecurityOrigin()->canDisplay(url)) { | 953 if (!request.originDocument()->getSecurityOrigin()->canDisplay(url)) { |
| 943 reportLocalLoadFailed(m_frame, url.elidedString()); | 954 reportLocalLoadFailed(m_frame, url.elidedString()); |
| 944 return false; | 955 return false; |
| 945 } | 956 } |
| 946 | 957 |
| 947 if (!request.form() && request.frameName().isEmpty()) | 958 if (!request.form() && request.frameName().isEmpty()) |
| 948 request.setFrameName(m_frame->document()->baseTarget()); | 959 request.setFrameName(m_frame->document()->baseTarget()); |
| 949 return true; | 960 return true; |
| 950 } | 961 } |
| 951 | 962 |
| 952 static bool shouldOpenInNewWindow(Frame* targetFrame, | 963 static bool shouldOpenInNewWindow(Frame* targetFrame, |
| 953 const FrameLoadRequest& request, | 964 const FrameLoadRequest& request, |
| 954 NavigationPolicy policy) { | 965 NavigationPolicy policy) { |
| 955 if (!targetFrame && !request.frameName().isEmpty()) | 966 if (!targetFrame && !request.frameName().isEmpty()) |
| 956 return true; | 967 return true; |
| 957 // FIXME: This case is a workaround for the fact that ctrl+clicking a form sub
mission incorrectly | 968 // FIXME: This case is a workaround for the fact that ctrl+clicking a form |
| 958 // sends as a GET rather than a POST if it creates a new window in a different
process. | 969 // submission incorrectly sends as a GET rather than a POST if it creates a |
| 970 // new window in a different process. |
| 959 return request.form() && policy != NavigationPolicyCurrentTab; | 971 return request.form() && policy != NavigationPolicyCurrentTab; |
| 960 } | 972 } |
| 961 | 973 |
| 962 static NavigationType determineNavigationType(FrameLoadType frameLoadType, | 974 static NavigationType determineNavigationType(FrameLoadType frameLoadType, |
| 963 bool isFormSubmission, | 975 bool isFormSubmission, |
| 964 bool haveEvent) { | 976 bool haveEvent) { |
| 965 bool isReload = isReloadLoadType(frameLoadType); | 977 bool isReload = isReloadLoadType(frameLoadType); |
| 966 bool isBackForward = isBackForwardLoadType(frameLoadType); | 978 bool isBackForward = isBackForwardLoadType(frameLoadType); |
| 967 if (isFormSubmission) | 979 if (isFormSubmission) |
| 968 return (isReload || isBackForward) ? NavigationTypeFormResubmitted | 980 return (isReload || isBackForward) ? NavigationTypeFormResubmitted |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 frame->document()->addConsoleMessage( | 1155 frame->document()->addConsoleMessage( |
| 1144 ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, | 1156 ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, |
| 1145 "Not allowed to load local resource: " + url)); | 1157 "Not allowed to load local resource: " + url)); |
| 1146 } | 1158 } |
| 1147 | 1159 |
| 1148 void FrameLoader::stopAllLoaders() { | 1160 void FrameLoader::stopAllLoaders() { |
| 1149 if (m_frame->document()->pageDismissalEventBeingDispatched() != | 1161 if (m_frame->document()->pageDismissalEventBeingDispatched() != |
| 1150 Document::NoDismissal) | 1162 Document::NoDismissal) |
| 1151 return; | 1163 return; |
| 1152 | 1164 |
| 1153 // If this method is called from within this method, infinite recursion can oc
cur (3442218). Avoid this. | 1165 // If this method is called from within this method, infinite recursion can |
| 1166 // occur (3442218). Avoid this. |
| 1154 if (m_inStopAllLoaders) | 1167 if (m_inStopAllLoaders) |
| 1155 return; | 1168 return; |
| 1156 | 1169 |
| 1157 m_inStopAllLoaders = true; | 1170 m_inStopAllLoaders = true; |
| 1158 | 1171 |
| 1159 m_isNavigationHandledByClient = false; | 1172 m_isNavigationHandledByClient = false; |
| 1160 | 1173 |
| 1161 for (Frame* child = m_frame->tree().firstChild(); child; | 1174 for (Frame* child = m_frame->tree().firstChild(); child; |
| 1162 child = child->tree().nextSibling()) { | 1175 child = child->tree().nextSibling()) { |
| 1163 if (child->isLocalFrame()) | 1176 if (child->isLocalFrame()) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1181 loadFailed(m_documentLoader.get(), | 1194 loadFailed(m_documentLoader.get(), |
| 1182 ResourceError::cancelledError(m_documentLoader->url())); | 1195 ResourceError::cancelledError(m_documentLoader->url())); |
| 1183 | 1196 |
| 1184 m_inStopAllLoaders = false; | 1197 m_inStopAllLoaders = false; |
| 1185 takeObjectSnapshot(); | 1198 takeObjectSnapshot(); |
| 1186 } | 1199 } |
| 1187 | 1200 |
| 1188 void FrameLoader::didAccessInitialDocument() { | 1201 void FrameLoader::didAccessInitialDocument() { |
| 1189 // We only need to notify the client for the main frame. | 1202 // We only need to notify the client for the main frame. |
| 1190 if (isLoadingMainFrame()) { | 1203 if (isLoadingMainFrame()) { |
| 1191 // Forbid script execution to prevent re-entering V8, since this is | 1204 // Forbid script execution to prevent re-entering V8, since this is called |
| 1192 // called from a binding security check. | 1205 // from a binding security check. |
| 1193 ScriptForbiddenScope forbidScripts; | 1206 ScriptForbiddenScope forbidScripts; |
| 1194 if (client()) | 1207 if (client()) |
| 1195 client()->didAccessInitialDocument(); | 1208 client()->didAccessInitialDocument(); |
| 1196 } | 1209 } |
| 1197 } | 1210 } |
| 1198 | 1211 |
| 1199 bool FrameLoader::prepareForCommit() { | 1212 bool FrameLoader::prepareForCommit() { |
| 1200 PluginScriptForbiddenScope forbidPluginDestructorScripting; | 1213 PluginScriptForbiddenScope forbidPluginDestructorScripting; |
| 1201 DocumentLoader* pdl = m_provisionalDocumentLoader; | 1214 DocumentLoader* pdl = m_provisionalDocumentLoader; |
| 1202 | 1215 |
| 1203 if (m_frame->document()) { | 1216 if (m_frame->document()) { |
| 1204 unsigned nodeCount = 0; | 1217 unsigned nodeCount = 0; |
| 1205 for (Frame* frame = m_frame; frame; frame = frame->tree().traverseNext()) { | 1218 for (Frame* frame = m_frame; frame; frame = frame->tree().traverseNext()) { |
| 1206 if (frame->isLocalFrame()) { | 1219 if (frame->isLocalFrame()) { |
| 1207 LocalFrame* localFrame = toLocalFrame(frame); | 1220 LocalFrame* localFrame = toLocalFrame(frame); |
| 1208 nodeCount += localFrame->document()->nodeCount(); | 1221 nodeCount += localFrame->document()->nodeCount(); |
| 1209 } | 1222 } |
| 1210 } | 1223 } |
| 1211 unsigned totalNodeCount = | 1224 unsigned totalNodeCount = |
| 1212 InstanceCounters::counterValue(InstanceCounters::NodeCounter); | 1225 InstanceCounters::counterValue(InstanceCounters::NodeCounter); |
| 1213 float ratio = static_cast<float>(nodeCount) / totalNodeCount; | 1226 float ratio = static_cast<float>(nodeCount) / totalNodeCount; |
| 1214 ThreadState::current()->schedulePageNavigationGCIfNeeded(ratio); | 1227 ThreadState::current()->schedulePageNavigationGCIfNeeded(ratio); |
| 1215 } | 1228 } |
| 1216 | 1229 |
| 1217 // Don't allow any new child frames to load in this frame: attaching a new | 1230 // Don't allow any new child frames to load in this frame: attaching a new |
| 1218 // child frame during or after detaching children results in an attached | 1231 // child frame during or after detaching children results in an attached frame |
| 1219 // frame on a detached DOM tree, which is bad. | 1232 // on a detached DOM tree, which is bad. |
| 1220 SubframeLoadingDisabler disabler(m_frame->document()); | 1233 SubframeLoadingDisabler disabler(m_frame->document()); |
| 1221 if (m_documentLoader) { | 1234 if (m_documentLoader) { |
| 1222 client()->dispatchWillCommitProvisionalLoad(); | 1235 client()->dispatchWillCommitProvisionalLoad(); |
| 1223 dispatchUnloadEvent(); | 1236 dispatchUnloadEvent(); |
| 1224 } | 1237 } |
| 1225 m_frame->detachChildren(); | 1238 m_frame->detachChildren(); |
| 1226 // The previous calls to dispatchUnloadEvent() and detachChildren() can | 1239 // The previous calls to dispatchUnloadEvent() and detachChildren() can |
| 1227 // execute arbitrary script via things like unload events. If the executed | 1240 // execute arbitrary script via things like unload events. If the executed |
| 1228 // script intiates a new load or causes the current frame to be detached, | 1241 // script intiates a new load or causes the current frame to be detached, we |
| 1229 // we need to abandon the current load. | 1242 // need to abandon the current load. |
| 1230 if (pdl != m_provisionalDocumentLoader) | 1243 if (pdl != m_provisionalDocumentLoader) |
| 1231 return false; | 1244 return false; |
| 1232 // detachFromFrame() will abort XHRs that haven't completed, which can | 1245 // detachFromFrame() will abort XHRs that haven't completed, which can trigger |
| 1233 // trigger event listeners for 'abort'. These event listeners might call | 1246 // event listeners for 'abort'. These event listeners might call |
| 1234 // window.stop(), which will in turn detach the provisional document loader. | 1247 // window.stop(), which will in turn detach the provisional document loader. |
| 1235 // At this point, the provisional document loader should not detach, because | 1248 // At this point, the provisional document loader should not detach, because |
| 1236 // then the FrameLoader would not have any attached DocumentLoaders. | 1249 // then the FrameLoader would not have any attached DocumentLoaders. |
| 1237 if (m_documentLoader) { | 1250 if (m_documentLoader) { |
| 1238 AutoReset<bool> inDetachDocumentLoader(&m_protectProvisionalLoader, true); | 1251 AutoReset<bool> inDetachDocumentLoader(&m_protectProvisionalLoader, true); |
| 1239 detachDocumentLoader(m_documentLoader); | 1252 detachDocumentLoader(m_documentLoader); |
| 1240 } | 1253 } |
| 1241 // 'abort' listeners can also detach the frame. | 1254 // 'abort' listeners can also detach the frame. |
| 1242 if (!m_frame->client()) | 1255 if (!m_frame->client()) |
| 1243 return false; | 1256 return false; |
| 1244 DCHECK_EQ(m_provisionalDocumentLoader, pdl); | 1257 DCHECK_EQ(m_provisionalDocumentLoader, pdl); |
| 1245 // No more events will be dispatched so detach the Document. | 1258 // No more events will be dispatched so detach the Document. |
| 1246 // TODO(yoav): Should we also be nullifying domWindow's document (or domWindow
) since the doc is now detached? | 1259 // TODO(yoav): Should we also be nullifying domWindow's document (or |
| 1260 // domWindow) since the doc is now detached? |
| 1247 if (m_frame->document()) | 1261 if (m_frame->document()) |
| 1248 m_frame->document()->shutdown(); | 1262 m_frame->document()->shutdown(); |
| 1249 m_documentLoader = m_provisionalDocumentLoader.release(); | 1263 m_documentLoader = m_provisionalDocumentLoader.release(); |
| 1250 takeObjectSnapshot(); | 1264 takeObjectSnapshot(); |
| 1251 | 1265 |
| 1252 return true; | 1266 return true; |
| 1253 } | 1267 } |
| 1254 | 1268 |
| 1255 void FrameLoader::commitProvisionalLoad() { | 1269 void FrameLoader::commitProvisionalLoad() { |
| 1256 DCHECK(client()->hasWebView()); | 1270 DCHECK(client()->hasWebView()); |
| 1257 | 1271 |
| 1258 // Check if the destination page is allowed to access the previous page's timi
ng information. | 1272 // Check if the destination page is allowed to access the previous page's |
| 1273 // timing information. |
| 1259 if (m_frame->document()) { | 1274 if (m_frame->document()) { |
| 1260 RefPtr<SecurityOrigin> securityOrigin = | 1275 RefPtr<SecurityOrigin> securityOrigin = |
| 1261 SecurityOrigin::create(m_provisionalDocumentLoader->request().url()); | 1276 SecurityOrigin::create(m_provisionalDocumentLoader->request().url()); |
| 1262 m_provisionalDocumentLoader->timing().setHasSameOriginAsPreviousDocument( | 1277 m_provisionalDocumentLoader->timing().setHasSameOriginAsPreviousDocument( |
| 1263 securityOrigin->canRequest(m_frame->document()->url())); | 1278 securityOrigin->canRequest(m_frame->document()->url())); |
| 1264 } | 1279 } |
| 1265 | 1280 |
| 1266 if (!prepareForCommit()) | 1281 if (!prepareForCommit()) |
| 1267 return; | 1282 return; |
| 1268 | 1283 |
| 1269 if (isLoadingMainFrame()) { | 1284 if (isLoadingMainFrame()) { |
| 1270 m_frame->page()->chromeClient().setEventListenerProperties( | 1285 m_frame->page()->chromeClient().setEventListenerProperties( |
| 1271 WebEventListenerClass::TouchStartOrMove, | 1286 WebEventListenerClass::TouchStartOrMove, |
| 1272 WebEventListenerProperties::Nothing); | 1287 WebEventListenerProperties::Nothing); |
| 1273 m_frame->page()->chromeClient().setEventListenerProperties( | 1288 m_frame->page()->chromeClient().setEventListenerProperties( |
| 1274 WebEventListenerClass::MouseWheel, WebEventListenerProperties::Nothing); | 1289 WebEventListenerClass::MouseWheel, WebEventListenerProperties::Nothing); |
| 1275 m_frame->page()->chromeClient().setEventListenerProperties( | 1290 m_frame->page()->chromeClient().setEventListenerProperties( |
| 1276 WebEventListenerClass::TouchEndOrCancel, | 1291 WebEventListenerClass::TouchEndOrCancel, |
| 1277 WebEventListenerProperties::Nothing); | 1292 WebEventListenerProperties::Nothing); |
| 1278 } | 1293 } |
| 1279 | 1294 |
| 1280 client()->transitionToCommittedForNewPage(); | 1295 client()->transitionToCommittedForNewPage(); |
| 1281 m_frame->navigationScheduler().cancel(); | 1296 m_frame->navigationScheduler().cancel(); |
| 1282 m_frame->editor().clearLastEditCommand(); | 1297 m_frame->editor().clearLastEditCommand(); |
| 1283 | 1298 |
| 1284 // If we are still in the process of initializing an empty document then | 1299 // If we are still in the process of initializing an empty document then its |
| 1285 // its frame is not in a consistent state for rendering, so avoid setJSStatusB
arText | 1300 // frame is not in a consistent state for rendering, so avoid |
| 1286 // since it may cause clients to attempt to render the frame. | 1301 // setJSStatusBarText since it may cause clients to attempt to render the |
| 1302 // frame. |
| 1287 if (!m_stateMachine.creatingInitialEmptyDocument()) { | 1303 if (!m_stateMachine.creatingInitialEmptyDocument()) { |
| 1288 DOMWindow* window = m_frame->domWindow(); | 1304 DOMWindow* window = m_frame->domWindow(); |
| 1289 window->setStatus(String()); | 1305 window->setStatus(String()); |
| 1290 window->setDefaultStatus(String()); | 1306 window->setDefaultStatus(String()); |
| 1291 } | 1307 } |
| 1292 } | 1308 } |
| 1293 | 1309 |
| 1294 bool FrameLoader::isLoadingMainFrame() const { | 1310 bool FrameLoader::isLoadingMainFrame() const { |
| 1295 return m_frame->isMainFrame(); | 1311 return m_frame->isMainFrame(); |
| 1296 } | 1312 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1308 } | 1324 } |
| 1309 | 1325 |
| 1310 if (!needsHistoryItemRestore(m_loadType)) | 1326 if (!needsHistoryItemRestore(m_loadType)) |
| 1311 return; | 1327 return; |
| 1312 | 1328 |
| 1313 bool shouldRestoreScroll = | 1329 bool shouldRestoreScroll = |
| 1314 m_currentItem->scrollRestorationType() != ScrollRestorationManual; | 1330 m_currentItem->scrollRestorationType() != ScrollRestorationManual; |
| 1315 bool shouldRestoreScale = m_currentItem->pageScaleFactor(); | 1331 bool shouldRestoreScale = m_currentItem->pageScaleFactor(); |
| 1316 | 1332 |
| 1317 // This tries to balance: | 1333 // This tries to balance: |
| 1318 // 1. restoring as soon as possible | 1334 // 1. restoring as soon as possible |
| 1319 // 2. not overriding user scroll (TODO(majidvp): also respect user scale) | 1335 // 2. not overriding user scroll (TODO(majidvp): also respect user scale) |
| 1320 // 3. detecting clamping to avoid repeatedly popping the scroll position | 1336 // 3. detecting clamping to avoid repeatedly popping the scroll position down |
| 1321 // down as the page height increases | 1337 // as the page height increases |
| 1322 // 4. ignore clamp detection if we are not restoring scroll or after load | 1338 // 4. ignore clamp detection if we are not restoring scroll or after load |
| 1323 // completes because that may be because the page will never reach its | 1339 // completes because that may be because the page will never reach its |
| 1324 // previous height | 1340 // previous height |
| 1325 bool canRestoreWithoutClamping = | 1341 bool canRestoreWithoutClamping = |
| 1326 view->layoutViewportScrollableArea()->clampScrollPosition( | 1342 view->layoutViewportScrollableArea()->clampScrollPosition( |
| 1327 m_currentItem->scrollPoint()) == m_currentItem->scrollPoint(); | 1343 m_currentItem->scrollPoint()) == m_currentItem->scrollPoint(); |
| 1328 bool canRestoreWithoutAnnoyingUser = | 1344 bool canRestoreWithoutAnnoyingUser = |
| 1329 !documentLoader()->initialScrollState().wasScrolledByUser && | 1345 !documentLoader()->initialScrollState().wasScrolledByUser && |
| 1330 (canRestoreWithoutClamping || !m_frame->isLoading() || | 1346 (canRestoreWithoutClamping || !m_frame->isLoading() || |
| 1331 !shouldRestoreScroll); | 1347 !shouldRestoreScroll); |
| 1332 if (!canRestoreWithoutAnnoyingUser) | 1348 if (!canRestoreWithoutAnnoyingUser) |
| 1333 return; | 1349 return; |
| 1334 | 1350 |
| 1335 if (shouldRestoreScroll) | 1351 if (shouldRestoreScroll) |
| 1336 view->layoutViewportScrollableArea()->setScrollPosition( | 1352 view->layoutViewportScrollableArea()->setScrollPosition( |
| 1337 m_currentItem->scrollPoint(), ProgrammaticScroll); | 1353 m_currentItem->scrollPoint(), ProgrammaticScroll); |
| 1338 | 1354 |
| 1339 // For main frame restore scale and visual viewport position | 1355 // For main frame restore scale and visual viewport position |
| 1340 if (m_frame->isMainFrame()) { | 1356 if (m_frame->isMainFrame()) { |
| 1341 FloatPoint visualViewportOffset(m_currentItem->visualViewportScrollPoint()); | 1357 FloatPoint visualViewportOffset(m_currentItem->visualViewportScrollPoint()); |
| 1342 | 1358 |
| 1343 // If the visual viewport's offset is (-1, -1) it means the history item | 1359 // If the visual viewport's offset is (-1, -1) it means the history item is |
| 1344 // is an old version of HistoryItem so distribute the scroll between | 1360 // an old version of HistoryItem so distribute the scroll between the main |
| 1345 // the main frame and the visual viewport as best as we can. | 1361 // frame and the visual viewport as best as we can. |
| 1346 if (visualViewportOffset.x() == -1 && visualViewportOffset.y() == -1) | 1362 if (visualViewportOffset.x() == -1 && visualViewportOffset.y() == -1) |
| 1347 visualViewportOffset = | 1363 visualViewportOffset = |
| 1348 FloatPoint(m_currentItem->scrollPoint() - view->scrollPosition()); | 1364 FloatPoint(m_currentItem->scrollPoint() - view->scrollPosition()); |
| 1349 | 1365 |
| 1350 VisualViewport& visualViewport = m_frame->host()->visualViewport(); | 1366 VisualViewport& visualViewport = m_frame->host()->visualViewport(); |
| 1351 if (shouldRestoreScale && shouldRestoreScroll) | 1367 if (shouldRestoreScale && shouldRestoreScroll) |
| 1352 visualViewport.setScaleAndLocation(m_currentItem->pageScaleFactor(), | 1368 visualViewport.setScaleAndLocation(m_currentItem->pageScaleFactor(), |
| 1353 visualViewportOffset); | 1369 visualViewportOffset); |
| 1354 else if (shouldRestoreScale) | 1370 else if (shouldRestoreScale) |
| 1355 visualViewport.setScale(m_currentItem->pageScaleFactor()); | 1371 visualViewport.setScale(m_currentItem->pageScaleFactor()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1410 m_progressTracker->progressCompleted(); | 1426 m_progressTracker->progressCompleted(); |
| 1411 } | 1427 } |
| 1412 } | 1428 } |
| 1413 checkCompleted(); | 1429 checkCompleted(); |
| 1414 } | 1430 } |
| 1415 | 1431 |
| 1416 bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, | 1432 bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, |
| 1417 const String& httpMethod, | 1433 const String& httpMethod, |
| 1418 FrameLoadType loadType, | 1434 FrameLoadType loadType, |
| 1419 const KURL& url) { | 1435 const KURL& url) { |
| 1420 // We don't do this if we are submitting a form with method other than "GET",
explicitly reloading, | 1436 // We don't do this if we are submitting a form with method other than "GET", |
| 1421 // currently displaying a frameset, or if the URL does not have a fragment. | 1437 // explicitly reloading, currently displaying a frameset, or if the URL does |
| 1438 // not have a fragment. |
| 1422 return (!isFormSubmission || equalIgnoringCase(httpMethod, HTTPNames::GET)) && | 1439 return (!isFormSubmission || equalIgnoringCase(httpMethod, HTTPNames::GET)) && |
| 1423 !isReloadLoadType(loadType) && loadType != FrameLoadTypeBackForward && | 1440 !isReloadLoadType(loadType) && loadType != FrameLoadTypeBackForward && |
| 1424 url.hasFragmentIdentifier() && | 1441 url.hasFragmentIdentifier() && |
| 1425 equalIgnoringFragmentIdentifier(m_frame->document()->url(), url) | 1442 equalIgnoringFragmentIdentifier(m_frame->document()->url(), url) |
| 1426 // We don't want to just scroll if a link from within a | 1443 // We don't want to just scroll if a link from within a frameset is |
| 1427 // frameset is trying to reload the frameset into _top. | 1444 // trying to reload the frameset into _top. |
| 1428 && !m_frame->document()->isFrameSet(); | 1445 && !m_frame->document()->isFrameSet(); |
| 1429 } | 1446 } |
| 1430 | 1447 |
| 1431 void FrameLoader::processFragment(const KURL& url, | 1448 void FrameLoader::processFragment(const KURL& url, |
| 1432 LoadStartType loadStartType) { | 1449 LoadStartType loadStartType) { |
| 1433 FrameView* view = m_frame->view(); | 1450 FrameView* view = m_frame->view(); |
| 1434 if (!view) | 1451 if (!view) |
| 1435 return; | 1452 return; |
| 1436 | 1453 |
| 1437 // Leaking scroll position to a cross-origin ancestor would permit the so-call
ed "framesniffing" attack. | 1454 // Leaking scroll position to a cross-origin ancestor would permit the |
| 1455 // so-called "framesniffing" attack. |
| 1438 Frame* boundaryFrame = | 1456 Frame* boundaryFrame = |
| 1439 url.hasFragmentIdentifier() | 1457 url.hasFragmentIdentifier() |
| 1440 ? m_frame->findUnsafeParentScrollPropagationBoundary() | 1458 ? m_frame->findUnsafeParentScrollPropagationBoundary() |
| 1441 : 0; | 1459 : 0; |
| 1442 | 1460 |
| 1443 // FIXME: Handle RemoteFrames | 1461 // FIXME: Handle RemoteFrames |
| 1444 if (boundaryFrame && boundaryFrame->isLocalFrame()) | 1462 if (boundaryFrame && boundaryFrame->isLocalFrame()) |
| 1445 toLocalFrame(boundaryFrame) | 1463 toLocalFrame(boundaryFrame) |
| 1446 ->view() | 1464 ->view() |
| 1447 ->setSafeToPropagateScrollToParent(false); | 1465 ->setSafeToPropagateScrollToParent(false); |
| 1448 | 1466 |
| 1449 // If scroll position is restored from history fragment then we should not ove
rride it unless | 1467 // If scroll position is restored from history fragment then we should not |
| 1450 // this is a same document reload. | 1468 // override it unless this is a same document reload. |
| 1451 bool shouldScrollToFragment = | 1469 bool shouldScrollToFragment = |
| 1452 (loadStartType == NavigationWithinSameDocument && | 1470 (loadStartType == NavigationWithinSameDocument && |
| 1453 !isBackForwardLoadType(m_loadType)) || | 1471 !isBackForwardLoadType(m_loadType)) || |
| 1454 (documentLoader() && | 1472 (documentLoader() && |
| 1455 !documentLoader()->initialScrollState().didRestoreFromHistory); | 1473 !documentLoader()->initialScrollState().didRestoreFromHistory); |
| 1456 | 1474 |
| 1457 view->processUrlFragment(url, shouldScrollToFragment | 1475 view->processUrlFragment(url, shouldScrollToFragment |
| 1458 ? FrameView::UrlFragmentScroll | 1476 ? FrameView::UrlFragmentScroll |
| 1459 : FrameView::UrlFragmentDontScroll); | 1477 : FrameView::UrlFragmentDontScroll); |
| 1460 | 1478 |
| 1461 if (boundaryFrame && boundaryFrame->isLocalFrame()) | 1479 if (boundaryFrame && boundaryFrame->isLocalFrame()) |
| 1462 toLocalFrame(boundaryFrame)->view()->setSafeToPropagateScrollToParent(true); | 1480 toLocalFrame(boundaryFrame)->view()->setSafeToPropagateScrollToParent(true); |
| 1463 } | 1481 } |
| 1464 | 1482 |
| 1465 bool FrameLoader::shouldClose(bool isReload) { | 1483 bool FrameLoader::shouldClose(bool isReload) { |
| 1466 Page* page = m_frame->page(); | 1484 Page* page = m_frame->page(); |
| 1467 if (!page || !page->chromeClient().canOpenBeforeUnloadConfirmPanel()) | 1485 if (!page || !page->chromeClient().canOpenBeforeUnloadConfirmPanel()) |
| 1468 return true; | 1486 return true; |
| 1469 | 1487 |
| 1470 // Store all references to each subframe in advance since beforeunload's event
handler may modify frame | 1488 // Store all references to each subframe in advance since beforeunload's event |
| 1489 // handler may modify frame |
| 1471 HeapVector<Member<LocalFrame>> targetFrames; | 1490 HeapVector<Member<LocalFrame>> targetFrames; |
| 1472 targetFrames.append(m_frame); | 1491 targetFrames.append(m_frame); |
| 1473 for (Frame* child = m_frame->tree().firstChild(); child; | 1492 for (Frame* child = m_frame->tree().firstChild(); child; |
| 1474 child = child->tree().traverseNext(m_frame)) { | 1493 child = child->tree().traverseNext(m_frame)) { |
| 1475 // FIXME: There is not yet any way to dispatch events to out-of-process fram
es. | 1494 // FIXME: There is not yet any way to dispatch events to out-of-process |
| 1495 // frames. |
| 1476 if (child->isLocalFrame()) | 1496 if (child->isLocalFrame()) |
| 1477 targetFrames.append(toLocalFrame(child)); | 1497 targetFrames.append(toLocalFrame(child)); |
| 1478 } | 1498 } |
| 1479 | 1499 |
| 1480 bool shouldClose = false; | 1500 bool shouldClose = false; |
| 1481 { | 1501 { |
| 1482 NavigationDisablerForUnload navigationDisabler; | 1502 NavigationDisablerForUnload navigationDisabler; |
| 1483 size_t i; | 1503 size_t i; |
| 1484 | 1504 |
| 1485 bool didAllowNavigation = false; | 1505 bool didAllowNavigation = false; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1507 NavigationPolicy policy, | 1527 NavigationPolicy policy, |
| 1508 bool replacesCurrentHistoryItem, | 1528 bool replacesCurrentHistoryItem, |
| 1509 bool isClientRedirect, | 1529 bool isClientRedirect, |
| 1510 HTMLFormElement* form) { | 1530 HTMLFormElement* form) { |
| 1511 m_isNavigationHandledByClient = false; | 1531 m_isNavigationHandledByClient = false; |
| 1512 | 1532 |
| 1513 // Don't ask if we are loading an empty URL. | 1533 // Don't ask if we are loading an empty URL. |
| 1514 if (request.url().isEmpty() || substituteData.isValid()) | 1534 if (request.url().isEmpty() || substituteData.isValid()) |
| 1515 return true; | 1535 return true; |
| 1516 | 1536 |
| 1517 // If we're loading content into a subframe, check against the parent's Conten
t Security Policy | 1537 // If we're loading content into a subframe, check against the parent's |
| 1518 // and kill the load if that check fails, unless we should bypass the main wor
ld's CSP. | 1538 // Content Security Policy and kill the load if that check fails, unless we |
| 1539 // should bypass the main world's CSP. |
| 1519 if (shouldCheckMainWorldContentSecurityPolicy == CheckContentSecurityPolicy) { | 1540 if (shouldCheckMainWorldContentSecurityPolicy == CheckContentSecurityPolicy) { |
| 1520 Frame* parentFrame = m_frame->tree().parent(); | 1541 Frame* parentFrame = m_frame->tree().parent(); |
| 1521 if (parentFrame) { | 1542 if (parentFrame) { |
| 1522 ContentSecurityPolicy* parentPolicy = | 1543 ContentSecurityPolicy* parentPolicy = |
| 1523 parentFrame->securityContext()->contentSecurityPolicy(); | 1544 parentFrame->securityContext()->contentSecurityPolicy(); |
| 1524 if (!parentPolicy->allowChildFrameFromSource(request.url(), | 1545 if (!parentPolicy->allowChildFrameFromSource(request.url(), |
| 1525 request.redirectStatus())) { | 1546 request.redirectStatus())) { |
| 1526 // Fire a load event, as timing attacks would otherwise reveal that the | 1547 // Fire a load event, as timing attacks would otherwise reveal that the |
| 1527 // frame was blocked. This way, it looks like every other cross-origin | 1548 // frame was blocked. This way, it looks like every other cross-origin |
| 1528 // page load. | 1549 // page load. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1592 navigationType, navigationPolicy, | 1613 navigationType, navigationPolicy, |
| 1593 type == FrameLoadTypeReplaceCurrentItem, | 1614 type == FrameLoadTypeReplaceCurrentItem, |
| 1594 frameLoadRequest.clientRedirect() == | 1615 frameLoadRequest.clientRedirect() == |
| 1595 ClientRedirectPolicy::ClientRedirect, | 1616 ClientRedirectPolicy::ClientRedirect, |
| 1596 frameLoadRequest.form())) | 1617 frameLoadRequest.form())) |
| 1597 return; | 1618 return; |
| 1598 | 1619 |
| 1599 m_frame->document()->cancelParsing(); | 1620 m_frame->document()->cancelParsing(); |
| 1600 detachDocumentLoader(m_provisionalDocumentLoader); | 1621 detachDocumentLoader(m_provisionalDocumentLoader); |
| 1601 | 1622 |
| 1602 // beforeunload fired above, and detaching a DocumentLoader can fire | 1623 // beforeunload fired above, and detaching a DocumentLoader can fire events, |
| 1603 // events, which can detach this frame. | 1624 // which can detach this frame. |
| 1604 if (!m_frame->host()) | 1625 if (!m_frame->host()) |
| 1605 return; | 1626 return; |
| 1606 | 1627 |
| 1607 m_provisionalDocumentLoader = client()->createDocumentLoader( | 1628 m_provisionalDocumentLoader = client()->createDocumentLoader( |
| 1608 m_frame, request, frameLoadRequest.substituteData().isValid() | 1629 m_frame, request, frameLoadRequest.substituteData().isValid() |
| 1609 ? frameLoadRequest.substituteData() | 1630 ? frameLoadRequest.substituteData() |
| 1610 : defaultSubstituteDataForURL(request.url())); | 1631 : defaultSubstituteDataForURL(request.url())); |
| 1611 m_provisionalDocumentLoader->setNavigationType(navigationType); | 1632 m_provisionalDocumentLoader->setNavigationType(navigationType); |
| 1612 m_provisionalDocumentLoader->setReplacesCurrentHistoryItem( | 1633 m_provisionalDocumentLoader->setReplacesCurrentHistoryItem( |
| 1613 type == FrameLoadTypeReplaceCurrentItem); | 1634 type == FrameLoadTypeReplaceCurrentItem); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1792 // out-of-process frames. For now, we'll always use default behavior. | 1813 // out-of-process frames. For now, we'll always use default behavior. |
| 1793 if (!parentFrame->isLocalFrame()) | 1814 if (!parentFrame->isLocalFrame()) |
| 1794 return nullptr; | 1815 return nullptr; |
| 1795 | 1816 |
| 1796 DCHECK(toLocalFrame(parentFrame)->document()); | 1817 DCHECK(toLocalFrame(parentFrame)->document()); |
| 1797 return toLocalFrame(parentFrame)->document()->insecureNavigationsToUpgrade(); | 1818 return toLocalFrame(parentFrame)->document()->insecureNavigationsToUpgrade(); |
| 1798 } | 1819 } |
| 1799 | 1820 |
| 1800 void FrameLoader::upgradeInsecureRequest(ResourceRequest& resourceRequest, | 1821 void FrameLoader::upgradeInsecureRequest(ResourceRequest& resourceRequest, |
| 1801 Document* document) const { | 1822 Document* document) const { |
| 1802 // Tack an 'Upgrade-Insecure-Requests' header to outgoing navigational request
s, as described in | 1823 // Tack an 'Upgrade-Insecure-Requests' header to outgoing navigational |
| 1824 // requests, as described in |
| 1803 // https://w3c.github.io/webappsec/specs/upgrade/#feature-detect | 1825 // https://w3c.github.io/webappsec/specs/upgrade/#feature-detect |
| 1804 if (resourceRequest.frameType() != WebURLRequest::FrameTypeNone) { | 1826 if (resourceRequest.frameType() != WebURLRequest::FrameTypeNone) { |
| 1805 // Early return if the request has already been upgraded. | 1827 // Early return if the request has already been upgraded. |
| 1806 if (resourceRequest.httpHeaderField("Upgrade-Insecure-Requests") == | 1828 if (resourceRequest.httpHeaderField("Upgrade-Insecure-Requests") == |
| 1807 AtomicString("1")) | 1829 AtomicString("1")) |
| 1808 return; | 1830 return; |
| 1809 | 1831 |
| 1810 resourceRequest.addHTTPHeaderField("Upgrade-Insecure-Requests", "1"); | 1832 resourceRequest.addHTTPHeaderField("Upgrade-Insecure-Requests", "1"); |
| 1811 } | 1833 } |
| 1812 | 1834 |
| 1813 KURL url = resourceRequest.url(); | 1835 KURL url = resourceRequest.url(); |
| 1814 | 1836 |
| 1815 // If we don't yet have an |m_document| (because we're loading an iframe, for
instance), check the FrameLoader's policy. | 1837 // If we don't yet have an |m_document| (because we're loading an iframe, for |
| 1838 // instance), check the FrameLoader's policy. |
| 1816 WebInsecureRequestPolicy relevantPolicy = | 1839 WebInsecureRequestPolicy relevantPolicy = |
| 1817 document ? document->getInsecureRequestPolicy() | 1840 document ? document->getInsecureRequestPolicy() |
| 1818 : getInsecureRequestPolicy(); | 1841 : getInsecureRequestPolicy(); |
| 1819 SecurityContext::InsecureNavigationsSet* relevantNavigationSet = | 1842 SecurityContext::InsecureNavigationsSet* relevantNavigationSet = |
| 1820 document ? document->insecureNavigationsToUpgrade() | 1843 document ? document->insecureNavigationsToUpgrade() |
| 1821 : insecureNavigationsToUpgrade(); | 1844 : insecureNavigationsToUpgrade(); |
| 1822 | 1845 |
| 1823 if (url.protocolIs("http") && relevantPolicy & kUpgradeInsecureRequests) { | 1846 if (url.protocolIs("http") && relevantPolicy & kUpgradeInsecureRequests) { |
| 1824 // We always upgrade requests that meet any of the following criteria: | 1847 // We always upgrade requests that meet any of the following criteria: |
| 1825 // | 1848 // |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1860 m_documentLoader ? m_documentLoader->url() : String()); | 1883 m_documentLoader ? m_documentLoader->url() : String()); |
| 1861 return tracedValue; | 1884 return tracedValue; |
| 1862 } | 1885 } |
| 1863 | 1886 |
| 1864 inline void FrameLoader::takeObjectSnapshot() const { | 1887 inline void FrameLoader::takeObjectSnapshot() const { |
| 1865 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID("loading", "FrameLoader", this, | 1888 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID("loading", "FrameLoader", this, |
| 1866 toTracedValue()); | 1889 toTracedValue()); |
| 1867 } | 1890 } |
| 1868 | 1891 |
| 1869 } // namespace blink | 1892 } // namespace blink |
| OLD | NEW |