Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights |
| 3 * reserved. | 3 * reserved. |
| 4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 5 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 5 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
| 6 * (http://www.torchmobile.com/) | 6 * (http://www.torchmobile.com/) |
| 7 * Copyright (C) 2008 Alp Toker <alp@atoker.com> | 7 * Copyright (C) 2008 Alp Toker <alp@atoker.com> |
| 8 * Copyright (C) Research In Motion Limited 2009. All rights reserved. | 8 * Copyright (C) Research In Motion Limited 2009. All rights reserved. |
| 9 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> | 9 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> |
| 10 * Copyright (C) 2011 Google Inc. All rights reserved. | 10 * Copyright (C) 2011 Google Inc. All rights reserved. |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 | 182 |
| 183 FrameLoader::FrameLoader(LocalFrame* frame) | 183 FrameLoader::FrameLoader(LocalFrame* frame) |
| 184 : m_frame(frame), | 184 : m_frame(frame), |
| 185 m_progressTracker(ProgressTracker::create(frame)), | 185 m_progressTracker(ProgressTracker::create(frame)), |
| 186 m_inStopAllLoaders(false), | 186 m_inStopAllLoaders(false), |
| 187 m_checkTimer(TaskRunnerHelper::get(TaskType::Networking, frame), | 187 m_checkTimer(TaskRunnerHelper::get(TaskType::Networking, frame), |
| 188 this, | 188 this, |
| 189 &FrameLoader::checkTimerFired), | 189 &FrameLoader::checkTimerFired), |
| 190 m_forcedSandboxFlags(SandboxNone), | 190 m_forcedSandboxFlags(SandboxNone), |
| 191 m_dispatchingDidClearWindowObjectInMainWorld(false), | 191 m_dispatchingDidClearWindowObjectInMainWorld(false), |
| 192 m_protectProvisionalLoader(false), | 192 m_protectProvisionalLoader(false) { |
| 193 m_isNavigationHandledByClient(false) { | |
| 194 DCHECK(m_frame); | 193 DCHECK(m_frame); |
| 195 TRACE_EVENT_OBJECT_CREATED_WITH_ID("loading", "FrameLoader", this); | 194 TRACE_EVENT_OBJECT_CREATED_WITH_ID("loading", "FrameLoader", this); |
| 196 takeObjectSnapshot(); | 195 takeObjectSnapshot(); |
| 197 } | 196 } |
| 198 | 197 |
| 199 FrameLoader::~FrameLoader() { | 198 FrameLoader::~FrameLoader() { |
| 200 // Verify that this FrameLoader has been detached. | 199 // Verify that this FrameLoader has been detached. |
| 201 DCHECK(!m_progressTracker); | 200 DCHECK(!m_progressTracker); |
| 202 } | 201 } |
| 203 | 202 |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 696 if (!allDescendantsAreComplete(frame)) | 695 if (!allDescendantsAreComplete(frame)) |
| 697 return false; | 696 return false; |
| 698 | 697 |
| 699 // Don't notify if the frame is being detached. | 698 // Don't notify if the frame is being detached. |
| 700 if (frame->isDetaching()) | 699 if (frame->isDetaching()) |
| 701 return false; | 700 return false; |
| 702 | 701 |
| 703 return true; | 702 return true; |
| 704 } | 703 } |
| 705 | 704 |
| 706 static bool shouldSendCompleteNotification(LocalFrame* frame, | 705 static bool shouldSendCompleteNotification(LocalFrame* frame) { |
| 707 bool isNavigationHandledByClient) { | |
| 708 // FIXME: We might have already sent stop notifications and be re-completing. | 706 // FIXME: We might have already sent stop notifications and be re-completing. |
| 709 if (!frame->isLoading()) | 707 if (!frame->isLoading()) |
| 710 return false; | 708 return false; |
| 711 // Only send didStopLoading() if there are no navigations in progress at all, | 709 // Only send didStopLoading() if there are no navigations in progress at all, |
| 712 // whether committed, provisional, or pending. | 710 // whether committed, provisional, or pending. |
| 713 return frame->loader().documentLoader()->sentDidFinishLoad() && | 711 return frame->loader().documentLoader()->sentDidFinishLoad() && |
| 714 !frame->loader().hasProvisionalNavigation(); | 712 !frame->loader().hasProvisionalNavigation(); |
| 715 } | 713 } |
| 716 | 714 |
| 717 void FrameLoader::checkCompleted() { | 715 void FrameLoader::checkCompleted() { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 737 // Android. | 735 // Android. |
| 738 if (m_frame->isMainFrame()) | 736 if (m_frame->isMainFrame()) |
| 739 m_frame->document()->viewportDescription().reportMobilePageStats(m_frame); | 737 m_frame->document()->viewportDescription().reportMobilePageStats(m_frame); |
| 740 m_documentLoader->setSentDidFinishLoad(); | 738 m_documentLoader->setSentDidFinishLoad(); |
| 741 client()->dispatchDidFinishLoad(); | 739 client()->dispatchDidFinishLoad(); |
| 742 // Finishing the load can detach the frame when running layout tests. | 740 // Finishing the load can detach the frame when running layout tests. |
| 743 if (!m_frame->client()) | 741 if (!m_frame->client()) |
| 744 return; | 742 return; |
| 745 } | 743 } |
| 746 | 744 |
| 747 if (shouldSendCompleteNotification(m_frame, m_isNavigationHandledByClient)) { | 745 if (shouldSendCompleteNotification(m_frame)) { |
| 748 m_progressTracker->progressCompleted(); | 746 m_progressTracker->progressCompleted(); |
| 749 // Retry restoring scroll offset since finishing loading disables content | 747 // Retry restoring scroll offset since finishing loading disables content |
| 750 // size clamping. | 748 // size clamping. |
| 751 restoreScrollPositionAndViewState(); | 749 restoreScrollPositionAndViewState(); |
| 752 if (m_documentLoader) | 750 if (m_documentLoader) |
| 753 m_documentLoader->setLoadType(FrameLoadTypeStandard); | 751 m_documentLoader->setLoadType(FrameLoadTypeStandard); |
| 754 m_frame->domWindow()->finishedLoading(); | 752 m_frame->domWindow()->finishedLoading(); |
| 755 } | 753 } |
| 756 | 754 |
| 757 Frame* parent = m_frame->tree().parent(); | 755 Frame* parent = m_frame->tree().parent(); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 858 HistoryLoadType historyLoadType, | 856 HistoryLoadType historyLoadType, |
| 859 ClientRedirectPolicy clientRedirect, | 857 ClientRedirectPolicy clientRedirect, |
| 860 Document* initiatingDocument) { | 858 Document* initiatingDocument) { |
| 861 // If we have a state object, we cannot also be a new navigation. | 859 // If we have a state object, we cannot also be a new navigation. |
| 862 DCHECK(!stateObject || frameLoadType == FrameLoadTypeBackForward); | 860 DCHECK(!stateObject || frameLoadType == FrameLoadTypeBackForward); |
| 863 | 861 |
| 864 // If we have a provisional request for a different document, a fragment | 862 // If we have a provisional request for a different document, a fragment |
| 865 // scroll should cancel it. | 863 // scroll should cancel it. |
| 866 detachDocumentLoader(m_provisionalDocumentLoader); | 864 detachDocumentLoader(m_provisionalDocumentLoader); |
| 867 | 865 |
| 868 // PlzNavigate: A fragment scroll should clear ongoing client navigations. | |
| 869 clearNavigationHandledByClient(); | |
| 870 | |
| 871 if (!m_frame->host()) | 866 if (!m_frame->host()) |
| 872 return; | 867 return; |
| 873 saveScrollState(); | 868 saveScrollState(); |
| 874 | 869 |
| 875 KURL oldURL = m_frame->document()->url(); | 870 KURL oldURL = m_frame->document()->url(); |
| 876 bool hashChange = equalIgnoringFragmentIdentifier(url, oldURL) && | 871 bool hashChange = equalIgnoringFragmentIdentifier(url, oldURL) && |
| 877 url.fragmentIdentifier() != oldURL.fragmentIdentifier(); | 872 url.fragmentIdentifier() != oldURL.fragmentIdentifier(); |
| 878 if (hashChange) { | 873 if (hashChange) { |
| 879 // If we were in the autoscroll/middleClickAutoscroll mode we want to stop | 874 // If we were in the autoscroll/middleClickAutoscroll mode we want to stop |
| 880 // it before following the link to the anchor | 875 // it before following the link to the anchor |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1238 Document::NoDismissal) | 1233 Document::NoDismissal) |
| 1239 return; | 1234 return; |
| 1240 | 1235 |
| 1241 // If this method is called from within this method, infinite recursion can | 1236 // If this method is called from within this method, infinite recursion can |
| 1242 // occur (3442218). Avoid this. | 1237 // occur (3442218). Avoid this. |
| 1243 if (m_inStopAllLoaders) | 1238 if (m_inStopAllLoaders) |
| 1244 return; | 1239 return; |
| 1245 | 1240 |
| 1246 m_inStopAllLoaders = true; | 1241 m_inStopAllLoaders = true; |
| 1247 | 1242 |
| 1248 if (m_isNavigationHandledByClient) { | |
| 1249 client()->dispatchDidFailProvisionalLoad( | |
| 1250 ResourceError::cancelledError(String()), StandardCommit); | |
| 1251 } | |
| 1252 | |
| 1253 clearNavigationHandledByClient(); | |
| 1254 | |
| 1255 for (Frame* child = m_frame->tree().firstChild(); child; | 1243 for (Frame* child = m_frame->tree().firstChild(); child; |
| 1256 child = child->tree().nextSibling()) { | 1244 child = child->tree().nextSibling()) { |
| 1257 if (child->isLocalFrame()) | 1245 if (child->isLocalFrame()) |
| 1258 toLocalFrame(child)->loader().stopAllLoaders(); | 1246 toLocalFrame(child)->loader().stopAllLoaders(); |
| 1259 } | 1247 } |
| 1260 | 1248 |
| 1261 m_frame->document()->suppressLoadEvent(); | 1249 m_frame->document()->suppressLoadEvent(); |
| 1262 if (m_documentLoader) | 1250 if (m_documentLoader) |
| 1263 m_documentLoader->fetcher()->stopFetching(); | 1251 m_documentLoader->fetcher()->stopFetching(); |
| 1264 m_frame->document()->cancelParsing(); | 1252 m_frame->document()->cancelParsing(); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1376 m_frame->page()->chromeClient().setEventListenerProperties( | 1364 m_frame->page()->chromeClient().setEventListenerProperties( |
| 1377 m_frame, WebEventListenerClass::MouseWheel, | 1365 m_frame, WebEventListenerClass::MouseWheel, |
| 1378 WebEventListenerProperties::Nothing); | 1366 WebEventListenerProperties::Nothing); |
| 1379 m_frame->page()->chromeClient().setEventListenerProperties( | 1367 m_frame->page()->chromeClient().setEventListenerProperties( |
| 1380 m_frame, WebEventListenerClass::TouchEndOrCancel, | 1368 m_frame, WebEventListenerClass::TouchEndOrCancel, |
| 1381 WebEventListenerProperties::Nothing); | 1369 WebEventListenerProperties::Nothing); |
| 1382 } | 1370 } |
| 1383 | 1371 |
| 1384 client()->transitionToCommittedForNewPage(); | 1372 client()->transitionToCommittedForNewPage(); |
| 1385 | 1373 |
| 1386 // PlzNavigate: We need to ensure that script initiated navigations are | 1374 m_frame->navigationScheduler().cancel(); |
| 1387 // honored. | |
| 1388 if (!m_isNavigationHandledByClient) | |
| 1389 m_frame->navigationScheduler().cancel(); | |
| 1390 | 1375 |
| 1391 m_frame->editor().clearLastEditCommand(); | 1376 m_frame->editor().clearLastEditCommand(); |
| 1392 | 1377 |
| 1393 // If we are still in the process of initializing an empty document then its | 1378 // If we are still in the process of initializing an empty document then its |
| 1394 // frame is not in a consistent state for rendering, so avoid | 1379 // frame is not in a consistent state for rendering, so avoid |
| 1395 // setJSStatusBarText since it may cause clients to attempt to render the | 1380 // setJSStatusBarText since it may cause clients to attempt to render the |
| 1396 // frame. | 1381 // frame. |
| 1397 if (!m_stateMachine.creatingInitialEmptyDocument()) { | 1382 if (!m_stateMachine.creatingInitialEmptyDocument()) { |
| 1398 LocalDOMWindow* window = m_frame->domWindow(); | 1383 LocalDOMWindow* window = m_frame->domWindow(); |
| 1399 window->setStatus(String()); | 1384 window->setStatus(String()); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1508 const ResourceError& error) { | 1493 const ResourceError& error) { |
| 1509 if (!error.isCancellation() && m_frame->owner()) { | 1494 if (!error.isCancellation() && m_frame->owner()) { |
| 1510 // FIXME: For now, fallback content doesn't work cross process. | 1495 // FIXME: For now, fallback content doesn't work cross process. |
| 1511 if (m_frame->owner()->isLocal()) | 1496 if (m_frame->owner()->isLocal()) |
| 1512 m_frame->deprecatedLocalOwner()->renderFallbackContent(); | 1497 m_frame->deprecatedLocalOwner()->renderFallbackContent(); |
| 1513 } | 1498 } |
| 1514 | 1499 |
| 1515 HistoryCommitType historyCommitType = | 1500 HistoryCommitType historyCommitType = |
| 1516 loadTypeToCommitType(loader->loadType()); | 1501 loadTypeToCommitType(loader->loadType()); |
| 1517 if (loader == m_provisionalDocumentLoader) { | 1502 if (loader == m_provisionalDocumentLoader) { |
| 1503 if (!m_provisionalDocumentLoader->didStart()) | |
| 1504 InspectorInstrumentation::frameClearedScheduledClientNavigation(m_frame); | |
| 1518 m_provisionalDocumentLoader->setSentDidFinishLoad(); | 1505 m_provisionalDocumentLoader->setSentDidFinishLoad(); |
| 1519 client()->dispatchDidFailProvisionalLoad(error, historyCommitType); | 1506 client()->dispatchDidFailProvisionalLoad(error, historyCommitType); |
| 1520 if (loader != m_provisionalDocumentLoader) | 1507 if (loader != m_provisionalDocumentLoader) |
| 1521 return; | 1508 return; |
| 1522 detachDocumentLoader(m_provisionalDocumentLoader); | 1509 detachDocumentLoader(m_provisionalDocumentLoader); |
| 1523 } else { | 1510 } else { |
| 1524 DCHECK_EQ(loader, m_documentLoader); | 1511 DCHECK_EQ(loader, m_documentLoader); |
| 1525 if (m_frame->document()->parser()) | 1512 if (m_frame->document()->parser()) |
| 1526 m_frame->document()->parser()->stopParsing(); | 1513 m_frame->document()->parser()->stopParsing(); |
| 1527 if (!m_documentLoader->sentDidFinishLoad()) { | 1514 if (!m_documentLoader->sentDidFinishLoad()) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1619 break; | 1606 break; |
| 1620 } | 1607 } |
| 1621 | 1608 |
| 1622 if (i == targetFrames.size()) | 1609 if (i == targetFrames.size()) |
| 1623 shouldClose = true; | 1610 shouldClose = true; |
| 1624 } | 1611 } |
| 1625 | 1612 |
| 1626 return shouldClose; | 1613 return shouldClose; |
| 1627 } | 1614 } |
| 1628 | 1615 |
| 1629 bool FrameLoader::shouldContinueForNavigationPolicy( | 1616 NavigationPolicy FrameLoader::shouldContinueForNavigationPolicy( |
| 1630 const ResourceRequest& request, | 1617 const ResourceRequest& request, |
| 1631 const SubstituteData& substituteData, | 1618 const SubstituteData& substituteData, |
| 1632 DocumentLoader* loader, | 1619 DocumentLoader* loader, |
| 1633 ContentSecurityPolicyDisposition shouldCheckMainWorldContentSecurityPolicy, | 1620 ContentSecurityPolicyDisposition shouldCheckMainWorldContentSecurityPolicy, |
| 1634 NavigationType type, | 1621 NavigationType type, |
| 1635 NavigationPolicy policy, | 1622 NavigationPolicy policy, |
| 1636 FrameLoadType frameLoadType, | 1623 FrameLoadType frameLoadType, |
| 1637 bool isClientRedirect, | 1624 bool isClientRedirect, |
| 1638 HTMLFormElement* form) { | 1625 HTMLFormElement* form) { |
| 1639 // Don't ask if we are loading an empty URL. | 1626 // Don't ask if we are loading an empty URL. |
| 1640 if (request.url().isEmpty() || substituteData.isValid()) | 1627 if (request.url().isEmpty() || substituteData.isValid()) |
| 1641 return true; | 1628 return NavigationPolicyCurrentTab; |
| 1642 | 1629 |
| 1643 // If we're loading content into |m_frame| (NavigationPolicyCurrentTab), check | 1630 // If we're loading content into |m_frame| (NavigationPolicyCurrentTab), check |
| 1644 // against the parent's Content Security Policy and kill the load if that | 1631 // against the parent's Content Security Policy and kill the load if that |
| 1645 // check fails, unless we should bypass the main world's CSP. | 1632 // check fails, unless we should bypass the main world's CSP. |
| 1646 if (policy == NavigationPolicyCurrentTab && | 1633 if (policy == NavigationPolicyCurrentTab && |
| 1647 shouldCheckMainWorldContentSecurityPolicy == CheckContentSecurityPolicy) { | 1634 shouldCheckMainWorldContentSecurityPolicy == CheckContentSecurityPolicy) { |
| 1648 Frame* parentFrame = m_frame->tree().parent(); | 1635 Frame* parentFrame = m_frame->tree().parent(); |
| 1649 if (parentFrame) { | 1636 if (parentFrame) { |
| 1650 ContentSecurityPolicy* parentPolicy = | 1637 ContentSecurityPolicy* parentPolicy = |
| 1651 parentFrame->securityContext()->contentSecurityPolicy(); | 1638 parentFrame->securityContext()->contentSecurityPolicy(); |
| 1652 if (!parentPolicy->allowFrameFromSource(request.url(), | 1639 if (!parentPolicy->allowFrameFromSource(request.url(), |
| 1653 request.redirectStatus())) { | 1640 request.redirectStatus())) { |
| 1654 // Fire a load event, as timing attacks would otherwise reveal that the | 1641 // Fire a load event, as timing attacks would otherwise reveal that the |
| 1655 // frame was blocked. This way, it looks like every other cross-origin | 1642 // frame was blocked. This way, it looks like every other cross-origin |
| 1656 // page load. | 1643 // page load. |
| 1657 m_frame->document()->enforceSandboxFlags(SandboxOrigin); | 1644 m_frame->document()->enforceSandboxFlags(SandboxOrigin); |
| 1658 m_frame->owner()->dispatchLoad(); | 1645 m_frame->owner()->dispatchLoad(); |
| 1659 return false; | 1646 return NavigationPolicyIgnore; |
| 1660 } | 1647 } |
| 1661 } | 1648 } |
| 1662 } | 1649 } |
| 1663 | 1650 |
| 1664 bool isFormSubmission = type == NavigationTypeFormSubmitted || | 1651 bool isFormSubmission = type == NavigationTypeFormSubmitted || |
| 1665 type == NavigationTypeFormResubmitted; | 1652 type == NavigationTypeFormResubmitted; |
| 1666 if (isFormSubmission && | 1653 if (isFormSubmission && |
| 1667 !m_frame->document()->contentSecurityPolicy()->allowFormAction( | 1654 !m_frame->document()->contentSecurityPolicy()->allowFormAction( |
| 1668 request.url())) | 1655 request.url())) |
| 1669 return false; | 1656 return NavigationPolicyIgnore; |
| 1670 | 1657 |
| 1671 bool replacesCurrentHistoryItem = | 1658 bool replacesCurrentHistoryItem = |
| 1672 frameLoadType == FrameLoadTypeReplaceCurrentItem; | 1659 frameLoadType == FrameLoadTypeReplaceCurrentItem; |
| 1673 policy = client()->decidePolicyForNavigation(request, loader, type, policy, | 1660 policy = client()->decidePolicyForNavigation(request, loader, type, policy, |
| 1674 replacesCurrentHistoryItem, | 1661 replacesCurrentHistoryItem, |
| 1675 isClientRedirect, form); | 1662 isClientRedirect, form); |
| 1676 if (policy == NavigationPolicyCurrentTab) | 1663 if (policy == NavigationPolicyCurrentTab || |
| 1677 return true; | 1664 policy == NavigationPolicyIgnore || |
| 1678 if (policy == NavigationPolicyIgnore) | 1665 policy == NavigationPolicyHandledByClient || |
| 1679 return false; | 1666 policy == NavigationPolicyHandledByClientForInitialHistory) { |
| 1680 if (policy == NavigationPolicyHandledByClient) { | 1667 return policy; |
| 1681 setNavigationHandledByClient(); | 1668 } |
| 1682 // Mark the frame as loading since the embedder is handling the navigation. | |
| 1683 m_progressTracker->progressStarted(frameLoadType); | |
| 1684 | 1669 |
| 1685 m_frame->navigationScheduler().cancel(); | |
| 1686 | |
| 1687 // If this is a form submit, dispatch that a form is being submitted | |
| 1688 // since the embedder is handling the navigation. | |
| 1689 if (form) | |
| 1690 client()->dispatchWillSubmitForm(form); | |
| 1691 | |
| 1692 m_frame->document()->cancelParsing(); | |
| 1693 | |
| 1694 return false; | |
| 1695 } | |
| 1696 if (!LocalDOMWindow::allowPopUp(*m_frame) && | 1670 if (!LocalDOMWindow::allowPopUp(*m_frame) && |
| 1697 !UserGestureIndicator::utilizeUserGesture()) | 1671 !UserGestureIndicator::utilizeUserGesture()) |
| 1698 return false; | 1672 return NavigationPolicyIgnore; |
| 1699 client()->loadURLExternally(request, policy, String(), | 1673 client()->loadURLExternally(request, policy, String(), |
| 1700 replacesCurrentHistoryItem); | 1674 replacesCurrentHistoryItem); |
| 1701 return false; | 1675 return NavigationPolicyIgnore; |
| 1702 } | 1676 } |
| 1703 | 1677 |
| 1704 bool FrameLoader::checkLoadCanStart(FrameLoadRequest& frameLoadRequest, | 1678 NavigationPolicy FrameLoader::checkLoadCanStart( |
| 1705 FrameLoadType type, | 1679 FrameLoadRequest& frameLoadRequest, |
| 1706 NavigationPolicy navigationPolicy, | 1680 FrameLoadType type, |
| 1707 NavigationType navigationType) { | 1681 NavigationPolicy navigationPolicy, |
| 1682 NavigationType navigationType) { | |
| 1708 if (m_frame->document()->pageDismissalEventBeingDispatched() != | 1683 if (m_frame->document()->pageDismissalEventBeingDispatched() != |
| 1709 Document::NoDismissal) { | 1684 Document::NoDismissal) { |
| 1710 return false; | 1685 return NavigationPolicyIgnore; |
| 1711 } | 1686 } |
| 1712 | 1687 |
| 1713 // Record the latest requiredCSP value that will be used when sending this | 1688 // Record the latest requiredCSP value that will be used when sending this |
| 1714 // request. | 1689 // request. |
| 1715 ResourceRequest& resourceRequest = frameLoadRequest.resourceRequest(); | 1690 ResourceRequest& resourceRequest = frameLoadRequest.resourceRequest(); |
| 1716 recordLatestRequiredCSP(); | 1691 recordLatestRequiredCSP(); |
| 1717 modifyRequestForCSP(resourceRequest, nullptr); | 1692 modifyRequestForCSP(resourceRequest, nullptr); |
| 1718 | 1693 |
| 1719 if (!shouldContinueForNavigationPolicy( | 1694 return shouldContinueForNavigationPolicy( |
| 1720 resourceRequest, frameLoadRequest.substituteData(), nullptr, | 1695 resourceRequest, frameLoadRequest.substituteData(), nullptr, |
| 1721 frameLoadRequest.shouldCheckMainWorldContentSecurityPolicy(), | 1696 frameLoadRequest.shouldCheckMainWorldContentSecurityPolicy(), |
| 1722 navigationType, navigationPolicy, type, | 1697 navigationType, navigationPolicy, type, |
| 1723 frameLoadRequest.clientRedirect() == | 1698 frameLoadRequest.clientRedirect() == ClientRedirectPolicy::ClientRedirect, |
| 1724 ClientRedirectPolicy::ClientRedirect, | 1699 frameLoadRequest.form()); |
| 1725 frameLoadRequest.form())) { | |
| 1726 return false; | |
| 1727 } | |
| 1728 | |
| 1729 m_frame->document()->cancelParsing(); | |
| 1730 detachDocumentLoader(m_provisionalDocumentLoader); | |
| 1731 | |
| 1732 // beforeunload fired above, and detaching a DocumentLoader can fire events, | |
| 1733 // which can detach this frame. | |
| 1734 if (!m_frame->host()) | |
| 1735 return false; | |
| 1736 | |
| 1737 return true; | |
| 1738 } | 1700 } |
| 1739 | 1701 |
| 1740 void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, | 1702 void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, |
| 1741 FrameLoadType type, | 1703 FrameLoadType type, |
| 1742 NavigationPolicy navigationPolicy) { | 1704 NavigationPolicy navigationPolicy) { |
| 1743 DCHECK(client()->hasWebView()); | 1705 DCHECK(client()->hasWebView()); |
| 1744 ResourceRequest& resourceRequest = frameLoadRequest.resourceRequest(); | 1706 ResourceRequest& resourceRequest = frameLoadRequest.resourceRequest(); |
| 1745 NavigationType navigationType = determineNavigationType( | 1707 NavigationType navigationType = determineNavigationType( |
| 1746 type, resourceRequest.httpBody() || frameLoadRequest.form(), | 1708 type, resourceRequest.httpBody() || frameLoadRequest.form(), |
| 1747 frameLoadRequest.triggeringEvent()); | 1709 frameLoadRequest.triggeringEvent()); |
| 1748 resourceRequest.setRequestContext( | 1710 resourceRequest.setRequestContext( |
| 1749 determineRequestContextFromNavigationType(navigationType)); | 1711 determineRequestContextFromNavigationType(navigationType)); |
| 1750 resourceRequest.setFrameType(m_frame->isMainFrame() | 1712 resourceRequest.setFrameType(m_frame->isMainFrame() |
| 1751 ? WebURLRequest::FrameTypeTopLevel | 1713 ? WebURLRequest::FrameTypeTopLevel |
| 1752 : WebURLRequest::FrameTypeNested); | 1714 : WebURLRequest::FrameTypeNested); |
| 1753 | 1715 |
| 1754 if (!checkLoadCanStart(frameLoadRequest, type, navigationPolicy, | 1716 bool hadPlaceholderClientDocumentLoader = |
| 1755 navigationType)) { | 1717 m_provisionalDocumentLoader && !m_provisionalDocumentLoader->didStart(); |
| 1756 if (m_isNavigationHandledByClient) { | 1718 navigationPolicy = checkLoadCanStart(frameLoadRequest, type, navigationPolicy, |
| 1757 // PlzNavigate: if the navigation is a commit of a client-handled | 1719 navigationType); |
| 1758 // navigation, record that there is no longer a navigation handled by the | 1720 if (navigationPolicy == NavigationPolicyIgnore) { |
| 1759 // client. | 1721 if (hadPlaceholderClientDocumentLoader && |
| 1760 if (!frameLoadRequest.resourceRequest().checkForBrowserSideNavigation()) { | 1722 !resourceRequest.checkForBrowserSideNavigation()) { |
| 1761 clearNavigationHandledByClient(); | 1723 detachDocumentLoader(m_provisionalDocumentLoader); |
| 1762 } else { | |
| 1763 DocumentLoader* loader = createDocumentLoader( | |
| 1764 resourceRequest, frameLoadRequest, type, navigationType); | |
| 1765 // PlzNavigate: If the navigation is handled by the client, then the | |
| 1766 // didFinishDocumentLoad() event occurs before the | |
| 1767 // didStartProvisionalLoad() notification which occurs after the | |
| 1768 // navigation | |
| 1769 // is committed. This causes a number of layout tests to fail. We | |
| 1770 // workaround this by invoking the didStartProvisionalLoad() | |
| 1771 // notification | |
| 1772 // here. Consumers of the didStartProvisionalLoad() notification rely on | |
| 1773 // the provisional loader and save navigation state in it. We want to | |
| 1774 // avoid | |
| 1775 // this dependency on the provisional loader. For now we create a | |
| 1776 // temporary | |
| 1777 // loader and pass it to the didStartProvisionalLoad() function. | |
| 1778 // TODO(ananta) | |
| 1779 // We should get rid of the dependency on the DocumentLoader in | |
| 1780 // consumers | |
| 1781 // of | |
| 1782 // the didStartProvisionalLoad() notification. | |
| 1783 client()->dispatchDidStartProvisionalLoad(loader); | |
| 1784 DCHECK(loader); | |
| 1785 loader->setSentDidFinishLoad(); | |
| 1786 loader->detachFromFrame(); | |
| 1787 } | |
| 1788 } | 1724 } |
| 1789 return; | 1725 return; |
| 1790 } | 1726 } |
| 1791 | 1727 |
| 1728 // For PlzNavigate placeholder DocumentLoaders, don't send failure callbacks | |
| 1729 // for a placeholder simply being replaced with a new DocumentLoader. | |
| 1730 if (hadPlaceholderClientDocumentLoader) | |
| 1731 m_provisionalDocumentLoader->setSentDidFinishLoad(); | |
| 1732 m_frame->document()->cancelParsing(); | |
| 1733 detachDocumentLoader(m_provisionalDocumentLoader); | |
| 1734 | |
| 1735 // beforeunload fired above, and detaching a DocumentLoader can fire events, | |
| 1736 // which can detach this frame. | |
|
clamy
2017/03/02 14:37:18
How likely is it that detaching the DocumentLoader
Nate Chapin
2017/03/02 19:39:18
In my experience, the primary user of this feature
clamy
2017/03/03 13:45:34
My question here was about the brief interval of t
Nate Chapin
2017/03/03 20:19:14
I believe that is correct. Though the possibly of
| |
| 1737 if (!m_frame->host()) | |
| 1738 return; | |
| 1739 | |
| 1740 m_progressTracker->progressStarted(type); | |
|
clamy
2017/03/02 14:37:18
Can we now call this all the time? We had an issue
Nate Chapin
2017/03/02 19:39:18
Yes, see change to ProgressTracker.cpp. Alternatel
clamy
2017/03/03 13:45:34
Acknowledged.
| |
| 1741 // TODO(japhet): This case wants to flag the frame as loading and do nothing | |
| 1742 // else. It'd be nice if it could go through the placeholder DocumentLoader | |
| 1743 // path, too. | |
| 1744 if (navigationPolicy == NavigationPolicyHandledByClientForInitialHistory) | |
| 1745 return; | |
| 1746 DCHECK(navigationPolicy == NavigationPolicyCurrentTab || | |
| 1747 navigationPolicy == NavigationPolicyHandledByClient); | |
| 1748 | |
| 1792 m_provisionalDocumentLoader = createDocumentLoader( | 1749 m_provisionalDocumentLoader = createDocumentLoader( |
| 1793 resourceRequest, frameLoadRequest, type, navigationType); | 1750 resourceRequest, frameLoadRequest, type, navigationType); |
| 1794 | 1751 |
| 1795 // PlzNavigate: We need to ensure that script initiated navigations are | 1752 // PlzNavigate: We need to ensure that script initiated navigations are |
| 1796 // honored. | 1753 // honored. |
| 1797 if (!m_isNavigationHandledByClient) { | 1754 if (!hadPlaceholderClientDocumentLoader || |
| 1755 navigationPolicy == NavigationPolicyHandledByClient) { | |
| 1798 m_frame->navigationScheduler().cancel(); | 1756 m_frame->navigationScheduler().cancel(); |
| 1799 m_checkTimer.stop(); | 1757 m_checkTimer.stop(); |
| 1800 } | 1758 } |
| 1801 | 1759 |
| 1802 if (frameLoadRequest.form()) | 1760 if (frameLoadRequest.form()) |
| 1803 client()->dispatchWillSubmitForm(frameLoadRequest.form()); | 1761 client()->dispatchWillSubmitForm(frameLoadRequest.form()); |
| 1804 | 1762 |
| 1805 bool isNavigationHandledByClient = m_isNavigationHandledByClient; | |
| 1806 // If the loader wasn't waiting for the client to handle a navigation, update | |
| 1807 // the progress tracker. Otherwise don't, as it was already notified before | |
| 1808 // sending the navigation to teh client. | |
| 1809 if (!m_isNavigationHandledByClient) | |
| 1810 m_progressTracker->progressStarted(type); | |
| 1811 else | |
| 1812 m_isNavigationHandledByClient = false; | |
| 1813 | |
| 1814 m_provisionalDocumentLoader->appendRedirect( | 1763 m_provisionalDocumentLoader->appendRedirect( |
| 1815 m_provisionalDocumentLoader->getRequest().url()); | 1764 m_provisionalDocumentLoader->getRequest().url()); |
| 1816 // TODO(ananta) | 1765 // TODO(ananta): |
| 1817 // We should get rid of the dependency on the DocumentLoader in consumers of | 1766 // We should get rid of the dependency on the DocumentLoader in consumers of |
| 1818 // the didStartProvisionalLoad() notification. | 1767 // the didStartProvisionalLoad() notification. |
| 1819 client()->dispatchDidStartProvisionalLoad(m_provisionalDocumentLoader); | 1768 client()->dispatchDidStartProvisionalLoad(m_provisionalDocumentLoader); |
| 1820 DCHECK(m_provisionalDocumentLoader); | 1769 DCHECK(m_provisionalDocumentLoader); |
| 1821 | 1770 |
| 1822 m_provisionalDocumentLoader->startLoadingMainResource(); | 1771 if (navigationPolicy == NavigationPolicyCurrentTab) { |
| 1823 | 1772 m_provisionalDocumentLoader->startLoadingMainResource(); |
| 1824 // This should happen after the request is sent, so we don't use | 1773 // This should happen after the request is sent, so that the state |
| 1825 // clearNavigationHandledByClient() above. | 1774 // the inspector stored in the matching frameScheduledClientNavigation() |
| 1826 if (isNavigationHandledByClient) | 1775 // is available while sending the request. |
| 1827 InspectorInstrumentation::frameClearedScheduledClientNavigation(m_frame); | 1776 InspectorInstrumentation::frameClearedScheduledClientNavigation(m_frame); |
| 1777 } else { | |
| 1778 InspectorInstrumentation::frameScheduledClientNavigation(m_frame); | |
| 1779 } | |
| 1828 | 1780 |
| 1829 takeObjectSnapshot(); | 1781 takeObjectSnapshot(); |
| 1830 } | 1782 } |
| 1831 | 1783 |
| 1832 void FrameLoader::applyUserAgent(ResourceRequest& request) { | 1784 void FrameLoader::applyUserAgent(ResourceRequest& request) { |
| 1833 String userAgent = this->userAgent(); | 1785 String userAgent = this->userAgent(); |
| 1834 DCHECK(!userAgent.isNull()); | 1786 DCHECK(!userAgent.isNull()); |
| 1835 request.setHTTPUserAgent(AtomicString(userAgent)); | 1787 request.setHTTPUserAgent(AtomicString(userAgent)); |
| 1836 } | 1788 } |
| 1837 | 1789 |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2025 : defaultSubstituteDataForURL(request.url()), | 1977 : defaultSubstituteDataForURL(request.url()), |
| 2026 frameLoadRequest.clientRedirect()); | 1978 frameLoadRequest.clientRedirect()); |
| 2027 | 1979 |
| 2028 loader->setLoadType(loadType); | 1980 loader->setLoadType(loadType); |
| 2029 loader->setNavigationType(navigationType); | 1981 loader->setNavigationType(navigationType); |
| 2030 loader->setReplacesCurrentHistoryItem(loadType == | 1982 loader->setReplacesCurrentHistoryItem(loadType == |
| 2031 FrameLoadTypeReplaceCurrentItem); | 1983 FrameLoadTypeReplaceCurrentItem); |
| 2032 return loader; | 1984 return loader; |
| 2033 } | 1985 } |
| 2034 | 1986 |
| 2035 void FrameLoader::setNavigationHandledByClient() { | |
| 2036 m_isNavigationHandledByClient = true; | |
| 2037 InspectorInstrumentation::frameScheduledClientNavigation(m_frame); | |
| 2038 } | |
| 2039 | |
| 2040 void FrameLoader::clearNavigationHandledByClient() { | |
| 2041 m_isNavigationHandledByClient = false; | |
| 2042 InspectorInstrumentation::frameClearedScheduledClientNavigation(m_frame); | |
| 2043 } | |
| 2044 | |
| 2045 } // namespace blink | 1987 } // namespace blink |
| OLD | NEW |