summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/FrameLoader.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/loader/FrameLoader.cpp
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/WebCore/loader/FrameLoader.cpp')
-rw-r--r--Source/WebCore/loader/FrameLoader.cpp1380
1 files changed, 628 insertions, 752 deletions
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index 5ca806300..c3cc3c559 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -12,13 +12,13 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -43,12 +43,11 @@
#include "CachedResourceLoader.h"
#include "Chrome.h"
#include "ChromeClient.h"
+#include "Console.h"
#include "ContentSecurityPolicy.h"
#include "DOMImplementation.h"
#include "DOMWindow.h"
#include "DatabaseManager.h"
-#include "DiagnosticLoggingClient.h"
-#include "DiagnosticLoggingKeys.h"
#include "Document.h"
#include "DocumentLoadTiming.h"
#include "DocumentLoader.h"
@@ -66,19 +65,16 @@
#include "FrameNetworkingContext.h"
#include "FrameTree.h"
#include "FrameView.h"
-#include "GCController.h"
#include "HTMLAnchorElement.h"
#include "HTMLFormElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "HTMLObjectElement.h"
#include "HTMLParserIdioms.h"
-#include "HTTPHeaderNames.h"
#include "HTTPParsers.h"
#include "HistoryController.h"
#include "HistoryItem.h"
#include "IconController.h"
-#include "IgnoreOpensDuringUnloadCountIncrementer.h"
#include "InspectorController.h"
#include "InspectorInstrumentation.h"
#include "LoaderStrategy.h"
@@ -86,24 +82,20 @@
#include "MIMETypeRegistry.h"
#include "MainFrame.h"
#include "MemoryCache.h"
+#include "Page.h"
+#include "PageActivityAssertionToken.h"
#include "PageCache.h"
-#include "PageThrottler.h"
#include "PageTransitionEvent.h"
#include "PlatformStrategies.h"
#include "PluginData.h"
+#include "PluginDatabase.h"
#include "PluginDocument.h"
#include "PolicyChecker.h"
#include "ProgressTracker.h"
#include "ResourceHandle.h"
-#include "ResourceLoadInfo.h"
#include "ResourceRequest.h"
-#include "SVGDocument.h"
-#include "SVGLocatable.h"
-#include "SVGNames.h"
-#include "SVGPreserveAspectRatio.h"
-#include "SVGViewElement.h"
-#include "SVGViewSpec.h"
#include "SchemeRegistry.h"
+#include "ScriptCallStack.h"
#include "ScriptController.h"
#include "ScriptSourceCode.h"
#include "ScrollAnimator.h"
@@ -114,7 +106,6 @@
#include "Settings.h"
#include "SubframeLoader.h"
#include "TextResourceDecoder.h"
-#include "UserContentController.h"
#include "WindowFeatures.h"
#include "XMLDocumentParser.h"
#include <wtf/CurrentTime.h>
@@ -123,12 +114,22 @@
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
-#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
-#include "Archive.h"
+#if ENABLE(SHARED_WORKERS)
+#include "SharedWorkerRepository.h"
#endif
-#if ENABLE(DATA_DETECTION)
-#include "DataDetection.h"
+#if ENABLE(SVG)
+#include "SVGDocument.h"
+#include "SVGLocatable.h"
+#include "SVGNames.h"
+#include "SVGPreserveAspectRatio.h"
+#include "SVGSVGElement.h"
+#include "SVGViewElement.h"
+#include "SVGViewSpec.h"
+#endif
+
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
+#include "Archive.h"
#endif
#if PLATFORM(IOS)
@@ -143,7 +144,10 @@
namespace WebCore {
using namespace HTMLNames;
+
+#if ENABLE(SVG)
using namespace SVGNames;
+#endif
static const char defaultAcceptHeader[] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
@@ -154,17 +158,17 @@ const int memoryLevelThresholdToPrunePageCache = 20;
bool isBackForwardLoadType(FrameLoadType type)
{
switch (type) {
- case FrameLoadType::Standard:
- case FrameLoadType::Reload:
- case FrameLoadType::ReloadFromOrigin:
- case FrameLoadType::Same:
- case FrameLoadType::RedirectWithLockedBackForwardList:
- case FrameLoadType::Replace:
- return false;
- case FrameLoadType::Back:
- case FrameLoadType::Forward:
- case FrameLoadType::IndexedBackForward:
- return true;
+ case FrameLoadTypeStandard:
+ case FrameLoadTypeReload:
+ case FrameLoadTypeReloadFromOrigin:
+ case FrameLoadTypeSame:
+ case FrameLoadTypeRedirectWithLockedBackForwardList:
+ case FrameLoadTypeReplace:
+ return false;
+ case FrameLoadTypeBack:
+ case FrameLoadTypeForward:
+ case FrameLoadTypeIndexedBackForward:
+ return true;
}
ASSERT_NOT_REACHED();
return false;
@@ -176,29 +180,11 @@ bool isBackForwardLoadType(FrameLoadType type)
// non-member lets us exclude it from the header file, thus keeping FrameLoader.h's
// API simpler.
//
-static bool isDocumentSandboxed(Frame& frame, SandboxFlags mask)
+static bool isDocumentSandboxed(Frame* frame, SandboxFlags mask)
{
- return frame.document() && frame.document()->isSandboxed(mask);
+ return frame->document() && frame->document()->isSandboxed(mask);
}
-struct ForbidPromptsScope {
- ForbidPromptsScope(Page* page) : m_page(page)
- {
- if (!m_page)
- return;
- m_page->forbidPrompts();
- }
-
- ~ForbidPromptsScope()
- {
- if (!m_page)
- return;
- m_page->allowPrompts();
- }
-
- Page* m_page;
-};
-
class FrameLoader::FrameProgressTracker {
public:
explicit FrameProgressTracker(Frame& frame)
@@ -244,20 +230,23 @@ FrameLoader::FrameLoader(Frame& frame, FrameLoaderClient& client)
, m_icon(std::make_unique<IconController>(frame))
, m_mixedContentChecker(frame)
, m_state(FrameStateProvisional)
- , m_loadType(FrameLoadType::Standard)
+ , m_loadType(FrameLoadTypeStandard)
+ , m_delegateIsHandlingProvisionalLoadError(false)
, m_quickRedirectComing(false)
, m_sentRedirectNotification(false)
, m_inStopAllLoaders(false)
, m_isExecutingJavaScriptFormAction(false)
, m_didCallImplicitClose(true)
, m_wasUnloadEventEmitted(false)
+ , m_pageDismissalEventBeingDispatched(NoDismissal)
, m_isComplete(false)
, m_needsClear(false)
- , m_checkTimer(*this, &FrameLoader::checkTimerFired)
+ , m_checkTimer(this, &FrameLoader::checkTimerFired)
, m_shouldCallCheckCompleted(false)
, m_shouldCallCheckLoadComplete(false)
, m_opener(nullptr)
, m_loadingFromCachedPage(false)
+ , m_suppressOpenerInNewFrame(false)
, m_currentNavigationHasShownBeforeUnloadConfirmPanel(false)
, m_loadsSynchronously(false)
, m_forcedSandboxFlags(SandboxNone)
@@ -268,8 +257,9 @@ FrameLoader::~FrameLoader()
{
setOpener(nullptr);
- for (auto& frame : m_openedFrames)
- frame->loader().m_opener = nullptr;
+ HashSet<Frame*>::iterator end = m_openedFrames.end();
+ for (HashSet<Frame*>::iterator it = m_openedFrames.begin(); it != end; ++it)
+ (*it)->loader().m_opener = 0;
m_client.frameLoaderDestroyed();
@@ -280,7 +270,7 @@ FrameLoader::~FrameLoader()
void FrameLoader::init()
{
// This somewhat odd set of steps gives the frame an initial empty document.
- setPolicyDocumentLoader(m_client.createDocumentLoader(ResourceRequest(URL(ParsedURLString, emptyString())), SubstituteData()).ptr());
+ setPolicyDocumentLoader(m_client.createDocumentLoader(ResourceRequest(URL(ParsedURLString, emptyString())), SubstituteData()).get());
setProvisionalDocumentLoader(m_policyDocumentLoader.get());
m_provisionalDocumentLoader->startLoadingMainResource();
@@ -299,8 +289,8 @@ void FrameLoader::initForSynthesizedDocument(const URL&)
// FrameLoader::checkCompleted() will overwrite the URL of the document to be activeDocumentLoader()->documentURL().
RefPtr<DocumentLoader> loader = m_client.createDocumentLoader(ResourceRequest(URL(ParsedURLString, emptyString())), SubstituteData());
- loader->attachToFrame(m_frame);
- loader->setResponse(ResourceResponse(URL(), ASCIILiteral("text/html"), 0, String()));
+ loader->setFrame(&m_frame);
+ loader->setResponse(ResourceResponse(URL(), ASCIILiteral("text/html"), 0, String(), String()));
loader->setCommitted(true);
setDocumentLoader(loader.get());
@@ -315,7 +305,6 @@ void FrameLoader::initForSynthesizedDocument(const URL&)
m_needsClear = true;
m_networkingContext = m_client.createNetworkingContext();
- m_progressTracker = std::make_unique<FrameProgressTracker>(m_frame);
}
#endif
@@ -335,32 +324,40 @@ void FrameLoader::setDefersLoading(bool defers)
}
}
-void FrameLoader::changeLocation(const FrameLoadRequest& request)
+void FrameLoader::changeLocation(SecurityOrigin* securityOrigin, const URL& url, const String& referrer, bool lockHistory, bool lockBackForwardList, bool refresh)
{
- urlSelected(request, nullptr);
+ urlSelected(FrameLoadRequest(securityOrigin, ResourceRequest(url, referrer, refresh ? ReloadIgnoringCacheData : UseProtocolCachePolicy), "_self"),
+ 0, lockHistory, lockBackForwardList, MaybeSendReferrer, ReplaceDocumentIfJavaScriptURL);
}
-void FrameLoader::urlSelected(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
+void FrameLoader::urlSelected(const URL& url, const String& passedTarget, PassRefPtr<Event> triggeringEvent, bool lockHistory, bool lockBackForwardList, ShouldSendReferrer shouldSendReferrer)
{
- NewFrameOpenerPolicy newFrameOpenerPolicy = shouldSendReferrer == NeverSendReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow;
-
- urlSelected(FrameLoadRequest(m_frame.document()->securityOrigin(), ResourceRequest(url), passedTarget, lockHistory, lockBackForwardList, shouldSendReferrer, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, DoNotReplaceDocumentIfJavaScriptURL, shouldOpenExternalURLsPolicy), triggeringEvent);
+ urlSelected(FrameLoadRequest(m_frame.document()->securityOrigin(), ResourceRequest(url), passedTarget),
+ triggeringEvent, lockHistory, lockBackForwardList, shouldSendReferrer, DoNotReplaceDocumentIfJavaScriptURL);
}
-void FrameLoader::urlSelected(const FrameLoadRequest& passedRequest, Event* triggeringEvent)
+// The shouldReplaceDocumentIfJavaScriptURL parameter will go away when the FIXME to eliminate the
+// corresponding parameter from ScriptController::executeIfJavaScriptURL() is addressed.
+void FrameLoader::urlSelected(const FrameLoadRequest& passedRequest, PassRefPtr<Event> triggeringEvent, bool lockHistory, bool lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL)
{
+ ASSERT(!m_suppressOpenerInNewFrame);
+
Ref<Frame> protect(m_frame);
FrameLoadRequest frameRequest(passedRequest);
- if (m_frame.script().executeIfJavaScriptURL(frameRequest.resourceRequest().url(), frameRequest.shouldReplaceDocumentIfJavaScriptURL()))
+ if (m_frame.script().executeIfJavaScriptURL(frameRequest.resourceRequest().url(), shouldReplaceDocumentIfJavaScriptURL))
return;
if (frameRequest.frameName().isEmpty())
frameRequest.setFrameName(m_frame.document()->baseTarget());
+ if (shouldSendReferrer == NeverSendReferrer)
+ m_suppressOpenerInNewFrame = true;
addHTTPOriginIfNeeded(frameRequest.resourceRequest(), outgoingOrigin());
- loadFrameRequest(frameRequest, triggeringEvent, nullptr);
+ loadFrameRequest(frameRequest, lockHistory, lockBackForwardList, triggeringEvent, 0, shouldSendReferrer);
+
+ m_suppressOpenerInNewFrame = false;
}
void FrameLoader::submitForm(PassRefPtr<FormSubmission> submission)
@@ -378,9 +375,9 @@ void FrameLoader::submitForm(PassRefPtr<FormSubmission> submission)
if (submission->action().isEmpty())
return;
- if (isDocumentSandboxed(m_frame, SandboxForms)) {
+ if (isDocumentSandboxed(&m_frame, SandboxForms)) {
// FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
- m_frame.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Blocked form submission to '" + submission->action().stringCenterEllipsizedToLength() + "' because the form's frame is sandboxed and the 'allow-forms' permission is not set.");
+ m_frame.document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked form submission to '" + submission->action().stringCenterEllipsizedToLength() + "' because the form's frame is sandboxed and the 'allow-forms' permission is not set.");
return;
}
@@ -416,7 +413,7 @@ void FrameLoader::submitForm(PassRefPtr<FormSubmission> submission)
// We do not want to submit more than one form from the same page, nor do we want to submit a single
// form more than once. This flag prevents these from happening; not sure how other browsers prevent this.
- // The flag is reset in each time we start dispatching a new mouse or key down event, and
+ // The flag is reset in each time we start handle a new mouse or key down event, and
// also in setView since this part may get reused for a page from the back/forward cache.
// The form multi-submit logic here is only needed when we are submitting a form that affects this frame.
@@ -442,8 +439,55 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy)
if (m_frame.document() && m_frame.document()->parser())
m_frame.document()->parser()->stopParsing();
- if (unloadEventPolicy != UnloadEventPolicyNone)
- dispatchUnloadEvents(unloadEventPolicy);
+ if (unloadEventPolicy != UnloadEventPolicyNone) {
+ if (m_frame.document()) {
+ if (m_didCallImplicitClose && !m_wasUnloadEventEmitted) {
+ Element* currentFocusedElement = m_frame.document()->focusedElement();
+ if (currentFocusedElement && currentFocusedElement->toInputElement())
+ currentFocusedElement->toInputElement()->endEditing();
+ if (m_pageDismissalEventBeingDispatched == NoDismissal) {
+ if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) {
+ m_pageDismissalEventBeingDispatched = PageHideDismissal;
+ m_frame.document()->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame.document()->inPageCache()), m_frame.document());
+ }
+
+ // FIXME: update Page Visibility state here.
+ // https://bugs.webkit.org/show_bug.cgi?id=116770
+
+ if (!m_frame.document()->inPageCache()) {
+ RefPtr<Event> unloadEvent(Event::create(eventNames().unloadEvent, false, false));
+ // The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed
+ // while dispatching the event, so protect it to prevent writing the end
+ // time into freed memory.
+ RefPtr<DocumentLoader> documentLoader = m_provisionalDocumentLoader;
+ m_pageDismissalEventBeingDispatched = UnloadDismissal;
+ if (documentLoader && !documentLoader->timing()->unloadEventStart() && !documentLoader->timing()->unloadEventEnd()) {
+ DocumentLoadTiming* timing = documentLoader->timing();
+ ASSERT(timing->navigationStart());
+ timing->markUnloadEventStart();
+ m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
+ timing->markUnloadEventEnd();
+ } else
+ m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
+ }
+ }
+ m_pageDismissalEventBeingDispatched = NoDismissal;
+ if (m_frame.document())
+ m_frame.document()->updateStyleIfNeeded();
+ m_wasUnloadEventEmitted = true;
+ }
+ }
+
+ // Dispatching the unload event could have made m_frame.document() null.
+ if (m_frame.document() && !m_frame.document()->inPageCache()) {
+ // Don't remove event listeners from a transitional empty document (see bug 28716 for more information).
+ bool keepEventListeners = m_stateMachine.isDisplayingInitialEmptyDocument() && m_provisionalDocumentLoader
+ && m_frame.document()->isSecureTransitionTo(m_provisionalDocumentLoader->url());
+
+ if (!keepEventListeners)
+ m_frame.document()->removeAllEventListeners();
+ }
+ }
m_isComplete = true; // to avoid calling completed() in finishedParsing()
m_didCallImplicitClose = true; // don't want that one either
@@ -458,8 +502,10 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy)
// http://www.w3.org/Bugs/Public/show_bug.cgi?id=10537
doc->setReadyState(Document::Complete);
+#if ENABLE(SQL_DATABASE)
// FIXME: Should the DatabaseManager watch for something like ActiveDOMObject::stop() rather than being special-cased here?
- DatabaseManager::singleton().stopDatabases(doc, 0);
+ DatabaseManager::manager().stopDatabases(doc, 0);
+#endif
}
// FIXME: This will cancel redirection timer, which really needs to be restarted when restoring the frame from b/f cache.
@@ -487,28 +533,18 @@ void FrameLoader::willTransitionToCommitted()
if (m_frame.editor().hasComposition()) {
// The text was already present in DOM, so it's better to confirm than to cancel the composition.
m_frame.editor().confirmComposition();
- if (EditorClient* editorClient = m_frame.editor().client()) {
+ if (EditorClient* editorClient = m_frame.editor().client())
editorClient->respondToChangedSelection(&m_frame);
- editorClient->discardedComposition(&m_frame);
- }
}
}
bool FrameLoader::closeURL()
{
history().saveDocumentState();
-
+
+ // Should only send the pagehide event here if the current document exists and has not been placed in the page cache.
Document* currentDocument = m_frame.document();
- UnloadEventPolicy unloadEventPolicy;
- if (m_frame.page() && m_frame.page()->chrome().client().isSVGImageChromeClient()) {
- // If this is the SVGDocument of an SVGImage, no need to dispatch events or recalcStyle.
- unloadEventPolicy = UnloadEventPolicyNone;
- } else {
- // Should only send the pagehide event here if the current document exists and has not been placed in the page cache.
- unloadEventPolicy = currentDocument && !currentDocument->inPageCache() ? UnloadEventPolicyUnloadAndPageHide : UnloadEventPolicyUnloadOnly;
- }
-
- stopLoading(unloadEventPolicy);
+ stopLoading(currentDocument && !currentDocument->inPageCache() ? UnloadEventPolicyUnloadAndPageHide : UnloadEventPolicyUnloadOnly);
m_frame.editor().clearUndoRedoOperations();
return true;
@@ -581,31 +617,27 @@ void FrameLoader::clear(Document* newDocument, bool clearWindowProperties, bool
if (!m_frame.document()->inPageCache()) {
m_frame.document()->cancelParsing();
m_frame.document()->stopActiveDOMObjects();
- bool hadLivingRenderTree = m_frame.document()->hasLivingRenderTree();
- m_frame.document()->prepareForDestruction();
- if (hadLivingRenderTree)
+ if (m_frame.document()->hasLivingRenderTree()) {
+ m_frame.document()->prepareForDestruction();
m_frame.document()->removeFocusedNodeOfSubtree(m_frame.document());
+ }
}
// Do this after detaching the document so that the unload event works.
if (clearWindowProperties) {
InspectorInstrumentation::frameWindowDiscarded(&m_frame, m_frame.document()->domWindow());
- m_frame.document()->domWindow()->resetUnlessSuspendedForDocumentSuspension();
+ m_frame.document()->domWindow()->resetUnlessSuspendedForPageCache();
m_frame.script().clearWindowShell(newDocument->domWindow(), m_frame.document()->inPageCache());
}
m_frame.selection().prepareForDestruction();
-
- // We may call this code during object destruction, so need to make sure eventHandler is present.
- if (auto eventHandler = m_frame.eventHandlerPtr())
- eventHandler->clear();
-
+ m_frame.eventHandler().clear();
if (clearFrameView && m_frame.view())
m_frame.view()->clear();
// Do not drop the document before the ScriptController and view are cleared
// as some destructors might still try to access the document.
- m_frame.setDocument(nullptr);
+ m_frame.setDocument(0);
subframeLoader().clear();
@@ -639,22 +671,23 @@ void FrameLoader::receivedFirstData()
if (!m_documentLoader)
return;
+ if (m_frame.document()->isViewSource())
+ return;
double delay;
- String urlString;
- if (!parseHTTPRefresh(m_documentLoader->response().httpHeaderField(HTTPHeaderName::Refresh), false, delay, urlString))
+ String url;
+ if (!parseHTTPRefresh(m_documentLoader->response().httpHeaderField("Refresh"), false, delay, url))
return;
- URL completedURL;
- if (urlString.isEmpty())
- completedURL = m_frame.document()->url();
+ if (url.isEmpty())
+ url = m_frame.document()->url().string();
else
- completedURL = m_frame.document()->completeURL(urlString);
+ url = m_frame.document()->completeURL(url).string();
- if (!protocolIsJavaScript(completedURL))
- m_frame.navigationScheduler().scheduleRedirect(m_frame.document(), delay, completedURL);
+ if (!protocolIsJavaScript(url))
+ m_frame.navigationScheduler().scheduleRedirect(delay, url);
else {
String message = "Refused to refresh " + m_frame.document()->url().stringCenterEllipsizedToLength() + " to a javascript: URL";
- m_frame.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message);
+ m_frame.document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
}
}
@@ -672,7 +705,7 @@ void FrameLoader::didBeginDocument(bool dispatch)
if (m_pendingStateObject) {
m_frame.document()->statePopped(m_pendingStateObject.get());
- m_pendingStateObject = nullptr;
+ m_pendingStateObject.clear();
}
if (dispatch)
@@ -682,17 +715,31 @@ void FrameLoader::didBeginDocument(bool dispatch)
m_frame.document()->initContentSecurityPolicy();
const Settings& settings = m_frame.settings();
- m_frame.document()->cachedResourceLoader().setImagesEnabled(settings.areImagesEnabled());
- m_frame.document()->cachedResourceLoader().setAutoLoadImages(settings.loadsImagesAutomatically());
+ m_frame.document()->cachedResourceLoader()->setImagesEnabled(settings.areImagesEnabled());
+ m_frame.document()->cachedResourceLoader()->setAutoLoadImages(settings.loadsImagesAutomatically());
if (m_documentLoader) {
- String dnsPrefetchControl = m_documentLoader->response().httpHeaderField(HTTPHeaderName::XDNSPrefetchControl);
+ String dnsPrefetchControl = m_documentLoader->response().httpHeaderField("X-DNS-Prefetch-Control");
if (!dnsPrefetchControl.isEmpty())
m_frame.document()->parseDNSPrefetchControlHeader(dnsPrefetchControl);
- m_frame.document()->contentSecurityPolicy()->didReceiveHeaders(ContentSecurityPolicyResponseHeaders(m_documentLoader->response()));
+ String policyValue = m_documentLoader->response().httpHeaderField("Content-Security-Policy");
+ if (!policyValue.isEmpty())
+ m_frame.document()->contentSecurityPolicy()->didReceiveHeader(policyValue, ContentSecurityPolicy::Enforce);
- String headerContentLanguage = m_documentLoader->response().httpHeaderField(HTTPHeaderName::ContentLanguage);
+ policyValue = m_documentLoader->response().httpHeaderField("Content-Security-Policy-Report-Only");
+ if (!policyValue.isEmpty())
+ m_frame.document()->contentSecurityPolicy()->didReceiveHeader(policyValue, ContentSecurityPolicy::Report);
+
+ policyValue = m_documentLoader->response().httpHeaderField("X-WebKit-CSP");
+ if (!policyValue.isEmpty())
+ m_frame.document()->contentSecurityPolicy()->didReceiveHeader(policyValue, ContentSecurityPolicy::PrefixedEnforce);
+
+ policyValue = m_documentLoader->response().httpHeaderField("X-WebKit-CSP-Report-Only");
+ if (!policyValue.isEmpty())
+ m_frame.document()->contentSecurityPolicy()->didReceiveHeader(policyValue, ContentSecurityPolicy::PrefixedReport);
+
+ String headerContentLanguage = m_documentLoader->response().httpHeaderField("Content-Language");
if (!headerContentLanguage.isEmpty()) {
size_t commaIndex = headerContentLanguage.find(',');
headerContentLanguage.truncate(commaIndex); // notFound == -1 == don't truncate
@@ -719,8 +766,6 @@ void FrameLoader::finishedParsing()
m_client.dispatchDidFinishDocumentLoad();
- scrollToFragmentWithParentBoundary(m_frame.document()->url());
-
checkCompleted();
if (!m_frame.view())
@@ -729,6 +774,7 @@ void FrameLoader::finishedParsing()
// Check if the scrollbars are really needed for the content.
// If not, remove them, relayout, and repaint.
m_frame.view()->restoreScrollbar();
+ scrollToFragmentWithParentBoundary(m_frame.document()->url());
}
void FrameLoader::loadDone()
@@ -756,6 +802,7 @@ bool FrameLoader::allAncestorsAreComplete() const
void FrameLoader::checkCompleted()
{
+ Ref<Frame> protect(m_frame);
m_shouldCallCheckCompleted = false;
// Have we completed before?
@@ -767,7 +814,7 @@ void FrameLoader::checkCompleted()
return;
// Still waiting for images/scripts?
- if (m_frame.document()->cachedResourceLoader().requestCount())
+ if (m_frame.document()->cachedResourceLoader()->requestCount())
return;
// Still waiting for elements that don't go through a FrameLoader?
@@ -778,14 +825,9 @@ void FrameLoader::checkCompleted()
if (!allChildrenAreComplete())
return;
- // Important not to protect earlier in this function, because earlier parts
- // of this function can be called in the frame's destructor, and it's not legal
- // to ref an object while it's being destroyed.
- Ref<Frame> protect(m_frame);
-
// OK, completed.
m_isComplete = true;
- m_requestedHistoryItem = nullptr;
+ m_requestedHistoryItem = 0;
m_frame.document()->setReadyState(Document::Complete);
#if PLATFORM(IOS)
@@ -809,7 +851,7 @@ void FrameLoader::checkCompleted()
checkLoadComplete();
}
-void FrameLoader::checkTimerFired()
+void FrameLoader::checkTimerFired(Timer<FrameLoader>&)
{
Ref<Frame> protect(m_frame);
@@ -877,13 +919,12 @@ void FrameLoader::loadURLIntoChildFrame(const URL& url, const String& referer, F
HistoryItem* childItem = parentItem->childItemWithTarget(childFrame->tree().uniqueName());
if (childItem) {
childFrame->loader().m_requestedHistoryItem = childItem;
- childFrame->loader().loadDifferentDocumentItem(*childItem, loadType(), MayAttemptCacheOnlyLoadForFormSubmissionItem);
+ childFrame->loader().loadDifferentDocumentItem(childItem, loadType(), MayAttemptCacheOnlyLoadForFormSubmissionItem);
return;
}
}
- FrameLoadRequest frameLoadRequest(m_frame.document()->securityOrigin(), ResourceRequest(url), "_self", LockHistory::No, LockBackForwardList::Yes, ShouldSendReferrer::MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
- childFrame->loader().loadURL(frameLoadRequest, referer, FrameLoadType::RedirectWithLockedBackForwardList, 0, 0);
+ childFrame->loader().loadURL(url, referer, "_self", false, FrameLoadTypeRedirectWithLockedBackForwardList, 0, 0);
}
#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
@@ -893,9 +934,8 @@ void FrameLoader::loadArchive(PassRefPtr<Archive> archive)
ASSERT(mainResource);
if (!mainResource)
return;
-
- ResourceResponse response(URL(), mainResource->mimeType(), mainResource->data()->size(), mainResource->textEncoding());
- SubstituteData substituteData(mainResource->data(), URL(), response, SubstituteData::SessionHistoryVisibility::Hidden);
+
+ SubstituteData substituteData(mainResource->data(), mainResource->mimeType(), mainResource->textEncoding(), URL());
ResourceRequest request(mainResource->url());
#if PLATFORM(MAC)
@@ -908,6 +948,41 @@ void FrameLoader::loadArchive(PassRefPtr<Archive> archive)
}
#endif // ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
+ObjectContentType FrameLoader::defaultObjectContentType(const URL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
+{
+ String mimeType = mimeTypeIn;
+
+ if (mimeType.isEmpty())
+ mimeType = mimeTypeFromURL(url);
+
+#if !PLATFORM(MAC) && !PLATFORM(EFL) // Mac has no PluginDatabase, nor does EFL
+ if (mimeType.isEmpty()) {
+ String decodedPath = decodeURLEscapeSequences(url.path());
+ mimeType = PluginDatabase::installedPlugins()->MIMETypeForExtension(decodedPath.substring(decodedPath.reverseFind('.') + 1));
+ }
+#endif
+
+ if (mimeType.isEmpty())
+ return ObjectContentFrame; // Go ahead and hope that we can display the content.
+
+#if !PLATFORM(MAC) && !PLATFORM(EFL) // Mac has no PluginDatabase, nor does EFL
+ bool plugInSupportsMIMEType = PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType);
+#else
+ bool plugInSupportsMIMEType = false;
+#endif
+
+ if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
+ return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? WebCore::ObjectContentNetscapePlugin : WebCore::ObjectContentImage;
+
+ if (plugInSupportsMIMEType)
+ return WebCore::ObjectContentNetscapePlugin;
+
+ if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
+ return WebCore::ObjectContentFrame;
+
+ return WebCore::ObjectContentNone;
+}
+
String FrameLoader::outgoingReferrer() const
{
// See http://www.whatwg.org/specs/web-apps/current-work/#fetching-resources
@@ -959,9 +1034,9 @@ void FrameLoader::setOpener(Frame* opener)
void FrameLoader::handleFallbackContent()
{
HTMLFrameOwnerElement* owner = m_frame.ownerElement();
- if (!is<HTMLObjectElement>(owner))
+ if (!owner || !owner->hasTagName(objectTag))
return;
- downcast<HTMLObjectElement>(*owner).renderFallbackContent();
+ toHTMLObjectElement(owner)->renderFallbackContent();
}
void FrameLoader::provisionalLoadStarted()
@@ -1074,18 +1149,37 @@ void FrameLoader::completed()
parent->loader().checkCompleted();
if (m_frame.view())
- m_frame.view()->maintainScrollPositionAtAnchor(nullptr);
+ m_frame.view()->maintainScrollPositionAtAnchor(0);
m_activityAssertion = nullptr;
}
void FrameLoader::started()
{
if (m_frame.page())
- m_activityAssertion = m_frame.page()->pageThrottler().pageLoadActivityToken();
+ m_activityAssertion = m_frame.page()->createActivityToken();
for (Frame* frame = &m_frame; frame; frame = frame->tree().parent())
frame->loader().m_isComplete = false;
}
+void FrameLoader::prepareForHistoryNavigation()
+{
+ // If there is no currentItem, but we still want to engage in
+ // history navigation we need to manufacture one, and update
+ // the state machine of this frame to impersonate having
+ // loaded it.
+ RefPtr<HistoryItem> currentItem = history().currentItem();
+ if (!currentItem) {
+ currentItem = HistoryItem::create();
+ currentItem->setLastVisitWasFailure(true);
+ history().setCurrentItem(currentItem.get());
+ m_frame.page()->backForward().setCurrentItem(currentItem.get());
+
+ ASSERT(stateMachine()->isDisplayingInitialEmptyDocument());
+ stateMachine()->advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
+ stateMachine()->advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
+ }
+}
+
void FrameLoader::prepareForLoadStart()
{
m_progressTracker->progressStarted();
@@ -1093,7 +1187,7 @@ void FrameLoader::prepareForLoadStart()
if (AXObjectCache::accessibilityEnabled()) {
if (AXObjectCache* cache = m_frame.document()->existingAXObjectCache()) {
- AXObjectCache::AXLoadingEvent loadingEvent = loadType() == FrameLoadType::Reload ? AXObjectCache::AXLoadingReloaded : AXObjectCache::AXLoadingStarted;
+ AXObjectCache::AXLoadingEvent loadingEvent = loadType() == FrameLoadTypeReload ? AXObjectCache::AXLoadingReloaded : AXObjectCache::AXLoadingStarted;
cache->frameLoadingEventNotification(&m_frame, loadingEvent);
}
}
@@ -1104,11 +1198,12 @@ void FrameLoader::setupForReplace()
m_client.revertToProvisionalState(m_documentLoader.get());
setState(FrameStateProvisional);
m_provisionalDocumentLoader = m_documentLoader;
- m_documentLoader = nullptr;
+ m_documentLoader = 0;
detachChildren();
}
-void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, Event* event, PassRefPtr<FormState> formState)
+void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, bool lockHistory, bool lockBackForwardList,
+ PassRefPtr<Event> event, PassRefPtr<FormState> formState, ShouldSendReferrer shouldSendReferrer)
{
// Protect frame from getting blown away inside dispatchBeforeLoadEvent in loadWithDocumentLoader.
Ref<Frame> protect(m_frame);
@@ -1126,21 +1221,21 @@ void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, Event* event
argsReferrer = outgoingReferrer();
String referrer = SecurityPolicy::generateReferrerHeader(m_frame.document()->referrerPolicy(), url, argsReferrer);
- if (request.shouldSendReferrer() == NeverSendReferrer)
+ if (shouldSendReferrer == NeverSendReferrer)
referrer = String();
-
+
FrameLoadType loadType;
if (request.resourceRequest().cachePolicy() == ReloadIgnoringCacheData)
- loadType = FrameLoadType::Reload;
- else if (request.lockBackForwardList() == LockBackForwardList::Yes)
- loadType = FrameLoadType::RedirectWithLockedBackForwardList;
+ loadType = FrameLoadTypeReload;
+ else if (lockBackForwardList)
+ loadType = FrameLoadTypeRedirectWithLockedBackForwardList;
else
- loadType = FrameLoadType::Standard;
+ loadType = FrameLoadTypeStandard;
if (request.resourceRequest().httpMethod() == "POST")
- loadPostRequest(request, referrer, loadType, event, formState.get());
+ loadPostRequest(request.resourceRequest(), referrer, request.frameName(), lockHistory, loadType, event, formState.get());
else
- loadURL(request, referrer, loadType, event, formState.get());
+ loadURL(request.resourceRequest().url(), referrer, request.frameName(), lockHistory, loadType, event, formState.get());
// FIXME: It's possible this targetFrame will not be the same frame that was targeted by the actual
// load if frame names have changed.
@@ -1154,30 +1249,17 @@ void FrameLoader::loadFrameRequest(const FrameLoadRequest& request, Event* event
}
}
-static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& sourceFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
-{
- if (!sourceFrame.isMainFrame())
- return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
- if (ScriptController::processingUserGesture())
- return ShouldOpenExternalURLsPolicy::ShouldAllow;
- return propagatedPolicy;
-}
-
-void FrameLoader::loadURL(const FrameLoadRequest& frameLoadRequest, const String& referrer, FrameLoadType newLoadType, Event* event, PassRefPtr<FormState> prpFormState)
+void FrameLoader::loadURL(const URL& newURL, const String& referrer, const String& frameName, bool lockHistory, FrameLoadType newLoadType,
+ PassRefPtr<Event> event, PassRefPtr<FormState> prpFormState)
{
if (m_inStopAllLoaders)
return;
Ref<Frame> protect(m_frame);
- String frameName = frameLoadRequest.frameName();
- AllowNavigationToInvalidURL allowNavigationToInvalidURL = frameLoadRequest.allowNavigationToInvalidURL();
- NewFrameOpenerPolicy openerPolicy = frameLoadRequest.newFrameOpenerPolicy();
- LockHistory lockHistory = frameLoadRequest.lockHistory();
RefPtr<FormState> formState = prpFormState;
bool isFormSubmission = formState;
-
- const URL& newURL = frameLoadRequest.resourceRequest().url();
+
ResourceRequest request(newURL);
if (!referrer.isEmpty()) {
request.setHTTPReferrer(referrer);
@@ -1186,32 +1268,29 @@ void FrameLoader::loadURL(const FrameLoadRequest& frameLoadRequest, const String
}
#if ENABLE(CACHE_PARTITIONING)
if (&m_frame.tree().top() != &m_frame)
- request.setDomainForCachePartition(m_frame.tree().top().document()->securityOrigin()->domainForCachePartition());
+ request.setCachePartition(m_frame.tree().top().document()->securityOrigin()->cachePartition());
#endif
addExtraFieldsToRequest(request, newLoadType, true);
- if (newLoadType == FrameLoadType::Reload || newLoadType == FrameLoadType::ReloadFromOrigin)
+ if (newLoadType == FrameLoadTypeReload || newLoadType == FrameLoadTypeReloadFromOrigin)
request.setCachePolicy(ReloadIgnoringCacheData);
- ASSERT(newLoadType != FrameLoadType::Same);
+ ASSERT(newLoadType != FrameLoadTypeSame);
// The search for a target frame is done earlier in the case of form submission.
Frame* targetFrame = isFormSubmission ? 0 : findFrameForNavigation(frameName);
if (targetFrame && targetFrame != &m_frame) {
- FrameLoadRequest newFrameLoadRequest(frameLoadRequest);
- newFrameLoadRequest.setFrameName("_self");
- targetFrame->loader().loadURL(newFrameLoadRequest, referrer, newLoadType, event, formState.release());
+ targetFrame->loader().loadURL(newURL, referrer, "_self", lockHistory, newLoadType, event, formState.release());
return;
}
- if (m_pageDismissalEventBeingDispatched != PageDismissalType::None)
+ if (m_pageDismissalEventBeingDispatched != NoDismissal)
return;
- NavigationAction action(request, newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy());
+ NavigationAction action(request, newLoadType, isFormSubmission, event);
if (!targetFrame && !frameName.isEmpty()) {
- action = action.copyWithShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, frameLoadRequest.shouldOpenExternalURLsPolicy()));
- policyChecker().checkNewWindowPolicy(action, request, formState.release(), frameName, [this, allowNavigationToInvalidURL, openerPolicy](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
- continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
+ policyChecker().checkNewWindowPolicy(action, request, formState.release(), frameName, [this](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
+ continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue);
});
return;
}
@@ -1237,16 +1316,16 @@ void FrameLoader::loadURL(const FrameLoadRequest& frameLoadRequest, const String
// must grab this now, since this load may stop the previous load and clear this flag
bool isRedirect = m_quickRedirectComing;
- loadWithNavigationAction(request, action, lockHistory, newLoadType, formState.release(), allowNavigationToInvalidURL);
+ loadWithNavigationAction(request, action, lockHistory, newLoadType, formState.release());
if (isRedirect) {
m_quickRedirectComing = false;
if (m_provisionalDocumentLoader)
m_provisionalDocumentLoader->setIsClientRedirect(true);
- } else if (sameURL && newLoadType != FrameLoadType::Reload && newLoadType != FrameLoadType::ReloadFromOrigin) {
+ } else if (sameURL && newLoadType != FrameLoadTypeReload && newLoadType != FrameLoadTypeReloadFromOrigin) {
// Example of this case are sites that reload the same URL with a different cookie
// driving the generated content, or a master frame with links that drive a target
// frame, where the user has clicked on the same link repeatedly.
- m_loadType = FrameLoadType::Same;
+ m_loadType = FrameLoadTypeSame;
}
}
@@ -1257,9 +1336,7 @@ SubstituteData FrameLoader::defaultSubstituteDataForURL(const URL& url)
String srcdoc = m_frame.ownerElement()->fastGetAttribute(srcdocAttr);
ASSERT(!srcdoc.isNull());
CString encodedSrcdoc = srcdoc.utf8();
-
- ResourceResponse response(URL(), ASCIILiteral("text/html"), encodedSrcdoc.length(), ASCIILiteral("UTF-8"));
- return SubstituteData(SharedBuffer::create(encodedSrcdoc.data(), encodedSrcdoc.length()), URL(), response, SubstituteData::SessionHistoryVisibility::Hidden);
+ return SubstituteData(SharedBuffer::create(encodedSrcdoc.data(), encodedSrcdoc.length()), "text/html", "UTF-8", URL());
}
void FrameLoader::load(const FrameLoadRequest& passedRequest)
@@ -1281,9 +1358,8 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest)
}
if (request.shouldCheckNewWindowPolicy()) {
- NavigationAction action(request.resourceRequest(), NavigationType::Other, passedRequest.shouldOpenExternalURLsPolicy());
- policyChecker().checkNewWindowPolicy(action, request.resourceRequest(), nullptr, request.frameName(), [this](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
- continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
+ policyChecker().checkNewWindowPolicy(NavigationAction(request.resourceRequest(), NavigationTypeOther), request.resourceRequest(), nullptr, request.frameName(), [this](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
+ continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue);
});
return;
@@ -1292,25 +1368,23 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest)
if (!request.hasSubstituteData())
request.setSubstituteData(defaultSubstituteDataForURL(request.resourceRequest().url()));
- Ref<DocumentLoader> loader = m_client.createDocumentLoader(request.resourceRequest(), request.substituteData());
- applyShouldOpenExternalURLsPolicyToNewDocumentLoader(loader, request.shouldOpenExternalURLsPolicy());
-
- load(loader.ptr());
+ RefPtr<DocumentLoader> loader = m_client.createDocumentLoader(request.resourceRequest(), request.substituteData());
+ if (request.lockHistory() && m_documentLoader)
+ loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
+ load(loader.get());
}
-void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, LockHistory lockHistory, FrameLoadType type, PassRefPtr<FormState> formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
+void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, bool lockHistory, FrameLoadType type, PassRefPtr<FormState> formState)
{
- Ref<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
- applyShouldOpenExternalURLsPolicyToNewDocumentLoader(loader, action.shouldOpenExternalURLsPolicy());
-
- if (lockHistory == LockHistory::Yes && m_documentLoader)
+ RefPtr<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
+ if (lockHistory && m_documentLoader)
loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
loader->setTriggeringAction(action);
if (m_documentLoader)
loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
- loadWithDocumentLoader(loader.ptr(), type, formState, allowNavigationToInvalidURL);
+ loadWithDocumentLoader(loader.get(), type, formState);
}
void FrameLoader::load(DocumentLoader* newDocumentLoader)
@@ -1321,11 +1395,11 @@ void FrameLoader::load(DocumentLoader* newDocumentLoader)
if (shouldTreatURLAsSameAsCurrent(newDocumentLoader->originalRequest().url())) {
r.setCachePolicy(ReloadIgnoringCacheData);
- type = FrameLoadType::Same;
- } else if (shouldTreatURLAsSameAsCurrent(newDocumentLoader->unreachableURL()) && m_loadType == FrameLoadType::Reload)
- type = FrameLoadType::Reload;
+ type = FrameLoadTypeSame;
+ } else if (shouldTreatURLAsSameAsCurrent(newDocumentLoader->unreachableURL()) && m_loadType == FrameLoadTypeReload)
+ type = FrameLoadTypeReload;
else
- type = FrameLoadType::Standard;
+ type = FrameLoadTypeStandard;
if (m_documentLoader)
newDocumentLoader->setOverrideEncoding(m_documentLoader->overrideEncoding());
@@ -1334,7 +1408,7 @@ void FrameLoader::load(DocumentLoader* newDocumentLoader)
// visiting in the history list, we treat it as a reload so the history list
// is appropriately maintained.
//
- // FIXME: This seems like a dangerous overloading of the meaning of "FrameLoadType::Reload" ...
+ // FIXME: This seems like a dangerous overloading of the meaning of "FrameLoadTypeReload" ...
// shouldn't a more explicit type of reload be defined, that means roughly
// "load without affecting history" ?
if (shouldReloadToHandleUnreachableURL(newDocumentLoader)) {
@@ -1343,47 +1417,14 @@ void FrameLoader::load(DocumentLoader* newDocumentLoader)
// changed and updateForBackForwardNavigation() will not be called when loading is committed.
history().saveDocumentAndScrollState();
- ASSERT(type == FrameLoadType::Standard);
- type = FrameLoadType::Reload;
+ ASSERT(type == FrameLoadTypeStandard);
+ type = FrameLoadTypeReload;
}
- loadWithDocumentLoader(newDocumentLoader, type, 0, AllowNavigationToInvalidURL::Yes);
+ loadWithDocumentLoader(newDocumentLoader, type, 0);
}
-static void logNavigation(MainFrame& frame, FrameLoadType type)
-{
- String navigationDescription;
- switch (type) {
- case FrameLoadType::Standard:
- navigationDescription = ASCIILiteral("standard");
- break;
- case FrameLoadType::Back:
- navigationDescription = ASCIILiteral("back");
- break;
- case FrameLoadType::Forward:
- navigationDescription = ASCIILiteral("forward");
- break;
- case FrameLoadType::IndexedBackForward:
- navigationDescription = ASCIILiteral("indexedBackForward");
- break;
- case FrameLoadType::Reload:
- navigationDescription = ASCIILiteral("reload");
- break;
- case FrameLoadType::Same:
- navigationDescription = ASCIILiteral("same");
- break;
- case FrameLoadType::ReloadFromOrigin:
- navigationDescription = ASCIILiteral("reloadFromOrigin");
- break;
- case FrameLoadType::Replace:
- case FrameLoadType::RedirectWithLockedBackForwardList:
- // Not logging those for now.
- return;
- }
- frame.diagnosticLoggingClient().logDiagnosticMessage(DiagnosticLoggingKeys::navigationKey(), navigationDescription, ShouldSample::No);
-}
-
-void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType type, PassRefPtr<FormState> prpFormState, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
+void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType type, PassRefPtr<FormState> prpFormState)
{
// Retain because dispatchBeforeLoadEvent may release the last reference to it.
Ref<Frame> protect(m_frame);
@@ -1395,16 +1436,12 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
ASSERT(m_frame.view());
- if (m_pageDismissalEventBeingDispatched != PageDismissalType::None)
+ if (m_pageDismissalEventBeingDispatched != NoDismissal)
return;
if (m_frame.document())
m_previousURL = m_frame.document()->url();
- // Log main frame navigation types.
- if (m_frame.isMainFrame())
- logNavigation(static_cast<MainFrame&>(m_frame), type);
-
policyChecker().setLoadType(type);
RefPtr<FormState> formState = prpFormState;
bool isFormSubmission = formState;
@@ -1441,13 +1478,13 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t
// a new URL, the parent frame shouldn't learn the URL.
if (!m_stateMachine.committedFirstRealDocumentLoad()
&& !ownerElement->dispatchBeforeLoadEvent(loader->request().url().string())) {
- continueLoadAfterNavigationPolicy(loader->request(), formState, false, allowNavigationToInvalidURL);
+ continueLoadAfterNavigationPolicy(loader->request(), formState, false);
return;
}
}
- policyChecker().checkNavigationPolicy(loader->request(), loader, formState, [this, allowNavigationToInvalidURL](const ResourceRequest& request, PassRefPtr<FormState> formState, bool shouldContinue) {
- continueLoadAfterNavigationPolicy(request, formState, shouldContinue, allowNavigationToInvalidURL);
+ policyChecker().checkNavigationPolicy(loader->request(), loader, formState, [this](const ResourceRequest& request, PassRefPtr<FormState> formState, bool shouldContinue) {
+ continueLoadAfterNavigationPolicy(request, formState, shouldContinue);
});
}
@@ -1457,16 +1494,7 @@ void FrameLoader::reportLocalLoadFailed(Frame* frame, const String& url)
if (!frame)
return;
- frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to load local resource: " + url);
-}
-
-void FrameLoader::reportBlockedPortFailed(Frame* frame, const String& url)
-{
- ASSERT(!url.isEmpty());
- if (!frame)
- return;
-
- frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to use restricted network port: " + url);
+ frame->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Not allowed to load local resource: " + url);
}
const ResourceRequest& FrameLoader::initialRequest() const
@@ -1488,7 +1516,7 @@ bool FrameLoader::willLoadMediaElementURL(URL& url)
unsigned long identifier;
ResourceError error;
requestFromDelegate(request, identifier, error);
- notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, ResourceResponse(url, String(), -1, String()), 0, -1, -1, error);
+ notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, ResourceResponse(url, String(), -1, String(), String()), 0, -1, -1, error);
url = request.url();
@@ -1510,10 +1538,13 @@ bool FrameLoader::shouldReloadToHandleUnreachableURL(DocumentLoader* docLoader)
// case handles well-formed URLs that can't be loaded, and the latter
// case handles malformed URLs and unknown schemes. Loading alternate content
// at other times behaves like a standard load.
+ DocumentLoader* compareDocumentLoader = 0;
if (policyChecker().delegateIsDecidingNavigationPolicy() || policyChecker().delegateIsHandlingUnimplementablePolicy())
- return m_policyDocumentLoader && unreachableURL == m_policyDocumentLoader->request().url();
+ compareDocumentLoader = m_policyDocumentLoader.get();
+ else if (m_delegateIsHandlingProvisionalLoadError)
+ compareDocumentLoader = m_provisionalDocumentLoader.get();
- return unreachableURL == m_provisionalLoadErrorBeingHandledURL;
+ return compareDocumentLoader && unreachableURL == compareDocumentLoader->request().url();
}
void FrameLoader::reloadWithOverrideEncoding(const String& encoding)
@@ -1530,17 +1561,28 @@ void FrameLoader::reloadWithOverrideEncoding(const String& encoding)
// We should ask the user for confirmation in this case.
request.setCachePolicy(ReturnCacheDataElseLoad);
- Ref<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
- applyShouldOpenExternalURLsPolicyToNewDocumentLoader(loader, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
-
- setPolicyDocumentLoader(loader.ptr());
+ RefPtr<DocumentLoader> loader = m_client.createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
+ setPolicyDocumentLoader(loader.get());
loader->setOverrideEncoding(encoding);
- loadWithDocumentLoader(loader.ptr(), FrameLoadType::Reload, 0, AllowNavigationToInvalidURL::Yes);
+ loadWithDocumentLoader(loader.get(), FrameLoadTypeReload, 0);
+}
+
+void FrameLoader::reloadWithOverrideURL(const URL& overrideUrl, bool endToEndReload)
+{
+ if (!m_documentLoader)
+ return;
+
+ if (overrideUrl.isEmpty())
+ return;
+
+ ResourceRequest request = m_documentLoader->request();
+ request.setURL(overrideUrl);
+ reloadWithRequest(request, endToEndReload);
}
-void FrameLoader::reload(bool endToEndReload, bool contentBlockersEnabled)
+void FrameLoader::reload(bool endToEndReload)
{
if (!m_documentLoader)
return;
@@ -1556,13 +1598,17 @@ void FrameLoader::reload(bool endToEndReload, bool contentBlockersEnabled)
if (!unreachableURL.isEmpty())
initialRequest.setURL(unreachableURL);
+ reloadWithRequest(initialRequest, endToEndReload);
+}
+
+void FrameLoader::reloadWithRequest(const ResourceRequest& initialRequest, bool endToEndReload)
+{
+ ASSERT(m_documentLoader);
+
// Create a new document loader for the reload, this will become m_documentLoader eventually,
// but first it has to be the "policy" document loader, and then the "provisional" document loader.
- Ref<DocumentLoader> loader = m_client.createDocumentLoader(initialRequest, defaultSubstituteDataForURL(initialRequest.url()));
- applyShouldOpenExternalURLsPolicyToNewDocumentLoader(loader, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
+ RefPtr<DocumentLoader> loader = m_client.createDocumentLoader(initialRequest, defaultSubstituteDataForURL(initialRequest.url()));
- loader->setUserContentExtensionsEnabled(contentBlockersEnabled);
-
ResourceRequest& request = loader->request();
// FIXME: We don't have a mechanism to revalidate the main resource without reloading at the moment.
@@ -1570,17 +1616,17 @@ void FrameLoader::reload(bool endToEndReload, bool contentBlockersEnabled)
// If we're about to re-post, set up action so the application can warn the user.
if (request.httpMethod() == "POST")
- loader->setTriggeringAction(NavigationAction(request, NavigationType::FormResubmitted));
+ loader->setTriggeringAction(NavigationAction(request, NavigationTypeFormResubmitted));
loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
- loadWithDocumentLoader(loader.ptr(), endToEndReload ? FrameLoadType::ReloadFromOrigin : FrameLoadType::Reload, 0, AllowNavigationToInvalidURL::Yes);
+ loadWithDocumentLoader(loader.get(), endToEndReload ? FrameLoadTypeReloadFromOrigin : FrameLoadTypeReload, 0);
}
void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItemPolicy)
{
ASSERT(!m_frame.document() || !m_frame.document()->inPageCache());
- if (m_pageDismissalEventBeingDispatched != PageDismissalType::None)
+ if (m_pageDismissalEventBeingDispatched != NoDismissal)
return;
// If this method is called from within this method, infinite recursion can occur (3442218). Avoid this.
@@ -1598,7 +1644,7 @@ void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItem
// If no new load is in progress, we should clear the provisional item from history
// before we call stopLoading.
if (clearProvisionalItemPolicy == ShouldClearProvisionalItem)
- history().setProvisionalItem(nullptr);
+ history().setProvisionalItem(0);
for (RefPtr<Frame> child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
child->loader().stopAllLoaders(clearProvisionalItemPolicy);
@@ -1607,7 +1653,7 @@ void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItem
if (m_documentLoader)
m_documentLoader->stopLoading();
- setProvisionalDocumentLoader(nullptr);
+ setProvisionalDocumentLoader(0);
m_checkTimer.stop();
@@ -1616,9 +1662,6 @@ void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItem
void FrameLoader::stopForUserCancel(bool deferCheckLoadComplete)
{
- // Calling stopAllLoaders can cause the frame to be deallocated, including the frame loader.
- Ref<Frame> protectedFrame(m_frame);
-
stopAllLoaders();
#if PLATFORM(IOS)
@@ -1688,7 +1731,7 @@ void FrameLoader::setPolicyDocumentLoader(DocumentLoader* loader)
return;
if (loader)
- loader->attachToFrame(m_frame);
+ loader->setFrame(&m_frame);
if (m_policyDocumentLoader
&& m_policyDocumentLoader != m_provisionalDocumentLoader
&& m_policyDocumentLoader != m_documentLoader)
@@ -1723,7 +1766,7 @@ void FrameLoader::setState(FrameState newState)
void FrameLoader::clearProvisionalLoad()
{
- setProvisionalDocumentLoader(nullptr);
+ setProvisionalDocumentLoader(0);
m_progressTracker->progressCompleted();
setState(FrameStateComplete);
}
@@ -1734,8 +1777,8 @@ void FrameLoader::commitProvisionalLoad()
Ref<Frame> protect(m_frame);
std::unique_ptr<CachedPage> cachedPage;
- if (m_loadingFromCachedPage && history().provisionalItem())
- cachedPage = PageCache::singleton().take(*history().provisionalItem(), m_frame.page());
+ if (m_loadingFromCachedPage)
+ cachedPage = pageCache()->take(history().provisionalItem());
LOG(PageCache, "WebCoreLoading %s: About to commit provisional load from previous URL '%s' to new URL '%s'", m_frame.tree().uniqueName().string().utf8().data(),
m_frame.document() ? m_frame.document()->url().stringCenterEllipsizedToLength().utf8().data() : "",
@@ -1748,35 +1791,28 @@ void FrameLoader::commitProvisionalLoad()
// page cache. We could still preemptively prune the page cache while navigating to a cached page if capacity > 1.
// See <rdar://problem/11779846> for more details.
if (!cachedPage) {
- if (MemoryPressureHandler::singleton().isUnderMemoryPressure()) {
+ if (memoryPressureHandler().hasReceivedMemoryPressure()) {
LOG(MemoryPressure, "Pruning page cache because under memory pressure at: %s", __PRETTY_FUNCTION__);
LOG(PageCache, "Pruning page cache to 0 due to memory pressure");
// Don't cache any page if we are under memory pressure.
- PageCache::singleton().pruneToSizeNow(0, PruningReason::MemoryPressure);
+ pageCache()->pruneToCapacityNow(0);
} else if (systemMemoryLevel() <= memoryLevelThresholdToPrunePageCache) {
LOG(MemoryPressure, "Pruning page cache because system memory level is %d at: %s", systemMemoryLevel(), __PRETTY_FUNCTION__);
- auto& pageCache = PageCache::singleton();
- LOG(PageCache, "Pruning page cache to %d due to low memory (level %d less or equal to %d threshold)", pageCache.maxSize() / 2, systemMemoryLevel(), memoryLevelThresholdToPrunePageCache);
- pageCache.pruneToSizeNow(pageCache.maxSize() / 2, PruningReason::MemoryPressure);
+ LOG(PageCache, "Pruning page cache to %d due to low memory (level %d less or equal to %d threshold)", pageCache()->capacity() / 2, systemMemoryLevel(), memoryLevelThresholdToPrunePageCache);
+ pageCache()->pruneToCapacityNow(pageCache()->capacity() / 2);
}
}
#endif
willTransitionToCommitted();
- if (!m_frame.tree().parent() && history().currentItem()) {
- // Check to see if we need to cache the page we are navigating away from into the back/forward cache.
- // We are doing this here because we know for sure that a new page is about to be loaded.
- PageCache::singleton().addIfCacheable(*history().currentItem(), m_frame.page());
+ // Check to see if we need to cache the page we are navigating away from into the back/forward cache.
+ // We are doing this here because we know for sure that a new page is about to be loaded.
+ HistoryItem* item = history().currentItem();
+ if (!m_frame.tree().parent() && pageCache()->canCache(m_frame.page()) && !item->isInPageCache())
+ pageCache()->add(item, *m_frame.page());
-#if PLATFORM(IOS)
- // For top-level navigations, have JSC throw away linked code. The immediate memory savings far
- // outweigh the cost of recompiling in the case of a future backwards navigation.
- GCController::singleton().deleteAllLinkedCode();
-#endif
- }
-
- if (m_loadType != FrameLoadType::Replace)
+ if (m_loadType != FrameLoadTypeReplace)
closeOldDataSources();
if (!cachedPage && !m_stateMachine.creatingInitialEmptyDocument())
@@ -1786,8 +1822,8 @@ void FrameLoader::commitProvisionalLoad()
if (pdl && m_documentLoader) {
// Check if the destination page is allowed to access the previous page's timing information.
- Ref<SecurityOrigin> securityOrigin(SecurityOrigin::create(pdl->request().url()));
- m_documentLoader->timing().setHasSameOriginAsPreviousDocument(securityOrigin.get().canRequest(m_previousURL));
+ RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::create(pdl->request().url());
+ m_documentLoader->timing()->setHasSameOriginAsPreviousDocument(securityOrigin->canRequest(m_previousURL));
}
// Call clientRedirectCancelledOrFinished() here so that the frame load delegate is notified that the redirect's
@@ -1805,14 +1841,6 @@ void FrameLoader::commitProvisionalLoad()
#endif
prepareForCachedPageRestore();
- // Start request for the main resource and dispatch didReceiveResponse before the load is committed for
- // consistency with all other loads. See https://bugs.webkit.org/show_bug.cgi?id=150927.
- ResourceError mainResouceError;
- unsigned long mainResourceIdentifier;
- ResourceRequest mainResourceRequest(cachedPage->documentLoader()->request());
- requestFromDelegate(mainResourceRequest, mainResourceIdentifier, mainResouceError);
- notifier().dispatchDidReceiveResponse(cachedPage->documentLoader(), mainResourceIdentifier, cachedPage->documentLoader()->response());
-
// FIXME: This API should be turned around so that we ground CachedPage into the Page.
cachedPage->restore(*m_frame.page());
@@ -1826,10 +1854,6 @@ void FrameLoader::commitProvisionalLoad()
if (!title.isNull())
m_client.dispatchDidReceiveTitle(title);
- // Send remaining notifications for the main resource.
- notifier().sendRemainingDelegateMessages(m_documentLoader.get(), mainResourceIdentifier, mainResourceRequest, ResourceResponse(),
- nullptr, static_cast<int>(m_documentLoader->response().expectedContentLength()), 0, mainResouceError);
-
checkCompleted();
} else
didOpenURL();
@@ -1837,7 +1861,7 @@ void FrameLoader::commitProvisionalLoad()
LOG(Loading, "WebCoreLoading %s: Finished committing provisional load to URL %s", m_frame.tree().uniqueName().string().utf8().data(),
m_frame.document() ? m_frame.document()->url().stringCenterEllipsizedToLength().utf8().data() : "");
- if (m_loadType == FrameLoadType::Standard && m_documentLoader->isClientRedirect())
+ if (m_loadType == FrameLoadTypeStandard && m_documentLoader->isClientRedirect())
history().updateForClientRedirect();
if (m_loadingFromCachedPage) {
@@ -1846,19 +1870,19 @@ void FrameLoader::commitProvisionalLoad()
if (m_frame.document()->doctype() && m_frame.page())
m_frame.page()->chrome().didReceiveDocType(&m_frame);
#endif
- m_frame.document()->resume(ActiveDOMObject::PageCache);
+ m_frame.document()->documentDidResumeFromPageCache();
// Force a layout to update view size and thereby update scrollbars.
#if PLATFORM(IOS)
- if (!m_client.forceLayoutOnRestoreFromPageCache())
- m_frame.view()->forceLayout();
+ m_client.forceLayoutWithoutRecalculatingStyles();
#else
m_frame.view()->forceLayout();
#endif
- // Main resource delegates were already sent, so we skip the first response here.
- for (unsigned i = 1; i < m_documentLoader->responses().size(); ++i) {
- const auto& response = m_documentLoader->responses()[i];
+ const ResponseVector& responses = m_documentLoader->responses();
+ size_t count = responses.size();
+ for (size_t i = 0; i < count; i++) {
+ const ResourceResponse& response = responses[i];
// FIXME: If the WebKit client changes or cancels the request, this is not respected.
ResourceError error;
unsigned long identifier;
@@ -1907,7 +1931,7 @@ void FrameLoader::transitionToCommitted(CachedPage* cachedPage)
m_documentLoader->stopLoadingPlugIns();
setDocumentLoader(m_provisionalDocumentLoader.get());
- setProvisionalDocumentLoader(nullptr);
+ setProvisionalDocumentLoader(0);
if (pdl != m_documentLoader) {
ASSERT(m_state == FrameStateComplete);
@@ -1925,57 +1949,57 @@ void FrameLoader::transitionToCommitted(CachedPage* cachedPage)
DocumentLoader* dl = m_documentLoader.get();
switch (m_loadType) {
- case FrameLoadType::Forward:
- case FrameLoadType::Back:
- case FrameLoadType::IndexedBackForward:
- if (m_frame.page()) {
- // If the first load within a frame is a navigation within a back/forward list that was attached
- // without any of the items being loaded then we need to update the history in a similar manner as
- // for a standard load with the exception of updating the back/forward list (<rdar://problem/8091103>).
- if (!m_stateMachine.committedFirstRealDocumentLoad() && m_frame.isMainFrame())
- history().updateForStandardLoad(HistoryController::UpdateAllExceptBackForwardList);
-
- history().updateForBackForwardNavigation();
-
- // For cached pages, CachedFrame::restore will take care of firing the popstate event with the history item's state object
- if (history().currentItem() && !cachedPage)
- m_pendingStateObject = history().currentItem()->stateObject();
-
- // Create a document view for this document, or used the cached view.
- if (cachedPage) {
- DocumentLoader* cachedDocumentLoader = cachedPage->documentLoader();
- ASSERT(cachedDocumentLoader);
- cachedDocumentLoader->attachToFrame(m_frame);
- m_client.transitionToCommittedFromCachedFrame(cachedPage->cachedMainFrame());
- } else
- m_client.transitionToCommittedForNewPage();
- }
- break;
-
- case FrameLoadType::Reload:
- case FrameLoadType::ReloadFromOrigin:
- case FrameLoadType::Same:
- case FrameLoadType::Replace:
- history().updateForReload();
- m_client.transitionToCommittedForNewPage();
- break;
-
- case FrameLoadType::Standard:
- history().updateForStandardLoad();
- if (m_frame.view())
- m_frame.view()->setScrollbarsSuppressed(true);
- m_client.transitionToCommittedForNewPage();
- break;
-
- case FrameLoadType::RedirectWithLockedBackForwardList:
- history().updateForRedirectWithLockedBackForwardList();
- m_client.transitionToCommittedForNewPage();
- break;
-
- // FIXME Remove this check when dummy ds is removed (whatever "dummy ds" is).
- // An exception should be thrown if we're in the FrameLoadTypeUninitialized state.
- default:
- ASSERT_NOT_REACHED();
+ case FrameLoadTypeForward:
+ case FrameLoadTypeBack:
+ case FrameLoadTypeIndexedBackForward:
+ if (m_frame.page()) {
+ // If the first load within a frame is a navigation within a back/forward list that was attached
+ // without any of the items being loaded then we need to update the history in a similar manner as
+ // for a standard load with the exception of updating the back/forward list (<rdar://problem/8091103>).
+ if (!m_stateMachine.committedFirstRealDocumentLoad() && m_frame.isMainFrame())
+ history().updateForStandardLoad(HistoryController::UpdateAllExceptBackForwardList);
+
+ history().updateForBackForwardNavigation();
+
+ // For cached pages, CachedFrame::restore will take care of firing the popstate event with the history item's state object
+ if (history().currentItem() && !cachedPage)
+ m_pendingStateObject = history().currentItem()->stateObject();
+
+ // Create a document view for this document, or used the cached view.
+ if (cachedPage) {
+ DocumentLoader* cachedDocumentLoader = cachedPage->documentLoader();
+ ASSERT(cachedDocumentLoader);
+ cachedDocumentLoader->setFrame(&m_frame);
+ m_client.transitionToCommittedFromCachedFrame(cachedPage->cachedMainFrame());
+ } else
+ m_client.transitionToCommittedForNewPage();
+ }
+ break;
+
+ case FrameLoadTypeReload:
+ case FrameLoadTypeReloadFromOrigin:
+ case FrameLoadTypeSame:
+ case FrameLoadTypeReplace:
+ history().updateForReload();
+ m_client.transitionToCommittedForNewPage();
+ break;
+
+ case FrameLoadTypeStandard:
+ history().updateForStandardLoad();
+ if (m_frame.view())
+ m_frame.view()->setScrollbarsSuppressed(true);
+ m_client.transitionToCommittedForNewPage();
+ break;
+
+ case FrameLoadTypeRedirectWithLockedBackForwardList:
+ history().updateForRedirectWithLockedBackForwardList();
+ m_client.transitionToCommittedForNewPage();
+ break;
+
+ // FIXME Remove this check when dummy ds is removed (whatever "dummy ds" is).
+ // An exception should be thrown if we're in the FrameLoadTypeUninitialized state.
+ default:
+ ASSERT_NOT_REACHED();
}
m_documentLoader->writer().setMIMEType(dl->responseMIMEType());
@@ -2003,7 +2027,7 @@ void FrameLoader::clientRedirectCancelledOrFinished(bool cancelWithLoadInProgres
m_sentRedirectNotification = false;
}
-void FrameLoader::clientRedirected(const URL& url, double seconds, double fireDate, LockBackForwardList lockBackForwardList)
+void FrameLoader::clientRedirected(const URL& url, double seconds, double fireDate, bool lockBackForwardList)
{
m_client.dispatchWillPerformClientRedirect(url, seconds, fireDate);
@@ -2015,7 +2039,7 @@ void FrameLoader::clientRedirected(const URL& url, double seconds, double fireDa
// load as part of the original navigation. If we don't have a document loader, we have
// no "original" load on which to base a redirect, so we treat the redirect as a normal load.
// Loads triggered by JavaScript form submissions never count as quick redirects.
- m_quickRedirectComing = (lockBackForwardList == LockBackForwardList::Yes || history().currentItemShouldBeReplaced()) && m_documentLoader && !m_isExecutingJavaScriptFormAction;
+ m_quickRedirectComing = (lockBackForwardList || history().currentItemShouldBeReplaced()) && m_documentLoader && !m_isExecutingJavaScriptFormAction;
}
bool FrameLoader::shouldReload(const URL& currentURL, const URL& destinationURL)
@@ -2094,15 +2118,13 @@ void FrameLoader::open(CachedFrameBase& cachedFrame)
ASSERT(view);
view->setWasScrolledByUser(false);
- Optional<IntRect> previousViewFrameRect = m_frame.view() ? m_frame.view()->frameRect() : Optional<IntRect>(Nullopt);
+ // Use the current ScrollView's frame rect.
+ if (m_frame.view())
+ view->setFrameRect(m_frame.view()->frameRect());
m_frame.setView(view);
-
- // Use the previous ScrollView's frame rect.
- if (previousViewFrameRect)
- view->setFrameRect(previousViewFrameRect.value());
m_frame.setDocument(document);
- document->domWindow()->resumeFromDocumentSuspension();
+ document->domWindow()->resumeFromPageCache();
updateFirstPartyForCookies();
@@ -2117,12 +2139,12 @@ bool FrameLoader::isHostedByObjectElement() const
bool FrameLoader::isReplacing() const
{
- return m_loadType == FrameLoadType::Replace;
+ return m_loadType == FrameLoadTypeReplace;
}
void FrameLoader::setReplacing()
{
- m_loadType = FrameLoadType::Replace;
+ m_loadType = FrameLoadTypeReplace;
}
bool FrameLoader::subframeIsLoading() const
@@ -2158,7 +2180,7 @@ CachePolicy FrameLoader::subresourceCachePolicy() const
if (m_isComplete)
return CachePolicyVerify;
- if (m_loadType == FrameLoadType::ReloadFromOrigin)
+ if (m_loadType == FrameLoadTypeReloadFromOrigin)
return CachePolicyReload;
if (Frame* parentFrame = m_frame.tree().parent()) {
@@ -2167,24 +2189,18 @@ CachePolicy FrameLoader::subresourceCachePolicy() const
return parentCachePolicy;
}
- switch (m_loadType) {
- case FrameLoadType::Reload:
+ if (m_loadType == FrameLoadTypeReload)
+ return CachePolicyRevalidate;
+
+ const ResourceRequest& request(documentLoader()->request());
+#if PLATFORM(MAC)
+ if (request.cachePolicy() == ReloadIgnoringCacheData && !equalIgnoringCase(request.httpMethod(), "post") && ResourceRequest::useQuickLookResourceCachingQuirks())
return CachePolicyRevalidate;
- case FrameLoadType::Back:
- case FrameLoadType::Forward:
- case FrameLoadType::IndexedBackForward:
+#endif
+
+ if (request.cachePolicy() == ReturnCacheDataElseLoad)
return CachePolicyHistoryBuffer;
- case FrameLoadType::ReloadFromOrigin:
- ASSERT_NOT_REACHED(); // Already handled above.
- return CachePolicyReload;
- case FrameLoadType::RedirectWithLockedBackForwardList:
- case FrameLoadType::Replace:
- case FrameLoadType::Same:
- case FrameLoadType::Standard:
- return CachePolicyVerify;
- }
- RELEASE_ASSERT_NOT_REACHED();
return CachePolicyVerify;
}
@@ -2194,11 +2210,7 @@ void FrameLoader::checkLoadCompleteForThisFrame()
switch (m_state) {
case FrameStateProvisional: {
- // FIXME: Prohibiting any provisional load failures from being sent to clients
- // while handling provisional load failures is too heavy. For example, the current
- // load will fail to cancel another ongoing load. That might prevent clients' page
- // load state being handled properly.
- if (!m_provisionalLoadErrorBeingHandledURL.isEmpty())
+ if (m_delegateIsHandlingProvisionalLoadError)
return;
RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
@@ -2220,9 +2232,9 @@ void FrameLoader::checkLoadCompleteForThisFrame()
// Only reset if we aren't already going to a new provisional item.
bool shouldReset = !history().provisionalItem();
if (!pdl->isLoadingInAPISense() || pdl->isStopping()) {
- m_provisionalLoadErrorBeingHandledURL = m_provisionalDocumentLoader->url();
+ m_delegateIsHandlingProvisionalLoadError = true;
m_client.dispatchDidFailProvisionalLoad(error);
- m_provisionalLoadErrorBeingHandledURL = { };
+ m_delegateIsHandlingProvisionalLoadError = false;
ASSERT(!pdl->isLoading());
@@ -2263,7 +2275,7 @@ void FrameLoader::checkLoadCompleteForThisFrame()
// If the user had a scroll point, scroll to it, overriding the anchor point if any.
if (m_frame.page()) {
- if (isBackForwardLoadType(m_loadType) || m_loadType == FrameLoadType::Reload || m_loadType == FrameLoadType::ReloadFromOrigin)
+ if (isBackForwardLoadType(m_loadType) || m_loadType == FrameLoadTypeReload || m_loadType == FrameLoadTypeReloadFromOrigin)
history().restoreScrollPositionAndViewState();
}
@@ -2271,8 +2283,7 @@ void FrameLoader::checkLoadCompleteForThisFrame()
return;
m_progressTracker->progressCompleted();
- Page* page = m_frame.page();
- if (page) {
+ if (Page* page = m_frame.page()) {
if (m_frame.isMainFrame())
page->resetRelevantPaintedObjectCounter();
}
@@ -2284,14 +2295,6 @@ void FrameLoader::checkLoadCompleteForThisFrame()
m_client.dispatchDidFailLoad(error);
loadingEvent = AXObjectCache::AXLoadingFailed;
} else {
-#if ENABLE(DATA_DETECTION)
- if (m_frame.settings().dataDetectorTypes() != DataDetectorTypeNone) {
- RefPtr<Range> documentRange = makeRange(firstPositionInNode(m_frame.document()->documentElement()), lastPositionInNode(m_frame.document()->documentElement()));
- m_frame.setDataDetectionResults(DataDetection::detectContentInRange(documentRange, m_frame.settings().dataDetectorTypes()));
- if (m_frame.isMainFrame())
- m_client.dispatchDidFinishDataDetection(m_frame.dataDetectionResults());
- }
-#endif
m_client.dispatchDidFinishLoad();
loadingEvent = AXObjectCache::AXLoadingFinished;
}
@@ -2300,19 +2303,11 @@ void FrameLoader::checkLoadCompleteForThisFrame()
if (AXObjectCache* cache = m_frame.document()->existingAXObjectCache())
cache->frameLoadingEventNotification(&m_frame, loadingEvent);
- // The above calls to dispatchDidFinishLoad() might have detached the Frame
- // from its Page and also might have caused Page to be deleted.
- // Don't assume 'page' is still available to use.
- if (m_frame.isMainFrame() && m_frame.page()) {
- ASSERT(&m_frame.page()->mainFrame() == &m_frame);
- m_frame.page()->mainFrame().diagnosticLoggingClient().logDiagnosticMessageWithResult(DiagnosticLoggingKeys::pageLoadedKey(), emptyString(), error.isNull() ? DiagnosticLoggingResultPass : DiagnosticLoggingResultFail, ShouldSample::Yes);
- }
-
return;
}
case FrameStateComplete:
- m_loadType = FrameLoadType::Standard;
+ m_loadType = FrameLoadTypeStandard;
frameLoadCompleted();
return;
}
@@ -2385,7 +2380,7 @@ void FrameLoader::setOriginalURLForDownloadRequest(ResourceRequest& request)
// FIXME: Using host-only URL is a very heavy-handed approach. We should attempt to provide the actual page where the download was initiated from, as a reminder to the user.
String hostOnlyURLString;
if (port)
- hostOnlyURLString = makeString(originalURL.protocol(), "://", originalURL.host(), ':', String::number(port));
+ hostOnlyURLString = makeString(originalURL.protocol(), "://", originalURL.host(), ":", String::number(port));
else
hostOnlyURLString = makeString(originalURL.protocol(), "://", originalURL.host());
@@ -2433,25 +2428,19 @@ void FrameLoader::frameLoadCompleted()
void FrameLoader::detachChildren()
{
- // detachChildren() will fire the unload event in each subframe and the
- // HTML specification states that the parent document's ignore-opens-during-unload counter while
- // this event is being fired in its subframes:
- // https://html.spec.whatwg.org/multipage/browsers.html#unload-a-document
- IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
-
Vector<Ref<Frame>, 16> childrenToDetach;
childrenToDetach.reserveInitialCapacity(m_frame.tree().childCount());
for (Frame* child = m_frame.tree().lastChild(); child; child = child->tree().previousSibling())
childrenToDetach.uncheckedAppend(*child);
- for (auto& child : childrenToDetach)
- child->loader().detachFromParent();
+ for (unsigned i = 0; i < childrenToDetach.size(); ++i)
+ childrenToDetach[i]->loader().detachFromParent();
}
void FrameLoader::closeAndRemoveChild(Frame* child)
{
child->tree().detachFromParent();
- child->setView(nullptr);
+ child->setView(0);
if (child->ownerElement() && child->page())
child->page()->decrementSubframeCount();
child->willDetachPage();
@@ -2477,20 +2466,18 @@ void FrameLoader::checkLoadComplete()
frames.append(*frame);
// To process children before their parents, iterate the vector backwards.
- for (auto frame = frames.rbegin(); frame != frames.rend(); ++frame) {
- if ((*frame)->page())
- (*frame)->loader().checkLoadCompleteForThisFrame();
- }
+ for (unsigned i = frames.size(); i; --i)
+ frames[i - 1]->loader().checkLoadCompleteForThisFrame();
}
int FrameLoader::numPendingOrLoadingRequests(bool recurse) const
{
if (!recurse)
- return m_frame.document()->cachedResourceLoader().requestCount();
+ return m_frame.document()->cachedResourceLoader()->requestCount();
int count = 0;
for (Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext(&m_frame))
- count += frame->document()->cachedResourceLoader().requestCount();
+ count += frame->document()->cachedResourceLoader()->requestCount();
return count;
}
@@ -2499,19 +2486,16 @@ String FrameLoader::userAgent(const URL& url) const
return m_client.userAgent(url);
}
-void FrameLoader::dispatchOnloadEvents()
+void FrameLoader::handledOnloadEvents()
{
- m_client.dispatchDidDispatchOnloadEvents();
+ m_client.dispatchDidHandleOnloadEvents();
if (documentLoader())
- documentLoader()->dispatchOnloadEvents();
+ documentLoader()->handledOnloadEvents();
}
void FrameLoader::frameDetached()
{
- // Calling stopAllLoaders can cause the frame to be deallocated, including the frame loader.
- Ref<Frame> protectedFrame(m_frame);
-
stopAllLoaders();
m_frame.document()->stopActiveDOMObjects();
detachFromParent();
@@ -2529,7 +2513,7 @@ void FrameLoader::detachFromParent()
// handlers might start a new subresource load in this frame.
stopAllLoaders();
- InspectorInstrumentation::frameDetachedFromParent(m_frame);
+ InspectorInstrumentation::frameDetachedFromParent(&m_frame);
detachViewsAndDocumentLoader();
@@ -2539,7 +2523,7 @@ void FrameLoader::detachFromParent()
parent->loader().closeAndRemoveChild(&m_frame);
parent->loader().scheduleCheckCompleted();
} else {
- m_frame.setView(nullptr);
+ m_frame.setView(0);
m_frame.willDetachPage();
m_frame.detachFromPage();
}
@@ -2548,7 +2532,7 @@ void FrameLoader::detachFromParent()
void FrameLoader::detachViewsAndDocumentLoader()
{
m_client.detachedFromParent2();
- setDocumentLoader(nullptr);
+ setDocumentLoader(0);
m_client.detachedFromParent3();
}
@@ -2602,20 +2586,15 @@ void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadTyp
// FIXME: Other FrameLoader functions have duplicated code for setting cache policy of main request when reloading.
// It seems better to manage it explicitly than to hide the logic inside addExtraFieldsToRequest().
- } else if (loadType == FrameLoadType::Reload || loadType == FrameLoadType::ReloadFromOrigin || request.isConditional())
+ } else if (loadType == FrameLoadTypeReload || loadType == FrameLoadTypeReloadFromOrigin || request.isConditional())
request.setCachePolicy(ReloadIgnoringCacheData);
- if (m_overrideCachePolicyForTesting)
- request.setCachePolicy(m_overrideCachePolicyForTesting.value());
- if (m_overrideResourceLoadPriorityForTesting)
- request.setPriority(m_overrideResourceLoadPriorityForTesting.value());
-
if (request.cachePolicy() == ReloadIgnoringCacheData) {
- if (loadType == FrameLoadType::Reload)
- request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0");
- else if (loadType == FrameLoadType::ReloadFromOrigin) {
- request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "no-cache");
- request.setHTTPHeaderField(HTTPHeaderName::Pragma, "no-cache");
+ if (loadType == FrameLoadTypeReload)
+ request.setHTTPHeaderField("Cache-Control", "max-age=0");
+ else if (loadType == FrameLoadTypeReloadFromOrigin) {
+ request.setHTTPHeaderField("Cache-Control", "no-cache");
+ request.setHTTPHeaderField("Pragma", "no-cache");
}
}
@@ -2659,17 +2638,16 @@ void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, const String&
request.setHTTPOrigin(origin);
}
-void FrameLoader::loadPostRequest(const FrameLoadRequest& request, const String& referrer, FrameLoadType loadType, Event* event, PassRefPtr<FormState> prpFormState)
+void FrameLoader::loadPostRequest(const ResourceRequest& inRequest, const String& referrer, const String& frameName, bool lockHistory, FrameLoadType loadType, PassRefPtr<Event> event, PassRefPtr<FormState> prpFormState)
{
RefPtr<FormState> formState = prpFormState;
- String frameName = request.frameName();
- LockHistory lockHistory = request.lockHistory();
- AllowNavigationToInvalidURL allowNavigationToInvalidURL = request.allowNavigationToInvalidURL();
- NewFrameOpenerPolicy openerPolicy = request.newFrameOpenerPolicy();
-
- const ResourceRequest& inRequest = request.resourceRequest();
+ // Previously when this method was reached, the original FrameLoadRequest had been deconstructed to build a
+ // bunch of parameters that would come in here and then be built back up to a ResourceRequest. In case
+ // any caller depends on the immutability of the original ResourceRequest, I'm rebuilding a ResourceRequest
+ // from scratch as it did all along.
const URL& url = inRequest.url();
+ RefPtr<FormData> formData = inRequest.httpBody();
const String& contentType = inRequest.httpContentType();
String origin = inRequest.httpOrigin();
@@ -2679,28 +2657,28 @@ void FrameLoader::loadPostRequest(const FrameLoadRequest& request, const String&
workingResourceRequest.setHTTPReferrer(referrer);
workingResourceRequest.setHTTPOrigin(origin);
workingResourceRequest.setHTTPMethod("POST");
- workingResourceRequest.setHTTPBody(inRequest.httpBody());
+ workingResourceRequest.setHTTPBody(formData);
workingResourceRequest.setHTTPContentType(contentType);
addExtraFieldsToRequest(workingResourceRequest, loadType, true);
- NavigationAction action(workingResourceRequest, loadType, true, event, request.shouldOpenExternalURLsPolicy());
+ NavigationAction action(workingResourceRequest, loadType, true, event);
if (!frameName.isEmpty()) {
// The search for a target frame is done earlier in the case of form submission.
if (Frame* targetFrame = formState ? 0 : findFrameForNavigation(frameName)) {
- targetFrame->loader().loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState.release(), allowNavigationToInvalidURL);
+ targetFrame->loader().loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState.release());
return;
}
- policyChecker().checkNewWindowPolicy(action, workingResourceRequest, formState.release(), frameName, [this, allowNavigationToInvalidURL, openerPolicy](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
- continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
+ policyChecker().checkNewWindowPolicy(action, workingResourceRequest, formState.release(), frameName, [this](const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue) {
+ continueLoadAfterNewWindowPolicy(request, formState, frameName, action, shouldContinue);
});
return;
}
// must grab this now, since this load may stop the previous load and clear this flag
bool isRedirect = m_quickRedirectComing;
- loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState.release(), allowNavigationToInvalidURL);
+ loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState.release());
if (isRedirect) {
m_quickRedirectComing = false;
if (m_provisionalDocumentLoader)
@@ -2708,7 +2686,7 @@ void FrameLoader::loadPostRequest(const FrameLoadRequest& request, const String&
}
}
-unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ClientCredentialPolicy clientCredentialPolicy, ResourceError& error, ResourceResponse& response, RefPtr<SharedBuffer>& data)
+unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ClientCredentialPolicy clientCredentialPolicy, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
ASSERT(m_frame.document());
String referrer = SecurityPolicy::generateReferrerHeader(m_frame.document()->referrerPolicy(), request.url(), outgoingReferrer());
@@ -2728,32 +2706,15 @@ unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& requ
ResourceRequest newRequest(initialRequest);
requestFromDelegate(newRequest, identifier, error);
-#if ENABLE(CONTENT_EXTENSIONS)
- if (error.isNull()) {
- if (auto* page = m_frame.page()) {
- if (auto* controller = page->userContentController()) {
- if (m_documentLoader && controller->processContentExtensionRulesForLoad(newRequest, ResourceType::Raw, *m_documentLoader) == ContentExtensions::BlockedStatus::Blocked) {
- newRequest = { };
- error = ResourceError(errorDomainWebKitInternal, 0, initialRequest.url(), emptyString());
- response = { };
- data = nullptr;
- }
- }
- }
- }
-#endif
-
if (error.isNull()) {
ASSERT(!newRequest.isNull());
-
+
if (!documentLoader()->applicationCacheHost()->maybeLoadSynchronously(newRequest, error, response, data)) {
- Vector<char> buffer;
- platformStrategies()->loaderStrategy()->loadResourceSynchronously(networkingContext(), identifier, newRequest, storedCredentials, clientCredentialPolicy, error, response, buffer);
- data = SharedBuffer::adoptVector(buffer);
+ platformStrategies()->loaderStrategy()->loadResourceSynchronously(networkingContext(), identifier, newRequest, storedCredentials, clientCredentialPolicy, error, response, data);
documentLoader()->applicationCacheHost()->maybeLoadFallbackSynchronously(newRequest, error, response, data);
}
}
- notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, response, data ? data->data() : nullptr, data ? data->size() : 0, -1, error);
+ notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, response, data.data(), data.size(), -1, error);
return identifier;
}
@@ -2804,17 +2765,13 @@ void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequ
if (!shouldContinue)
return;
- // Calling stopLoading() on the provisional document loader can cause the underlying
- // frame to be deallocated.
- Ref<Frame> protectedFrame(m_frame);
-
// If we have a provisional request for a different document, a fragment scroll should cancel it.
if (m_provisionalDocumentLoader && !equalIgnoringFragmentIdentifier(m_provisionalDocumentLoader->request().url(), request.url())) {
m_provisionalDocumentLoader->stopLoading();
- setProvisionalDocumentLoader(nullptr);
+ setProvisionalDocumentLoader(0);
}
- bool isRedirect = m_quickRedirectComing || policyChecker().loadType() == FrameLoadType::RedirectWithLockedBackForwardList;
+ bool isRedirect = m_quickRedirectComing || policyChecker().loadType() == FrameLoadTypeRedirectWithLockedBackForwardList;
loadInSameDocument(request.url(), 0, !isRedirect);
}
@@ -2826,10 +2783,10 @@ bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, const S
// FIXME: What about load types other than Standard and Reload?
- return (!isFormSubmission || equalLettersIgnoringASCIICase(httpMethod, "get"))
- && loadType != FrameLoadType::Reload
- && loadType != FrameLoadType::ReloadFromOrigin
- && loadType != FrameLoadType::Same
+ return (!isFormSubmission || equalIgnoringCase(httpMethod, "GET"))
+ && loadType != FrameLoadTypeReload
+ && loadType != FrameLoadTypeReloadFromOrigin
+ && loadType != FrameLoadTypeSame
&& !shouldReload(m_frame.document()->url(), url)
// We don't want to just scroll if a link from within a
// frameset is trying to reload the frameset into _top.
@@ -2876,7 +2833,7 @@ bool FrameLoader::shouldClose()
for (i = 0; i < targetFrames.size(); i++) {
if (!targetFrames[i]->tree().isDescendantOf(&m_frame))
continue;
- if (!targetFrames[i]->loader().dispatchBeforeUnloadEvent(page->chrome(), this))
+ if (!targetFrames[i]->loader().handleBeforeUnloadEvent(page->chrome(), this))
break;
}
@@ -2891,95 +2848,36 @@ bool FrameLoader::shouldClose()
return shouldClose;
}
-void FrameLoader::dispatchUnloadEvents(UnloadEventPolicy unloadEventPolicy)
-{
- if (!m_frame.document())
- return;
-
- // We store the frame's page in a local variable because the frame might get detached inside dispatchEvent.
- ForbidPromptsScope forbidPrompts(m_frame.page());
- IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
-
- if (m_didCallImplicitClose && !m_wasUnloadEventEmitted) {
- auto* currentFocusedElement = m_frame.document()->focusedElement();
- if (is<HTMLInputElement>(currentFocusedElement))
- downcast<HTMLInputElement>(*currentFocusedElement).endEditing();
- if (m_pageDismissalEventBeingDispatched == PageDismissalType::None) {
- if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) {
- m_pageDismissalEventBeingDispatched = PageDismissalType::PageHide;
- m_frame.document()->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame.document()->inPageCache()), m_frame.document());
- }
-
- // FIXME: update Page Visibility state here.
- // https://bugs.webkit.org/show_bug.cgi?id=116770
-
- if (!m_frame.document()->inPageCache()) {
- Ref<Event> unloadEvent(Event::create(eventNames().unloadEvent, false, false));
- // The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed
- // while dispatching the event, so protect it to prevent writing the end
- // time into freed memory.
- RefPtr<DocumentLoader> documentLoader = m_provisionalDocumentLoader;
- m_pageDismissalEventBeingDispatched = PageDismissalType::Unload;
- if (documentLoader && documentLoader->timing().navigationStart() && !documentLoader->timing().unloadEventStart() && !documentLoader->timing().unloadEventEnd()) {
- auto& timing = documentLoader->timing();
- timing.markUnloadEventStart();
- m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
- timing.markUnloadEventEnd();
- } else
- m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
- }
- }
- m_pageDismissalEventBeingDispatched = PageDismissalType::None;
- if (m_frame.document())
- m_frame.document()->updateStyleIfNeeded();
- m_wasUnloadEventEmitted = true;
- }
-
- // Dispatching the unload event could have made m_frame.document() null.
- if (!m_frame.document())
- return;
-
- if (m_frame.document()->inPageCache())
- return;
-
- // Don't remove event listeners from a transitional empty document (see bug 28716 for more information).
- bool keepEventListeners = m_stateMachine.isDisplayingInitialEmptyDocument() && m_provisionalDocumentLoader
- && m_frame.document()->isSecureTransitionTo(m_provisionalDocumentLoader->url());
-
- if (!keepEventListeners)
- m_frame.document()->removeAllEventListeners();
-}
-
-bool FrameLoader::dispatchBeforeUnloadEvent(Chrome& chrome, FrameLoader* frameLoaderBeingNavigated)
+bool FrameLoader::handleBeforeUnloadEvent(Chrome& chrome, FrameLoader* frameLoaderBeingNavigated)
{
DOMWindow* domWindow = m_frame.document()->domWindow();
if (!domWindow)
return true;
RefPtr<Document> document = m_frame.document();
- if (!document->bodyOrFrameset())
+ if (!document->body())
return true;
- Ref<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
- m_pageDismissalEventBeingDispatched = PageDismissalType::BeforeUnload;
+ RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
+ m_pageDismissalEventBeingDispatched = BeforeUnloadDismissal;
- {
- ForbidPromptsScope forbidPrompts(m_frame.page());
- IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
- domWindow->dispatchEvent(beforeUnloadEvent, domWindow->document());
- }
+ // We store the frame's page in a local variable because the frame might get detached inside dispatchEvent.
+ Page* page = m_frame.page();
+ page->incrementFrameHandlingBeforeUnloadEventCount();
+ domWindow->dispatchEvent(beforeUnloadEvent.get(), domWindow->document());
+ page->decrementFrameHandlingBeforeUnloadEventCount();
- m_pageDismissalEventBeingDispatched = PageDismissalType::None;
+ m_pageDismissalEventBeingDispatched = NoDismissal;
if (!beforeUnloadEvent->defaultPrevented())
- document->defaultEventHandler(beforeUnloadEvent.ptr());
+ document->defaultEventHandler(beforeUnloadEvent.get());
if (beforeUnloadEvent->returnValue().isNull())
return true;
// If the navigating FrameLoader has already shown a beforeunload confirmation panel for the current navigation attempt,
// this frame is not allowed to cause another one to be shown.
if (frameLoaderBeingNavigated->m_currentNavigationHasShownBeforeUnloadConfirmPanel) {
- document->addConsoleMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("Blocked attempt to show multiple beforeunload confirmation dialogs for the same navigation."));
+ document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Blocked attempt to show multiple beforeunload confirmation dialogs for the same navigation.");
return true;
}
@@ -2992,7 +2890,7 @@ bool FrameLoader::dispatchBeforeUnloadEvent(Chrome& chrome, FrameLoader* frameLo
if (!parentDocument)
return true;
if (!m_frame.document() || !m_frame.document()->securityOrigin()->canAccess(parentDocument->securityOrigin())) {
- document->addConsoleMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("Blocked attempt to show beforeunload confirmation dialog on behalf of a frame with different security origin. Protocols, domains, and ports must match."));
+ document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Blocked attempt to show beforeunload confirmation dialog on behalf of a frame with different security origin. Protocols, domains, and ports must match.");
return true;
}
@@ -3013,7 +2911,7 @@ bool FrameLoader::dispatchBeforeUnloadEvent(Chrome& chrome, FrameLoader* frameLo
return chrome.runBeforeUnloadConfirmPanel(text, &m_frame);
}
-void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest& request, PassRefPtr<FormState> formState, bool shouldContinue, AllowNavigationToInvalidURL allowNavigationToInvalidURL)
+void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest&, PassRefPtr<FormState> formState, bool shouldContinue)
{
// If we loaded an alternate page to replace an unreachableURL, we'll get in here with a
// nil policyDataSource because loading the alternate page will have passed
@@ -3022,23 +2920,19 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest& reque
bool isTargetItem = history().provisionalItem() ? history().provisionalItem()->isTargetItem() : false;
- bool urlIsDisallowed = allowNavigationToInvalidURL == AllowNavigationToInvalidURL::No && !request.url().isValid();
-
- // Three reasons we can't continue:
+ // Two reasons we can't continue:
// 1) Navigation policy delegate said we can't so request is nil. A primary case of this
// is the user responding Cancel to the form repost nag sheet.
// 2) User responded Cancel to an alert popped up by the before unload event handler.
- // 3) The request's URL is invalid and navigation to invalid URLs is disallowed.
- bool canContinue = shouldContinue && shouldClose() && !urlIsDisallowed;
+ bool canContinue = shouldContinue && shouldClose();
if (!canContinue) {
// If we were waiting for a quick redirect, but the policy delegate decided to ignore it, then we
// need to report that the client redirect was cancelled.
- // FIXME: The client should be told about ignored non-quick redirects, too.
if (m_quickRedirectComing)
clientRedirectCancelledOrFinished(false);
- setPolicyDocumentLoader(nullptr);
+ setPolicyDocumentLoader(0);
// If the navigation request came from the back/forward menu, and we punt on it, we have the
// problem that we have optimistically moved the b/f cursor already, so move it back. For sanity,
@@ -3063,20 +2957,22 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest& reque
if (!m_frame.page())
return;
+#if ENABLE(INSPECTOR)
+ if (Page* page = m_frame.page()) {
+ if (m_frame.isMainFrame())
+ page->inspectorController().resume();
+ }
+#endif
+
setProvisionalDocumentLoader(m_policyDocumentLoader.get());
m_loadType = type;
setState(FrameStateProvisional);
- setPolicyDocumentLoader(nullptr);
+ setPolicyDocumentLoader(0);
- if (isBackForwardLoadType(type)) {
- auto& diagnosticLoggingClient = m_frame.mainFrame().diagnosticLoggingClient();
- if (history().provisionalItem()->isInPageCache()) {
- diagnosticLoggingClient.logDiagnosticMessageWithResult(DiagnosticLoggingKeys::pageCacheKey(), DiagnosticLoggingKeys::retrievalKey(), DiagnosticLoggingResultPass, ShouldSample::Yes);
- loadProvisionalItemFromCachedPage();
- return;
- }
- diagnosticLoggingClient.logDiagnosticMessageWithResult(DiagnosticLoggingKeys::pageCacheKey(), DiagnosticLoggingKeys::retrievalKey(), DiagnosticLoggingResultFail, ShouldSample::Yes);
+ if (isBackForwardLoadType(type) && history().provisionalItem()->isInPageCache()) {
+ loadProvisionalItemFromCachedPage();
+ return;
}
if (!formState) {
@@ -3090,7 +2986,7 @@ void FrameLoader::continueLoadAfterNavigationPolicy(const ResourceRequest& reque
}
void FrameLoader::continueLoadAfterNewWindowPolicy(const ResourceRequest& request,
- PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy openerPolicy)
+ PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action, bool shouldContinue)
{
if (!shouldContinue)
return;
@@ -3105,13 +3001,11 @@ void FrameLoader::continueLoadAfterNewWindowPolicy(const ResourceRequest& reques
mainFrame->page()->setOpenedByDOM();
mainFrame->loader().m_client.dispatchShow();
- if (openerPolicy == NewFrameOpenerPolicy::Allow) {
- mainFrame->loader().setOpener(frame.ptr());
+ if (!m_suppressOpenerInNewFrame) {
+ mainFrame->loader().setOpener(&frame.get());
mainFrame->document()->setReferrerPolicy(frame->document()->referrerPolicy());
}
-
- NavigationAction newAction(request, action.shouldOpenExternalURLsPolicy());
- mainFrame->loader().loadWithNavigationAction(request, newAction, LockHistory::No, FrameLoadType::Standard, formState, allowNavigationToInvalidURL);
+ mainFrame->loader().loadWithNavigationAction(request, NavigationAction(request), false, FrameLoadTypeStandard, formState);
}
void FrameLoader::requestFromDelegate(ResourceRequest& request, unsigned long& identifier, ResourceError& error)
@@ -3137,6 +3031,8 @@ void FrameLoader::requestFromDelegate(ResourceRequest& request, unsigned long& i
void FrameLoader::loadedResourceFromMemoryCache(CachedResource* resource, ResourceRequest& newRequest)
{
+ newRequest = ResourceRequest(resource->url());
+
Page* page = m_frame.page();
if (!page)
return;
@@ -3149,14 +3045,14 @@ void FrameLoader::loadedResourceFromMemoryCache(CachedResource* resource, Resour
return;
if (!page->areMemoryCacheClientCallsEnabled()) {
- InspectorInstrumentation::didLoadResourceFromMemoryCache(*page, m_documentLoader.get(), resource);
+ InspectorInstrumentation::didLoadResourceFromMemoryCache(page, m_documentLoader.get(), resource);
m_documentLoader->recordMemoryCacheLoadForFutureClientNotification(resource->resourceRequest());
m_documentLoader->didTellClientAboutLoad(resource->url());
return;
}
if (m_client.dispatchDidLoadResourceFromMemoryCache(m_documentLoader.get(), newRequest, resource->response(), resource->encodedSize())) {
- InspectorInstrumentation::didLoadResourceFromMemoryCache(*page, m_documentLoader.get(), resource);
+ InspectorInstrumentation::didLoadResourceFromMemoryCache(page, m_documentLoader.get(), resource);
m_documentLoader->didTellClientAboutLoad(resource->url());
return;
}
@@ -3164,7 +3060,7 @@ void FrameLoader::loadedResourceFromMemoryCache(CachedResource* resource, Resour
unsigned long identifier;
ResourceError error;
requestFromDelegate(newRequest, identifier, error);
- InspectorInstrumentation::markResourceAsCached(*page, identifier);
+ InspectorInstrumentation::markResourceAsCached(page, identifier);
notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, newRequest, resource->response(), 0, resource->encodedSize(), 0, error);
}
@@ -3177,6 +3073,8 @@ void FrameLoader::applyUserAgent(ResourceRequest& request)
bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, const URL& url, unsigned long requestIdentifier)
{
+ FeatureObserver::observe(m_frame.document(), FeatureObserver::XFrameOptions);
+
Frame& topFrame = m_frame.tree().top();
if (&m_frame == &topFrame)
return false;
@@ -3185,12 +3083,15 @@ bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, con
switch (disposition) {
case XFrameOptionsSameOrigin: {
+ FeatureObserver::observe(m_frame.document(), FeatureObserver::XFrameOptionsSameOrigin);
RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url);
if (!origin->isSameSchemeHostPort(topFrame.document()->securityOrigin()))
return true;
for (Frame* frame = m_frame.tree().parent(); frame; frame = frame->tree().parent()) {
- if (!origin->isSameSchemeHostPort(frame->document()->securityOrigin()))
+ if (!origin->isSameSchemeHostPort(frame->document()->securityOrigin())) {
+ FeatureObserver::observe(m_frame.document(), FeatureObserver::XFrameOptionsSameOriginWithBadAncestorChain);
break;
+ }
}
return false;
}
@@ -3199,16 +3100,15 @@ bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, con
case XFrameOptionsAllowAll:
return false;
case XFrameOptionsConflict:
- m_frame.document()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "Multiple 'X-Frame-Options' headers with conflicting values ('" + content + "') encountered when loading '" + url.stringCenterEllipsizedToLength() + "'. Falling back to 'DENY'.", requestIdentifier);
+ m_frame.document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Multiple 'X-Frame-Options' headers with conflicting values ('" + content + "') encountered when loading '" + url.stringCenterEllipsizedToLength() + "'. Falling back to 'DENY'.", requestIdentifier);
return true;
case XFrameOptionsInvalid:
- m_frame.document()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "Invalid 'X-Frame-Options' header encountered when loading '" + url.stringCenterEllipsizedToLength() + "': '" + content + "' is not a recognized directive. The header will be ignored.", requestIdentifier);
+ m_frame.document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Invalid 'X-Frame-Options' header encountered when loading '" + url.stringCenterEllipsizedToLength() + "': '" + content + "' is not a recognized directive. The header will be ignored.", requestIdentifier);
return false;
- case XFrameOptionsNone:
+ default:
+ ASSERT_NOT_REACHED();
return false;
}
- ASSERT_NOT_REACHED();
- return false;
}
void FrameLoader::loadProvisionalItemFromCachedPage()
@@ -3221,9 +3121,9 @@ void FrameLoader::loadProvisionalItemFromCachedPage()
m_loadingFromCachedPage = true;
// Should have timing data from previous time(s) the page was shown.
- ASSERT(provisionalLoader->timing().navigationStart());
+ ASSERT(provisionalLoader->timing()->navigationStart());
provisionalLoader->resetTiming();
- provisionalLoader->timing().markNavigationStart();
+ provisionalLoader->timing()->markNavigationStart();
provisionalLoader->setCommitted(true);
commitProvisionalLoad();
@@ -3238,7 +3138,7 @@ bool FrameLoader::shouldTreatURLAsSameAsCurrent(const URL& url) const
bool FrameLoader::shouldTreatURLAsSrcdocDocument(const URL& url) const
{
- if (!equalLettersIgnoringASCIICase(url.string(), "about:srcdoc"))
+ if (!equalIgnoringCase(url.string(), "about:srcdoc"))
return false;
HTMLFrameOwnerElement* ownerElement = m_frame.ownerElement();
if (!ownerElement)
@@ -3252,21 +3152,38 @@ Frame* FrameLoader::findFrameForNavigation(const AtomicString& name, Document* a
{
Frame* frame = m_frame.tree().find(name);
+ // From http://www.whatwg.org/specs/web-apps/current-work/#seamlessLinks:
+ //
+ // If the source browsing context is the same as the browsing context
+ // being navigated, and this browsing context has its seamless browsing
+ // context flag set, and the browsing context being navigated was not
+ // chosen using an explicit self-navigation override, then find the
+ // nearest ancestor browsing context that does not have its seamless
+ // browsing context flag set, and continue these steps as if that
+ // browsing context was the one that was going to be navigated instead.
+ if (frame == &m_frame && name != "_self" && m_frame.document()->shouldDisplaySeamlesslyWithParent()) {
+ for (Frame* ancestor = &m_frame; ancestor; ancestor = ancestor->tree().parent()) {
+ if (!ancestor->document()->shouldDisplaySeamlesslyWithParent()) {
+ frame = ancestor;
+ break;
+ }
+ }
+ ASSERT(frame != &m_frame);
+ }
+
// FIXME: Eventually all callers should supply the actual activeDocument so we can call canNavigate with the right document.
if (!activeDocument)
activeDocument = m_frame.document();
if (!activeDocument->canNavigate(frame))
- return nullptr;
+ return 0;
return frame;
}
-void FrameLoader::loadSameDocumentItem(HistoryItem& item)
+void FrameLoader::loadSameDocumentItem(HistoryItem* item)
{
- ASSERT(item.documentSequenceNumber() == history().currentItem()->documentSequenceNumber());
-
- Ref<Frame> protect(m_frame);
+ ASSERT(item->documentSequenceNumber() == history().currentItem()->documentSequenceNumber());
// Save user view state to the current history item here since we don't do a normal load.
// FIXME: Does form state need to be saved here too?
@@ -3274,10 +3191,10 @@ void FrameLoader::loadSameDocumentItem(HistoryItem& item)
if (FrameView* view = m_frame.view())
view->setWasScrolledByUser(false);
- history().setCurrentItem(&item);
+ history().setCurrentItem(item);
// loadInSameDocument() actually changes the URL and notifies load delegates of a "fake" load
- loadInSameDocument(item.url(), item.stateObject(), false);
+ loadInSameDocument(item->url(), item->stateObject(), false);
// Restore user view state from the current history item here since we don't do a normal load.
history().restoreScrollPositionAndViewState();
@@ -3286,45 +3203,37 @@ void FrameLoader::loadSameDocumentItem(HistoryItem& item)
// FIXME: This function should really be split into a couple pieces, some of
// which should be methods of HistoryController and some of which should be
// methods of FrameLoader.
-void FrameLoader::loadDifferentDocumentItem(HistoryItem& item, FrameLoadType loadType, FormSubmissionCacheLoadPolicy cacheLoadPolicy)
+void FrameLoader::loadDifferentDocumentItem(HistoryItem* item, FrameLoadType loadType, FormSubmissionCacheLoadPolicy cacheLoadPolicy)
{
// Remember this item so we can traverse any child items as child frames load
- history().setProvisionalItem(&item);
+ history().setProvisionalItem(item);
- if (CachedPage* cachedPage = PageCache::singleton().get(item, m_frame.page())) {
- auto documentLoader = cachedPage->documentLoader();
- m_client.updateCachedDocumentLoader(*documentLoader);
- documentLoader->setTriggeringAction(NavigationAction(documentLoader->request(), loadType, false));
- documentLoader->setLastCheckedRequest(ResourceRequest());
- loadWithDocumentLoader(documentLoader, loadType, 0, AllowNavigationToInvalidURL::Yes);
+ if (CachedPage* cachedPage = pageCache()->get(item)) {
+ loadWithDocumentLoader(cachedPage->documentLoader(), loadType, 0);
return;
}
- URL itemURL = item.url();
- URL itemOriginalURL = item.originalURL();
+ URL itemURL = item->url();
+ URL itemOriginalURL = item->originalURL();
URL currentURL;
if (documentLoader())
currentURL = documentLoader()->url();
- RefPtr<FormData> formData = item.formData();
+ RefPtr<FormData> formData = item->formData();
ResourceRequest request(itemURL);
- if (!item.referrer().isNull())
- request.setHTTPReferrer(item.referrer());
-
- ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(m_frame, item.shouldOpenExternalURLsPolicy());
- bool isFormSubmission = false;
- Event* event = nullptr;
-
+ if (!item->referrer().isNull())
+ request.setHTTPReferrer(item->referrer());
+
// If this was a repost that failed the page cache, we might try to repost the form.
NavigationAction action;
if (formData) {
formData->generateFiles(m_frame.document());
request.setHTTPMethod("POST");
- request.setHTTPBody(WTFMove(formData));
- request.setHTTPContentType(item.formContentType());
- RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item.referrer());
+ request.setHTTPBody(formData);
+ request.setHTTPContentType(item->formContentType());
+ RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->referrer());
addHTTPOriginIfNeeded(request, securityOrigin->toString());
// Make sure to add extra fields to the request after the Origin header is added for the FormData case.
@@ -3341,54 +3250,49 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem& item, FrameLoadType loa
if (cacheLoadPolicy == MayAttemptCacheOnlyLoadForFormSubmissionItem) {
request.setCachePolicy(ReturnCacheDataDontLoad);
- action = NavigationAction(request, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy);
+ action = NavigationAction(request, loadType, false);
} else {
request.setCachePolicy(ReturnCacheDataElseLoad);
- action = NavigationAction(request, NavigationType::FormResubmitted, event, shouldOpenExternalURLsPolicy);
+ action = NavigationAction(request, NavigationTypeFormResubmitted);
}
} else {
switch (loadType) {
- case FrameLoadType::Reload:
- case FrameLoadType::ReloadFromOrigin:
- request.setCachePolicy(ReloadIgnoringCacheData);
- break;
- case FrameLoadType::Back:
- case FrameLoadType::Forward:
- case FrameLoadType::IndexedBackForward: {
-#if PLATFORM(IOS)
- bool allowStaleData = true;
-#else
- bool allowStaleData = !item.wasRestoredFromSession();
-#endif
- if (allowStaleData)
- request.setCachePolicy(ReturnCacheDataElseLoad);
- item.setWasRestoredFromSession(false);
- break;
- }
- case FrameLoadType::Standard:
- case FrameLoadType::RedirectWithLockedBackForwardList:
- break;
- case FrameLoadType::Same:
- default:
- ASSERT_NOT_REACHED();
+ case FrameLoadTypeReload:
+ case FrameLoadTypeReloadFromOrigin:
+ request.setCachePolicy(ReloadIgnoringCacheData);
+ break;
+ case FrameLoadTypeBack:
+ case FrameLoadTypeForward:
+ case FrameLoadTypeIndexedBackForward:
+ // If the first load within a frame is a navigation within a back/forward list that was attached
+ // without any of the items being loaded then we should use the default caching policy (<rdar://problem/8131355>).
+ if (m_stateMachine.committedFirstRealDocumentLoad())
+ request.setCachePolicy(ReturnCacheDataElseLoad);
+ break;
+ case FrameLoadTypeStandard:
+ case FrameLoadTypeRedirectWithLockedBackForwardList:
+ break;
+ case FrameLoadTypeSame:
+ default:
+ ASSERT_NOT_REACHED();
}
addExtraFieldsToRequest(request, loadType, true);
ResourceRequest requestForOriginalURL(request);
requestForOriginalURL.setURL(itemOriginalURL);
- action = NavigationAction(requestForOriginalURL, loadType, isFormSubmission, event, shouldOpenExternalURLsPolicy);
+ action = NavigationAction(requestForOriginalURL, loadType, false);
}
- loadWithNavigationAction(request, action, LockHistory::No, loadType, 0, AllowNavigationToInvalidURL::Yes);
+ loadWithNavigationAction(request, action, false, loadType, 0);
}
// Loads content into this frame, as specified by history item
-void FrameLoader::loadItem(HistoryItem& item, FrameLoadType loadType)
+void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType)
{
- m_requestedHistoryItem = &item;
+ m_requestedHistoryItem = item;
HistoryItem* currentItem = history().currentItem();
- bool sameDocumentNavigation = currentItem && item.shouldDoSameDocumentNavigationTo(*currentItem);
+ bool sameDocumentNavigation = currentItem && item->shouldDoSameDocumentNavigationTo(currentItem);
if (sameDocumentNavigation)
loadSameDocumentItem(item);
@@ -3400,12 +3304,13 @@ void FrameLoader::retryAfterFailedCacheOnlyMainResourceLoad()
{
ASSERT(m_state == FrameStateProvisional);
ASSERT(!m_loadingFromCachedPage);
- ASSERT(history().provisionalItem());
+ // We only use cache-only loads to avoid resubmitting forms.
+ ASSERT(isBackForwardLoadType(m_loadType));
ASSERT(history().provisionalItem()->formData());
ASSERT(history().provisionalItem() == m_requestedHistoryItem.get());
FrameLoadType loadType = m_loadType;
- HistoryItem& item = *history().provisionalItem();
+ HistoryItem* item = history().provisionalItem();
stopAllLoaders(ShouldNotClearProvisionalItem);
loadDifferentDocumentItem(item, loadType, MayNotAttemptCacheOnlyLoadForFormSubmissionItem);
@@ -3418,18 +3323,6 @@ ResourceError FrameLoader::cancelledError(const ResourceRequest& request) const
return error;
}
-ResourceError FrameLoader::blockedByContentBlockerError(const ResourceRequest& request) const
-{
- return m_client.blockedByContentBlockerError(request);
-}
-
-ResourceError FrameLoader::blockedError(const ResourceRequest& request) const
-{
- ResourceError error = m_client.blockedError(request);
- error.setIsCancellation(true);
- return error;
-}
-
#if PLATFORM(IOS)
RetainPtr<CFDictionaryRef> FrameLoader::connectionProperties(ResourceLoader* loader)
{
@@ -3449,8 +3342,8 @@ void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
Vector<Ref<DOMWrapperWorld>> worlds;
ScriptController::getAllWorlds(worlds);
- for (auto& world : worlds)
- dispatchDidClearWindowObjectInWorld(world);
+ for (size_t i = 0; i < worlds.size(); ++i)
+ dispatchDidClearWindowObjectInWorld(worlds[i].get());
}
void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
@@ -3460,18 +3353,20 @@ void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
m_client.dispatchDidClearWindowObjectInWorld(world);
+#if ENABLE(INSPECTOR)
if (Page* page = m_frame.page())
- page->inspectorController().didClearWindowObjectInWorld(m_frame, world);
+ page->inspectorController().didClearWindowObjectInWorld(&m_frame, world);
+#endif
- InspectorInstrumentation::didClearWindowObjectInWorld(m_frame, world);
+ InspectorInstrumentation::didClearWindowObjectInWorld(&m_frame, world);
}
void FrameLoader::dispatchGlobalObjectAvailableInAllWorlds()
{
Vector<Ref<DOMWrapperWorld>> worlds;
ScriptController::getAllWorlds(worlds);
- for (auto& world : worlds)
- m_client.dispatchGlobalObjectAvailable(world);
+ for (size_t i = 0; i < worlds.size(); ++i)
+ m_client.dispatchGlobalObjectAvailable(worlds[i].get());
}
SandboxFlags FrameLoader::effectiveSandboxFlags() const
@@ -3503,6 +3398,11 @@ void FrameLoader::didChangeTitle(DocumentLoader* loader)
#endif
}
+void FrameLoader::didChangeIcons(IconType type)
+{
+ m_client.dispatchDidChangeIcons(type);
+}
+
void FrameLoader::dispatchDidCommitLoad()
{
if (m_stateMachine.creatingInitialEmptyDocument())
@@ -3515,12 +3415,14 @@ void FrameLoader::dispatchDidCommitLoad()
m_frame.page()->resetSeenMediaEngines();
}
- InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get());
+ InspectorInstrumentation::didCommitLoad(&m_frame, m_documentLoader.get());
+ if (m_frame.isMainFrame()) {
+ m_frame.page()->featureObserver()->didCommitLoad();
#if ENABLE(REMOTE_INSPECTOR)
- if (m_frame.isMainFrame())
m_frame.page()->remoteInspectorInformationDidChange();
#endif
+ }
}
void FrameLoader::tellClientAboutPastMemoryCacheLoads()
@@ -3534,8 +3436,9 @@ void FrameLoader::tellClientAboutPastMemoryCacheLoads()
Vector<ResourceRequest> pastLoads;
m_documentLoader->takeMemoryCacheLoadsForClientNotification(pastLoads);
- for (auto& pastLoad : pastLoads) {
- CachedResource* resource = MemoryCache::singleton().resourceForRequest(pastLoad, m_frame.page()->sessionID());
+ size_t size = pastLoads.size();
+ for (size_t i = 0; i < size; ++i) {
+ CachedResource* resource = memoryCache()->resourceForRequest(pastLoads[i]);
// FIXME: These loads, loaded from cache, but now gone from the cache by the time
// Page::setMemoryCacheClientCallsEnabled(true) is called, will not be seen by the client.
@@ -3556,8 +3459,12 @@ NetworkingContext* FrameLoader::networkingContext() const
void FrameLoader::loadProgressingStatusChanged()
{
- if (auto* view = m_frame.mainFrame().view())
- view->loadProgressingStatusChanged();
+ FrameView* view = m_frame.mainFrame().view();
+ if (!view)
+ return;
+
+ view->updateLayerFlushThrottlingInAllFrames();
+ view->adjustTiledBackingCoverage();
}
void FrameLoader::forcePageTransitionIfNeeded()
@@ -3565,35 +3472,22 @@ void FrameLoader::forcePageTransitionIfNeeded()
m_client.forcePageTransitionIfNeeded();
}
-void FrameLoader::clearTestingOverrides()
-{
- m_overrideCachePolicyForTesting = Nullopt;
- m_overrideResourceLoadPriorityForTesting = Nullopt;
- m_isStrictRawResourceValidationPolicyDisabledForTesting = false;
-}
-
-void FrameLoader::applyShouldOpenExternalURLsPolicyToNewDocumentLoader(DocumentLoader& documentLoader, ShouldOpenExternalURLsPolicy propagatedPolicy)
-{
- documentLoader.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, propagatedPolicy));
-}
-
bool FrameLoaderClient::hasHTMLView() const
{
return true;
}
-RefPtr<Frame> createWindow(Frame& openerFrame, Frame& lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, bool& created)
+PassRefPtr<Frame> createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, bool& created)
{
ASSERT(!features.dialog || request.frameName().isEmpty());
- created = false;
-
if (!request.frameName().isEmpty() && request.frameName() != "_blank") {
- if (RefPtr<Frame> frame = lookupFrame.loader().findFrameForNavigation(request.frameName(), openerFrame.document())) {
+ if (Frame* frame = lookupFrame->loader().findFrameForNavigation(request.frameName(), openerFrame->document())) {
if (request.frameName() != "_self") {
if (Page* page = frame->page())
page->chrome().focus();
}
+ created = false;
return frame;
}
}
@@ -3601,92 +3495,74 @@ RefPtr<Frame> createWindow(Frame& openerFrame, Frame& lookupFrame, const FrameLo
// Sandboxed frames cannot open new auxiliary browsing contexts.
if (isDocumentSandboxed(openerFrame, SandboxPopups)) {
// FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
- openerFrame.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Blocked opening '" + request.resourceRequest().url().stringCenterEllipsizedToLength() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
- return nullptr;
+ openerFrame->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceRequest().url().stringCenterEllipsizedToLength() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
+ return 0;
}
// FIXME: Setting the referrer should be the caller's responsibility.
FrameLoadRequest requestWithReferrer = request;
- String referrer = SecurityPolicy::generateReferrerHeader(openerFrame.document()->referrerPolicy(), request.resourceRequest().url(), openerFrame.loader().outgoingReferrer());
+ String referrer = SecurityPolicy::generateReferrerHeader(openerFrame->document()->referrerPolicy(), request.resourceRequest().url(), openerFrame->loader().outgoingReferrer());
if (!referrer.isEmpty())
requestWithReferrer.resourceRequest().setHTTPReferrer(referrer);
- FrameLoader::addHTTPOriginIfNeeded(requestWithReferrer.resourceRequest(), openerFrame.loader().outgoingOrigin());
+ FrameLoader::addHTTPOriginIfNeeded(requestWithReferrer.resourceRequest(), openerFrame->loader().outgoingOrigin());
- Page* oldPage = openerFrame.page();
+ Page* oldPage = openerFrame->page();
if (!oldPage)
- return nullptr;
+ return 0;
- ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLsPolicyToApply(openerFrame, request.shouldOpenExternalURLsPolicy());
- Page* page = oldPage->chrome().createWindow(&openerFrame, requestWithReferrer, features, NavigationAction(requestWithReferrer.resourceRequest(), shouldOpenExternalURLsPolicy));
+ NavigationAction action(requestWithReferrer.resourceRequest());
+ Page* page = oldPage->chrome().createWindow(openerFrame, requestWithReferrer, features, action);
if (!page)
- return nullptr;
+ return 0;
- RefPtr<Frame> frame = &page->mainFrame();
-
- frame->loader().forceSandboxFlags(openerFrame.document()->sandboxFlags());
+ page->mainFrame().loader().forceSandboxFlags(openerFrame->document()->sandboxFlags());
if (request.frameName() != "_blank")
- frame->tree().setName(request.frameName());
+ page->mainFrame().tree().setName(request.frameName());
page->chrome().setToolbarsVisible(features.toolBarVisible || features.locationBarVisible);
-
- if (!frame->page())
- return nullptr;
page->chrome().setStatusbarVisible(features.statusBarVisible);
-
- if (!frame->page())
- return nullptr;
page->chrome().setScrollbarsVisible(features.scrollbarsVisible);
-
- if (!frame->page())
- return nullptr;
page->chrome().setMenubarVisible(features.menuBarVisible);
-
- if (!frame->page())
- return nullptr;
page->chrome().setResizable(features.resizable);
// 'x' and 'y' specify the location of the window, while 'width' and 'height'
// specify the size of the viewport. We can only resize the window, so adjust
// for the difference between the window size and the viewport size.
- // FIXME: We should reconcile the initialization of viewport arguments between iOS and non-IOS.
+// FIXME: We should reconcile the initialization of viewport arguments between iOS and OpenSource.
#if !PLATFORM(IOS)
FloatSize viewportSize = page->chrome().pageRect().size();
FloatRect windowRect = page->chrome().windowRect();
- if (features.x)
- windowRect.setX(*features.x);
- if (features.y)
- windowRect.setY(*features.y);
+ if (features.xSet)
+ windowRect.setX(features.x);
+ if (features.ySet)
+ windowRect.setY(features.y);
// Zero width and height mean using default size, not minumum one.
- if (features.width && *features.width)
- windowRect.setWidth(*features.width + (windowRect.width() - viewportSize.width()));
- if (features.height && *features.height)
- windowRect.setHeight(*features.height + (windowRect.height() - viewportSize.height()));
+ if (features.widthSet && features.width)
+ windowRect.setWidth(features.width + (windowRect.width() - viewportSize.width()));
+ if (features.heightSet && features.height)
+ windowRect.setHeight(features.height + (windowRect.height() - viewportSize.height()));
// Ensure non-NaN values, minimum size as well as being within valid screen area.
FloatRect newWindowRect = DOMWindow::adjustWindowRect(page, windowRect);
- if (!frame->page())
- return nullptr;
page->chrome().setWindowRect(newWindowRect);
#else
// On iOS, width and height refer to the viewport dimensions.
ViewportArguments arguments;
// Zero width and height mean using default size, not minimum one.
- if (features.width && *features.width)
- arguments.width = *features.width;
- if (features.height && *features.height)
- arguments.height = *features.height;
- frame->setViewportArguments(arguments);
+ if (features.widthSet && features.width)
+ arguments.width = features.width;
+ if (features.heightSet && features.height)
+ arguments.height = features.height;
+ page->mainFrame().setViewportArguments(arguments);
#endif
- if (!frame->page())
- return nullptr;
page->chrome().show();
created = true;
- return frame;
+ return &page->mainFrame();
}
} // namespace WebCore