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 // If we are still in the process of initializing an empty document then its | 1376 // If we are still in the process of initializing an empty document then its |
1392 // frame is not in a consistent state for rendering, so avoid | 1377 // frame is not in a consistent state for rendering, so avoid |
1393 // setJSStatusBarText since it may cause clients to attempt to render the | 1378 // setJSStatusBarText since it may cause clients to attempt to render the |
1394 // frame. | 1379 // frame. |
1395 if (!m_stateMachine.creatingInitialEmptyDocument()) { | 1380 if (!m_stateMachine.creatingInitialEmptyDocument()) { |
1396 LocalDOMWindow* window = m_frame->domWindow(); | 1381 LocalDOMWindow* window = m_frame->domWindow(); |
1397 window->setStatus(String()); | 1382 window->setStatus(String()); |
1398 window->setDefaultStatus(String()); | 1383 window->setDefaultStatus(String()); |
1399 } | 1384 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1506 const ResourceError& error) { | 1491 const ResourceError& error) { |
1507 if (!error.isCancellation() && m_frame->owner()) { | 1492 if (!error.isCancellation() && m_frame->owner()) { |
1508 // FIXME: For now, fallback content doesn't work cross process. | 1493 // FIXME: For now, fallback content doesn't work cross process. |
1509 if (m_frame->owner()->isLocal()) | 1494 if (m_frame->owner()->isLocal()) |
1510 m_frame->deprecatedLocalOwner()->renderFallbackContent(); | 1495 m_frame->deprecatedLocalOwner()->renderFallbackContent(); |
1511 } | 1496 } |
1512 | 1497 |
1513 HistoryCommitType historyCommitType = | 1498 HistoryCommitType historyCommitType = |
1514 loadTypeToCommitType(loader->loadType()); | 1499 loadTypeToCommitType(loader->loadType()); |
1515 if (loader == m_provisionalDocumentLoader) { | 1500 if (loader == m_provisionalDocumentLoader) { |
| 1501 if (!m_provisionalDocumentLoader->didStart()) |
| 1502 probe::frameClearedScheduledClientNavigation(m_frame); |
1516 m_provisionalDocumentLoader->setSentDidFinishLoad(); | 1503 m_provisionalDocumentLoader->setSentDidFinishLoad(); |
1517 client()->dispatchDidFailProvisionalLoad(error, historyCommitType); | 1504 client()->dispatchDidFailProvisionalLoad(error, historyCommitType); |
1518 if (loader != m_provisionalDocumentLoader) | 1505 if (loader != m_provisionalDocumentLoader) |
1519 return; | 1506 return; |
1520 detachDocumentLoader(m_provisionalDocumentLoader); | 1507 detachDocumentLoader(m_provisionalDocumentLoader); |
1521 } else { | 1508 } else { |
1522 DCHECK_EQ(loader, m_documentLoader); | 1509 DCHECK_EQ(loader, m_documentLoader); |
1523 if (m_frame->document()->parser()) | 1510 if (m_frame->document()->parser()) |
1524 m_frame->document()->parser()->stopParsing(); | 1511 m_frame->document()->parser()->stopParsing(); |
1525 if (!m_documentLoader->sentDidFinishLoad()) { | 1512 if (!m_documentLoader->sentDidFinishLoad()) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1617 break; | 1604 break; |
1618 } | 1605 } |
1619 | 1606 |
1620 if (i == targetFrames.size()) | 1607 if (i == targetFrames.size()) |
1621 shouldClose = true; | 1608 shouldClose = true; |
1622 } | 1609 } |
1623 | 1610 |
1624 return shouldClose; | 1611 return shouldClose; |
1625 } | 1612 } |
1626 | 1613 |
1627 bool FrameLoader::shouldContinueForNavigationPolicy( | 1614 NavigationPolicy FrameLoader::shouldContinueForNavigationPolicy( |
1628 const ResourceRequest& request, | 1615 const ResourceRequest& request, |
1629 const SubstituteData& substituteData, | 1616 const SubstituteData& substituteData, |
1630 DocumentLoader* loader, | 1617 DocumentLoader* loader, |
1631 ContentSecurityPolicyDisposition shouldCheckMainWorldContentSecurityPolicy, | 1618 ContentSecurityPolicyDisposition shouldCheckMainWorldContentSecurityPolicy, |
1632 NavigationType type, | 1619 NavigationType type, |
1633 NavigationPolicy policy, | 1620 NavigationPolicy policy, |
1634 FrameLoadType frameLoadType, | 1621 FrameLoadType frameLoadType, |
1635 bool isClientRedirect, | 1622 bool isClientRedirect, |
1636 HTMLFormElement* form) { | 1623 HTMLFormElement* form) { |
1637 // Don't ask if we are loading an empty URL. | 1624 // Don't ask if we are loading an empty URL. |
1638 if (request.url().isEmpty() || substituteData.isValid()) | 1625 if (request.url().isEmpty() || substituteData.isValid()) |
1639 return true; | 1626 return NavigationPolicyCurrentTab; |
1640 | 1627 |
1641 // If we're loading content into |m_frame| (NavigationPolicyCurrentTab), check | 1628 // If we're loading content into |m_frame| (NavigationPolicyCurrentTab), check |
1642 // against the parent's Content Security Policy and kill the load if that | 1629 // against the parent's Content Security Policy and kill the load if that |
1643 // check fails, unless we should bypass the main world's CSP. | 1630 // check fails, unless we should bypass the main world's CSP. |
1644 if (policy == NavigationPolicyCurrentTab && | 1631 if (policy == NavigationPolicyCurrentTab && |
1645 shouldCheckMainWorldContentSecurityPolicy == CheckContentSecurityPolicy) { | 1632 shouldCheckMainWorldContentSecurityPolicy == CheckContentSecurityPolicy) { |
1646 Frame* parentFrame = m_frame->tree().parent(); | 1633 Frame* parentFrame = m_frame->tree().parent(); |
1647 if (parentFrame) { | 1634 if (parentFrame) { |
1648 ContentSecurityPolicy* parentPolicy = | 1635 ContentSecurityPolicy* parentPolicy = |
1649 parentFrame->securityContext()->contentSecurityPolicy(); | 1636 parentFrame->securityContext()->contentSecurityPolicy(); |
1650 if (!parentPolicy->allowFrameFromSource(request.url(), | 1637 if (!parentPolicy->allowFrameFromSource(request.url(), |
1651 request.redirectStatus())) { | 1638 request.redirectStatus())) { |
1652 // Fire a load event, as timing attacks would otherwise reveal that the | 1639 // Fire a load event, as timing attacks would otherwise reveal that the |
1653 // frame was blocked. This way, it looks like every other cross-origin | 1640 // frame was blocked. This way, it looks like every other cross-origin |
1654 // page load. | 1641 // page load. |
1655 m_frame->document()->enforceSandboxFlags(SandboxOrigin); | 1642 m_frame->document()->enforceSandboxFlags(SandboxOrigin); |
1656 m_frame->owner()->dispatchLoad(); | 1643 m_frame->owner()->dispatchLoad(); |
1657 return false; | 1644 return NavigationPolicyIgnore; |
1658 } | 1645 } |
1659 } | 1646 } |
1660 } | 1647 } |
1661 | 1648 |
1662 bool isFormSubmission = type == NavigationTypeFormSubmitted || | 1649 bool isFormSubmission = type == NavigationTypeFormSubmitted || |
1663 type == NavigationTypeFormResubmitted; | 1650 type == NavigationTypeFormResubmitted; |
1664 if (isFormSubmission && | 1651 if (isFormSubmission && |
1665 !m_frame->document()->contentSecurityPolicy()->allowFormAction( | 1652 !m_frame->document()->contentSecurityPolicy()->allowFormAction( |
1666 request.url())) | 1653 request.url())) |
1667 return false; | 1654 return NavigationPolicyIgnore; |
1668 | 1655 |
1669 bool replacesCurrentHistoryItem = | 1656 bool replacesCurrentHistoryItem = |
1670 frameLoadType == FrameLoadTypeReplaceCurrentItem; | 1657 frameLoadType == FrameLoadTypeReplaceCurrentItem; |
1671 policy = client()->decidePolicyForNavigation(request, loader, type, policy, | 1658 policy = client()->decidePolicyForNavigation(request, loader, type, policy, |
1672 replacesCurrentHistoryItem, | 1659 replacesCurrentHistoryItem, |
1673 isClientRedirect, form); | 1660 isClientRedirect, form); |
1674 if (policy == NavigationPolicyCurrentTab) | 1661 if (policy == NavigationPolicyCurrentTab || |
1675 return true; | 1662 policy == NavigationPolicyIgnore || |
1676 if (policy == NavigationPolicyIgnore) | 1663 policy == NavigationPolicyHandledByClient || |
1677 return false; | 1664 policy == NavigationPolicyHandledByClientForInitialHistory) { |
1678 if (policy == NavigationPolicyHandledByClient) { | 1665 return policy; |
1679 setNavigationHandledByClient(); | 1666 } |
1680 // Mark the frame as loading since the embedder is handling the navigation. | |
1681 m_progressTracker->progressStarted(frameLoadType); | |
1682 | 1667 |
1683 m_frame->navigationScheduler().cancel(); | |
1684 | |
1685 // If this is a form submit, dispatch that a form is being submitted | |
1686 // since the embedder is handling the navigation. | |
1687 if (form) | |
1688 client()->dispatchWillSubmitForm(form); | |
1689 | |
1690 m_frame->document()->cancelParsing(); | |
1691 | |
1692 return false; | |
1693 } | |
1694 if (!LocalDOMWindow::allowPopUp(*m_frame) && | 1668 if (!LocalDOMWindow::allowPopUp(*m_frame) && |
1695 !UserGestureIndicator::utilizeUserGesture()) | 1669 !UserGestureIndicator::utilizeUserGesture()) |
1696 return false; | 1670 return NavigationPolicyIgnore; |
1697 client()->loadURLExternally(request, policy, String(), | 1671 client()->loadURLExternally(request, policy, String(), |
1698 replacesCurrentHistoryItem); | 1672 replacesCurrentHistoryItem); |
1699 return false; | 1673 return NavigationPolicyIgnore; |
1700 } | 1674 } |
1701 | 1675 |
1702 bool FrameLoader::checkLoadCanStart(FrameLoadRequest& frameLoadRequest, | 1676 NavigationPolicy FrameLoader::checkLoadCanStart( |
1703 FrameLoadType type, | 1677 FrameLoadRequest& frameLoadRequest, |
1704 NavigationPolicy navigationPolicy, | 1678 FrameLoadType type, |
1705 NavigationType navigationType) { | 1679 NavigationPolicy navigationPolicy, |
| 1680 NavigationType navigationType) { |
1706 if (m_frame->document()->pageDismissalEventBeingDispatched() != | 1681 if (m_frame->document()->pageDismissalEventBeingDispatched() != |
1707 Document::NoDismissal) { | 1682 Document::NoDismissal) { |
1708 return false; | 1683 return NavigationPolicyIgnore; |
1709 } | 1684 } |
1710 | 1685 |
1711 // Record the latest requiredCSP value that will be used when sending this | 1686 // Record the latest requiredCSP value that will be used when sending this |
1712 // request. | 1687 // request. |
1713 ResourceRequest& resourceRequest = frameLoadRequest.resourceRequest(); | 1688 ResourceRequest& resourceRequest = frameLoadRequest.resourceRequest(); |
1714 recordLatestRequiredCSP(); | 1689 recordLatestRequiredCSP(); |
1715 modifyRequestForCSP(resourceRequest, nullptr); | 1690 modifyRequestForCSP(resourceRequest, nullptr); |
1716 | 1691 |
1717 if (!shouldContinueForNavigationPolicy( | 1692 return shouldContinueForNavigationPolicy( |
1718 resourceRequest, frameLoadRequest.substituteData(), nullptr, | 1693 resourceRequest, frameLoadRequest.substituteData(), nullptr, |
1719 frameLoadRequest.shouldCheckMainWorldContentSecurityPolicy(), | 1694 frameLoadRequest.shouldCheckMainWorldContentSecurityPolicy(), |
1720 navigationType, navigationPolicy, type, | 1695 navigationType, navigationPolicy, type, |
1721 frameLoadRequest.clientRedirect() == | 1696 frameLoadRequest.clientRedirect() == ClientRedirectPolicy::ClientRedirect, |
1722 ClientRedirectPolicy::ClientRedirect, | 1697 frameLoadRequest.form()); |
1723 frameLoadRequest.form())) { | |
1724 return false; | |
1725 } | |
1726 | |
1727 m_frame->document()->cancelParsing(); | |
1728 detachDocumentLoader(m_provisionalDocumentLoader); | |
1729 | |
1730 // beforeunload fired above, and detaching a DocumentLoader can fire events, | |
1731 // which can detach this frame. | |
1732 if (!m_frame->host()) | |
1733 return false; | |
1734 | |
1735 return true; | |
1736 } | 1698 } |
1737 | 1699 |
1738 void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, | 1700 void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, |
1739 FrameLoadType type, | 1701 FrameLoadType type, |
1740 NavigationPolicy navigationPolicy) { | 1702 NavigationPolicy navigationPolicy) { |
1741 DCHECK(client()->hasWebView()); | 1703 DCHECK(client()->hasWebView()); |
1742 ResourceRequest& resourceRequest = frameLoadRequest.resourceRequest(); | 1704 ResourceRequest& resourceRequest = frameLoadRequest.resourceRequest(); |
1743 NavigationType navigationType = determineNavigationType( | 1705 NavigationType navigationType = determineNavigationType( |
1744 type, resourceRequest.httpBody() || frameLoadRequest.form(), | 1706 type, resourceRequest.httpBody() || frameLoadRequest.form(), |
1745 frameLoadRequest.triggeringEvent()); | 1707 frameLoadRequest.triggeringEvent()); |
1746 resourceRequest.setRequestContext( | 1708 resourceRequest.setRequestContext( |
1747 determineRequestContextFromNavigationType(navigationType)); | 1709 determineRequestContextFromNavigationType(navigationType)); |
1748 resourceRequest.setFrameType(m_frame->isMainFrame() | 1710 resourceRequest.setFrameType(m_frame->isMainFrame() |
1749 ? WebURLRequest::FrameTypeTopLevel | 1711 ? WebURLRequest::FrameTypeTopLevel |
1750 : WebURLRequest::FrameTypeNested); | 1712 : WebURLRequest::FrameTypeNested); |
1751 | 1713 |
1752 if (!checkLoadCanStart(frameLoadRequest, type, navigationPolicy, | 1714 bool hadPlaceholderClientDocumentLoader = |
1753 navigationType)) { | 1715 m_provisionalDocumentLoader && !m_provisionalDocumentLoader->didStart(); |
1754 if (m_isNavigationHandledByClient) { | 1716 navigationPolicy = checkLoadCanStart(frameLoadRequest, type, navigationPolicy, |
1755 // PlzNavigate: if the navigation is a commit of a client-handled | 1717 navigationType); |
1756 // navigation, record that there is no longer a navigation handled by the | 1718 if (navigationPolicy == NavigationPolicyIgnore) { |
1757 // client. | 1719 if (hadPlaceholderClientDocumentLoader && |
1758 if (!frameLoadRequest.resourceRequest().checkForBrowserSideNavigation()) { | 1720 !resourceRequest.checkForBrowserSideNavigation()) { |
1759 clearNavigationHandledByClient(); | 1721 detachDocumentLoader(m_provisionalDocumentLoader); |
1760 } else { | |
1761 DocumentLoader* loader = createDocumentLoader( | |
1762 resourceRequest, frameLoadRequest, type, navigationType); | |
1763 // PlzNavigate: If the navigation is handled by the client, then the | |
1764 // didFinishDocumentLoad() event occurs before the | |
1765 // didStartProvisionalLoad() notification which occurs after the | |
1766 // navigation | |
1767 // is committed. This causes a number of layout tests to fail. We | |
1768 // workaround this by invoking the didStartProvisionalLoad() | |
1769 // notification | |
1770 // here. Consumers of the didStartProvisionalLoad() notification rely on | |
1771 // the provisional loader and save navigation state in it. We want to | |
1772 // avoid | |
1773 // this dependency on the provisional loader. For now we create a | |
1774 // temporary | |
1775 // loader and pass it to the didStartProvisionalLoad() function. | |
1776 // TODO(ananta) | |
1777 // We should get rid of the dependency on the DocumentLoader in | |
1778 // consumers | |
1779 // of | |
1780 // the didStartProvisionalLoad() notification. | |
1781 client()->dispatchDidStartProvisionalLoad(loader); | |
1782 DCHECK(loader); | |
1783 loader->setSentDidFinishLoad(); | |
1784 loader->detachFromFrame(); | |
1785 } | |
1786 } | 1722 } |
1787 return; | 1723 return; |
1788 } | 1724 } |
1789 | 1725 |
| 1726 // For PlzNavigate placeholder DocumentLoaders, don't send failure callbacks |
| 1727 // for a placeholder simply being replaced with a new DocumentLoader. |
| 1728 if (hadPlaceholderClientDocumentLoader) |
| 1729 m_provisionalDocumentLoader->setSentDidFinishLoad(); |
| 1730 m_frame->document()->cancelParsing(); |
| 1731 detachDocumentLoader(m_provisionalDocumentLoader); |
| 1732 |
| 1733 // beforeunload fired above, and detaching a DocumentLoader can fire events, |
| 1734 // which can detach this frame. |
| 1735 if (!m_frame->host()) |
| 1736 return; |
| 1737 |
| 1738 m_progressTracker->progressStarted(type); |
| 1739 // TODO(japhet): This case wants to flag the frame as loading and do nothing |
| 1740 // else. It'd be nice if it could go through the placeholder DocumentLoader |
| 1741 // path, too. |
| 1742 if (navigationPolicy == NavigationPolicyHandledByClientForInitialHistory) |
| 1743 return; |
| 1744 DCHECK(navigationPolicy == NavigationPolicyCurrentTab || |
| 1745 navigationPolicy == NavigationPolicyHandledByClient); |
| 1746 |
1790 m_provisionalDocumentLoader = createDocumentLoader( | 1747 m_provisionalDocumentLoader = createDocumentLoader( |
1791 resourceRequest, frameLoadRequest, type, navigationType); | 1748 resourceRequest, frameLoadRequest, type, navigationType); |
1792 | 1749 |
1793 // PlzNavigate: We need to ensure that script initiated navigations are | 1750 // PlzNavigate: We need to ensure that script initiated navigations are |
1794 // honored. | 1751 // honored. |
1795 if (!m_isNavigationHandledByClient) { | 1752 if (!hadPlaceholderClientDocumentLoader || |
| 1753 navigationPolicy == NavigationPolicyHandledByClient) { |
1796 m_frame->navigationScheduler().cancel(); | 1754 m_frame->navigationScheduler().cancel(); |
1797 m_checkTimer.stop(); | 1755 m_checkTimer.stop(); |
1798 } | 1756 } |
1799 | 1757 |
1800 if (frameLoadRequest.form()) | 1758 if (frameLoadRequest.form()) |
1801 client()->dispatchWillSubmitForm(frameLoadRequest.form()); | 1759 client()->dispatchWillSubmitForm(frameLoadRequest.form()); |
1802 | 1760 |
1803 bool isNavigationHandledByClient = m_isNavigationHandledByClient; | |
1804 // If the loader wasn't waiting for the client to handle a navigation, update | |
1805 // the progress tracker. Otherwise don't, as it was already notified before | |
1806 // sending the navigation to teh client. | |
1807 if (!m_isNavigationHandledByClient) | |
1808 m_progressTracker->progressStarted(type); | |
1809 else | |
1810 m_isNavigationHandledByClient = false; | |
1811 | |
1812 m_provisionalDocumentLoader->appendRedirect( | 1761 m_provisionalDocumentLoader->appendRedirect( |
1813 m_provisionalDocumentLoader->getRequest().url()); | 1762 m_provisionalDocumentLoader->getRequest().url()); |
1814 // TODO(ananta) | 1763 // TODO(ananta): |
1815 // We should get rid of the dependency on the DocumentLoader in consumers of | 1764 // We should get rid of the dependency on the DocumentLoader in consumers of |
1816 // the didStartProvisionalLoad() notification. | 1765 // the didStartProvisionalLoad() notification. |
1817 client()->dispatchDidStartProvisionalLoad(m_provisionalDocumentLoader); | 1766 client()->dispatchDidStartProvisionalLoad(m_provisionalDocumentLoader); |
1818 DCHECK(m_provisionalDocumentLoader); | 1767 DCHECK(m_provisionalDocumentLoader); |
1819 | 1768 |
1820 m_provisionalDocumentLoader->startLoadingMainResource(); | 1769 if (navigationPolicy == NavigationPolicyCurrentTab) { |
1821 | 1770 m_provisionalDocumentLoader->startLoadingMainResource(); |
1822 // This should happen after the request is sent, so we don't use | 1771 // This should happen after the request is sent, so that the state |
1823 // clearNavigationHandledByClient() above. | 1772 // the inspector stored in the matching frameScheduledClientNavigation() |
1824 if (isNavigationHandledByClient) | 1773 // is available while sending the request. |
1825 probe::frameClearedScheduledClientNavigation(m_frame); | 1774 probe::frameClearedScheduledClientNavigation(m_frame); |
| 1775 } else { |
| 1776 probe::frameScheduledClientNavigation(m_frame); |
| 1777 } |
1826 | 1778 |
1827 takeObjectSnapshot(); | 1779 takeObjectSnapshot(); |
1828 } | 1780 } |
1829 | 1781 |
1830 void FrameLoader::applyUserAgent(ResourceRequest& request) { | 1782 void FrameLoader::applyUserAgent(ResourceRequest& request) { |
1831 String userAgent = this->userAgent(); | 1783 String userAgent = this->userAgent(); |
1832 DCHECK(!userAgent.isNull()); | 1784 DCHECK(!userAgent.isNull()); |
1833 request.setHTTPUserAgent(AtomicString(userAgent)); | 1785 request.setHTTPUserAgent(AtomicString(userAgent)); |
1834 } | 1786 } |
1835 | 1787 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2023 : defaultSubstituteDataForURL(request.url()), | 1975 : defaultSubstituteDataForURL(request.url()), |
2024 frameLoadRequest.clientRedirect()); | 1976 frameLoadRequest.clientRedirect()); |
2025 | 1977 |
2026 loader->setLoadType(loadType); | 1978 loader->setLoadType(loadType); |
2027 loader->setNavigationType(navigationType); | 1979 loader->setNavigationType(navigationType); |
2028 loader->setReplacesCurrentHistoryItem(loadType == | 1980 loader->setReplacesCurrentHistoryItem(loadType == |
2029 FrameLoadTypeReplaceCurrentItem); | 1981 FrameLoadTypeReplaceCurrentItem); |
2030 return loader; | 1982 return loader; |
2031 } | 1983 } |
2032 | 1984 |
2033 void FrameLoader::setNavigationHandledByClient() { | |
2034 m_isNavigationHandledByClient = true; | |
2035 probe::frameScheduledClientNavigation(m_frame); | |
2036 } | |
2037 | |
2038 void FrameLoader::clearNavigationHandledByClient() { | |
2039 m_isNavigationHandledByClient = false; | |
2040 probe::frameClearedScheduledClientNavigation(m_frame); | |
2041 } | |
2042 | |
2043 } // namespace blink | 1985 } // namespace blink |
OLD | NEW |