Source/WebCore:
[WebKit-https.git] / Source / WebCore / loader / FrameLoader.cpp
1 /*
2  * Copyright (C) 2006-2018 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
5  * Copyright (C) 2008 Alp Toker <alp@atoker.com>
6  * Copyright (C) Research In Motion Limited 2009. All rights reserved.
7  * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com>
8  * Copyright (C) 2011 Google Inc. All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * 1.  Redistributions of source code must retain the above copyright
15  *     notice, this list of conditions and the following disclaimer.
16  * 2.  Redistributions in binary form must reproduce the above copyright
17  *     notice, this list of conditions and the following disclaimer in the
18  *     documentation and/or other materials provided with the distribution.
19  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
20  *     its contributors may be used to endorse or promote products derived
21  *     from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
24  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
27  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include "config.h"
36 #include "FrameLoader.h"
37
38 #include "AXObjectCache.h"
39 #include "ApplicationCacheHost.h"
40 #include "BackForwardCache.h"
41 #include "BackForwardController.h"
42 #include "BeforeUnloadEvent.h"
43 #include "CachedPage.h"
44 #include "CachedResourceLoader.h"
45 #include "Chrome.h"
46 #include "ChromeClient.h"
47 #include "CommonVM.h"
48 #include "ContentFilter.h"
49 #include "ContentRuleListResults.h"
50 #include "ContentSecurityPolicy.h"
51 #include "CustomHeaderFields.h"
52 #include "DOMWindow.h"
53 #include "DatabaseManager.h"
54 #include "DiagnosticLoggingClient.h"
55 #include "DiagnosticLoggingKeys.h"
56 #include "Document.h"
57 #include "DocumentLoader.h"
58 #include "Editor.h"
59 #include "EditorClient.h"
60 #include "Element.h"
61 #include "Event.h"
62 #include "EventHandler.h"
63 #include "EventNames.h"
64 #include "FloatRect.h"
65 #include "FormState.h"
66 #include "FormSubmission.h"
67 #include "Frame.h"
68 #include "FrameLoadRequest.h"
69 #include "FrameLoaderClient.h"
70 #include "FrameNetworkingContext.h"
71 #include "FrameTree.h"
72 #include "FrameView.h"
73 #include "GCController.h"
74 #include "HTMLFormElement.h"
75 #include "HTMLInputElement.h"
76 #include "HTMLNames.h"
77 #include "HTMLObjectElement.h"
78 #include "HTMLParserIdioms.h"
79 #include "HTTPHeaderNames.h"
80 #include "HTTPHeaderValues.h"
81 #include "HTTPParsers.h"
82 #include "HistoryController.h"
83 #include "HistoryItem.h"
84 #include "IgnoreOpensDuringUnloadCountIncrementer.h"
85 #include "InspectorController.h"
86 #include "InspectorInstrumentation.h"
87 #include "LinkLoader.h"
88 #include "LoadTiming.h"
89 #include "LoaderStrategy.h"
90 #include "Logging.h"
91 #include "MemoryCache.h"
92 #include "MemoryRelease.h"
93 #include "NavigationDisabler.h"
94 #include "NavigationScheduler.h"
95 #include "Node.h"
96 #include "Page.h"
97 #include "PageTransitionEvent.h"
98 #include "PerformanceLogging.h"
99 #include "PlatformStrategies.h"
100 #include "PluginData.h"
101 #include "PluginDocument.h"
102 #include "PolicyChecker.h"
103 #include "ProgressTracker.h"
104 #include "ResourceHandle.h"
105 #include "ResourceLoadInfo.h"
106 #include "ResourceLoadObserver.h"
107 #include "ResourceRequest.h"
108 #include "SVGDocument.h"
109 #include "SVGLocatable.h"
110 #include "SVGNames.h"
111 #include "SVGViewElement.h"
112 #include "SVGViewSpec.h"
113 #include "ScriptController.h"
114 #include "ScriptSourceCode.h"
115 #include "ScrollAnimator.h"
116 #include "SecurityOrigin.h"
117 #include "SecurityPolicy.h"
118 #include "SegmentedString.h"
119 #include "SerializedScriptValue.h"
120 #include "Settings.h"
121 #include "ShouldTreatAsContinuingLoad.h"
122 #include "StyleTreeResolver.h"
123 #include "SubframeLoader.h"
124 #include "SubresourceLoader.h"
125 #include "TextResourceDecoder.h"
126 #include "UserContentController.h"
127 #include "UserGestureIndicator.h"
128 #include "WindowFeatures.h"
129 #include "XMLDocumentParser.h"
130 #include <dom/ScriptDisallowedScope.h>
131 #include <wtf/CompletionHandler.h>
132 #include <wtf/URL.h>
133 #include <wtf/Ref.h>
134 #include <wtf/SetForScope.h>
135 #include <wtf/StdLibExtras.h>
136 #include <wtf/SystemTracing.h>
137 #include <wtf/text/CString.h>
138 #include <wtf/text/WTFString.h>
139
140 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
141 #include "Archive.h"
142 #endif
143
144 #if ENABLE(DATA_DETECTION)
145 #include "DataDetection.h"
146 #endif
147
148 #if PLATFORM(IOS_FAMILY)
149 #include "DocumentType.h"
150 #include "ResourceLoader.h"
151 #include "RuntimeApplicationChecks.h"
152 #endif
153
154 #define PAGE_ID ((pageID().valueOr(PageIdentifier())).toUInt64())
155 #define FRAME_ID ((frameID().valueOr(FrameIdentifier())).toUInt64())
156 #define FRAMELOADER_RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [pageID=%" PRIu64 ", frameID=%" PRIu64 ", main=%d] FrameLoader::" fmt, this, PAGE_ID, FRAME_ID, m_frame.isMainFrame(), ##__VA_ARGS__)
157 #define FRAMELOADER_RELEASE_LOG_ERROR_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [pageID=%" PRIu64 ", frameID=%" PRIu64 ", main=%d] FrameLoader::" fmt, this, PAGE_ID, FRAME_ID, m_frame.isMainFrame(), ##__VA_ARGS__)
158
159 namespace WebCore {
160
161 using namespace HTMLNames;
162 using namespace SVGNames;
163
164 bool isBackForwardLoadType(FrameLoadType type)
165 {
166     switch (type) {
167     case FrameLoadType::Standard:
168     case FrameLoadType::Reload:
169     case FrameLoadType::ReloadFromOrigin:
170     case FrameLoadType::ReloadExpiredOnly:
171     case FrameLoadType::Same:
172     case FrameLoadType::RedirectWithLockedBackForwardList:
173     case FrameLoadType::Replace:
174         return false;
175     case FrameLoadType::Back:
176     case FrameLoadType::Forward:
177     case FrameLoadType::IndexedBackForward:
178         return true;
179     }
180     ASSERT_NOT_REACHED();
181     return false;
182 }
183
184 bool isReload(FrameLoadType type)
185 {
186     switch (type) {
187     case FrameLoadType::Reload:
188     case FrameLoadType::ReloadFromOrigin:
189     case FrameLoadType::ReloadExpiredOnly:
190         return true;
191     case FrameLoadType::Standard:
192     case FrameLoadType::Same:
193     case FrameLoadType::RedirectWithLockedBackForwardList:
194     case FrameLoadType::Replace:
195     case FrameLoadType::Back:
196     case FrameLoadType::Forward:
197     case FrameLoadType::IndexedBackForward:
198         return false;
199     }
200     ASSERT_NOT_REACHED();
201     return false;
202 }
203
204 // This is not in the FrameLoader class to emphasize that it does not depend on
205 // private FrameLoader data, and to avoid increasing the number of public functions
206 // with access to private data.  Since only this .cpp file needs it, making it
207 // non-member lets us exclude it from the header file, thus keeping FrameLoader.h's
208 // API simpler.
209 //
210 static bool isDocumentSandboxed(Frame& frame, SandboxFlags mask)
211 {
212     return frame.document() && frame.document()->isSandboxed(mask);
213 }
214
215 class PageLevelForbidScope {
216 protected:
217     explicit PageLevelForbidScope(Page* page)
218         : m_page(makeWeakPtr(page))
219     {
220     }
221
222     ~PageLevelForbidScope() = default;
223
224     WeakPtr<Page> m_page;
225 };
226
227 struct ForbidPromptsScope : public PageLevelForbidScope {
228     explicit ForbidPromptsScope(Page* page)
229         : PageLevelForbidScope(page)
230     {
231         if (m_page)
232             m_page->forbidPrompts();
233     }
234
235     ~ForbidPromptsScope()
236     {
237         if (m_page)
238             m_page->allowPrompts();
239     }
240 };
241
242 struct ForbidSynchronousLoadsScope : public PageLevelForbidScope {
243     explicit ForbidSynchronousLoadsScope(Page* page)
244         : PageLevelForbidScope(page)
245     {
246         if (m_page)
247             m_page->forbidSynchronousLoads();
248     }
249
250     ~ForbidSynchronousLoadsScope()
251     {
252         if (m_page)
253             m_page->allowSynchronousLoads();
254     }
255 };
256
257 class FrameLoader::FrameProgressTracker {
258     WTF_MAKE_FAST_ALLOCATED;
259 public:
260     explicit FrameProgressTracker(Frame& frame)
261         : m_frame(frame)
262         , m_inProgress(false)
263     {
264     }
265
266     ~FrameProgressTracker()
267     {
268         if (m_inProgress && m_frame.page())
269             m_frame.page()->progress().progressCompleted(m_frame);
270     }
271
272     void progressStarted()
273     {
274         ASSERT(m_frame.page());
275         if (!m_inProgress)
276             m_frame.page()->progress().progressStarted(m_frame);
277         m_inProgress = true;
278     }
279
280     void progressCompleted()
281     {
282         ASSERT(m_inProgress);
283         ASSERT(m_frame.page());
284         m_inProgress = false;
285         m_frame.page()->progress().progressCompleted(m_frame);
286         platformStrategies()->loaderStrategy()->pageLoadCompleted(*m_frame.page());
287     }
288
289 private:
290     Frame& m_frame;
291     bool m_inProgress;
292 };
293
294 FrameLoader::FrameLoader(Frame& frame, UniqueRef<FrameLoaderClient>&& client)
295     : m_frame(frame)
296     , m_client(WTFMove(client))
297     , m_policyChecker(makeUnique<PolicyChecker>(frame))
298     , m_history(makeUnique<HistoryController>(frame))
299     , m_notifier(frame)
300     , m_subframeLoader(makeUnique<SubframeLoader>(frame))
301     , m_mixedContentChecker(frame)
302     , m_state(FrameStateProvisional)
303     , m_loadType(FrameLoadType::Standard)
304     , m_quickRedirectComing(false)
305     , m_sentRedirectNotification(false)
306     , m_inStopAllLoaders(false)
307     , m_isExecutingJavaScriptFormAction(false)
308     , m_didCallImplicitClose(true)
309     , m_wasUnloadEventEmitted(false)
310     , m_isComplete(false)
311     , m_needsClear(false)
312     , m_checkTimer(*this, &FrameLoader::checkTimerFired)
313     , m_shouldCallCheckCompleted(false)
314     , m_shouldCallCheckLoadComplete(false)
315     , m_opener(nullptr)
316     , m_loadingFromCachedPage(false)
317     , m_currentNavigationHasShownBeforeUnloadConfirmPanel(false)
318     , m_loadsSynchronously(false)
319     , m_forcedSandboxFlags(SandboxNone)
320 {
321 }
322
323 FrameLoader::~FrameLoader()
324 {
325     setOpener(nullptr);
326     detachFromAllOpenedFrames();
327
328     if (m_networkingContext)
329         m_networkingContext->invalidate();
330 }
331
332 void FrameLoader::detachFromAllOpenedFrames()
333 {
334     for (auto& frame : m_openedFrames)
335         frame->loader().m_opener = nullptr;
336     m_openedFrames.clear();
337 }
338
339 void FrameLoader::init()
340 {
341     // This somewhat odd set of steps gives the frame an initial empty document.
342     setPolicyDocumentLoader(m_client->createDocumentLoader(ResourceRequest(URL({ }, emptyString())), SubstituteData()).ptr());
343     setProvisionalDocumentLoader(m_policyDocumentLoader.get());
344     m_provisionalDocumentLoader->startLoadingMainResource();
345
346     Ref<Frame> protect(m_frame);
347     m_frame.document()->cancelParsing();
348     m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument);
349
350     m_networkingContext = m_client->createNetworkingContext();
351     m_progressTracker = makeUnique<FrameProgressTracker>(m_frame);
352 }
353
354 void FrameLoader::initForSynthesizedDocument(const URL&)
355 {
356     // FIXME: We need to initialize the document URL to the specified URL. Currently the URL is empty and hence
357     // FrameLoader::checkCompleted() will overwrite the URL of the document to be activeDocumentLoader()->documentURL().
358
359     auto loader = m_client->createDocumentLoader(ResourceRequest(URL({ }, emptyString())), SubstituteData());
360     loader->attachToFrame(m_frame);
361     loader->setResponse(ResourceResponse(URL(), "text/html"_s, 0, String()));
362     loader->setCommitted(true);
363     setDocumentLoader(loader.ptr());
364
365     m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument);
366     m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
367     m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
368     m_client->transitionToCommittedForNewPage();
369
370     m_didCallImplicitClose = true;
371     m_isComplete = true;
372     m_state = FrameStateComplete;
373     m_needsClear = true;
374
375     m_networkingContext = m_client->createNetworkingContext();
376     m_progressTracker = makeUnique<FrameProgressTracker>(m_frame);
377 }
378
379 Optional<PageIdentifier> FrameLoader::pageID() const
380 {
381     return client().pageID();
382 }
383
384 Optional<FrameIdentifier> FrameLoader::frameID() const
385 {
386     return client().frameID();
387 }
388
389 void FrameLoader::setDefersLoading(bool defers)
390 {
391     if (m_documentLoader)
392         m_documentLoader->setDefersLoading(defers);
393     if (m_provisionalDocumentLoader)
394         m_provisionalDocumentLoader->setDefersLoading(defers);
395     if (m_policyDocumentLoader)
396         m_policyDocumentLoader->setDefersLoading(defers);
397     history().setDefersLoading(defers);
398
399     if (!defers) {
400         m_frame.navigationScheduler().startTimer();
401         startCheckCompleteTimer();
402     }
403 }
404
405 void FrameLoader::checkContentPolicy(const ResourceResponse& response, PolicyCheckIdentifier identifier, ContentPolicyDecisionFunction&& function)
406 {
407     if (!activeDocumentLoader()) {
408         // Load was cancelled
409         function(PolicyAction::Ignore, identifier);
410         return;
411     }
412
413     // FIXME: Validate the policy check identifier.
414     client().dispatchDecidePolicyForResponse(response, activeDocumentLoader()->request(), identifier, activeDocumentLoader()->downloadAttribute(), WTFMove(function));
415 }
416
417 void FrameLoader::changeLocation(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, const ReferrerPolicy& referrerPolicy, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, Optional<NewFrameOpenerPolicy> openerPolicy, const AtomString& downloadAttribute, const SystemPreviewInfo& systemPreviewInfo, Optional<AdClickAttribution>&& adClickAttribution)
418 {
419     auto* frame = lexicalFrameFromCommonVM();
420     auto initiatedByMainFrame = frame && frame->isMainFrame() ? InitiatedByMainFrame::Yes : InitiatedByMainFrame::Unknown;
421
422     NewFrameOpenerPolicy newFrameOpenerPolicy = openerPolicy.valueOr(referrerPolicy == ReferrerPolicy::NoReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow);
423     changeLocation(FrameLoadRequest(*m_frame.document(), m_frame.document()->securityOrigin(), { url }, passedTarget, lockHistory, lockBackForwardList, referrerPolicy, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, shouldOpenExternalURLsPolicy, initiatedByMainFrame, DoNotReplaceDocumentIfJavaScriptURL, downloadAttribute, systemPreviewInfo), triggeringEvent, WTFMove(adClickAttribution));
424 }
425
426 void FrameLoader::changeLocation(FrameLoadRequest&& frameRequest, Event* triggeringEvent, Optional<AdClickAttribution>&& adClickAttribution)
427 {
428     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "changeLocation: frame load started");
429
430     Ref<Frame> protect(m_frame);
431
432     if (m_frame.script().executeIfJavaScriptURL(frameRequest.resourceRequest().url(), &frameRequest.requester().securityOrigin(), frameRequest.shouldReplaceDocumentIfJavaScriptURL())) {
433         m_quickRedirectComing = false;
434         return;
435     }
436
437     if (frameRequest.frameName().isEmpty())
438         frameRequest.setFrameName(m_frame.document()->baseTarget());
439
440     addHTTPOriginIfNeeded(frameRequest.resourceRequest(), outgoingOrigin());
441     m_frame.document()->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(frameRequest.resourceRequest(), ContentSecurityPolicy::InsecureRequestType::Navigation);
442
443     loadFrameRequest(WTFMove(frameRequest), triggeringEvent, { }, WTFMove(adClickAttribution));
444 }
445
446 void FrameLoader::submitForm(Ref<FormSubmission>&& submission)
447 {
448     ASSERT(submission->method() == FormSubmission::Method::Post || submission->method() == FormSubmission::Method::Get);
449
450     // FIXME: Find a good spot for these.
451     ASSERT(!submission->state().sourceDocument().frame() || submission->state().sourceDocument().frame() == &m_frame);
452
453     if (!m_frame.page())
454         return;
455
456     if (submission->action().isEmpty())
457         return;
458
459     if (isDocumentSandboxed(m_frame, SandboxForms)) {
460         // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
461         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.");
462         return;
463     }
464
465     if (WTF::protocolIsJavaScript(submission->action())) {
466         if (!m_frame.document()->contentSecurityPolicy()->allowFormAction(URL(submission->action())))
467             return;
468         m_isExecutingJavaScriptFormAction = true;
469         Ref<Frame> protect(m_frame);
470         m_frame.script().executeIfJavaScriptURL(submission->action(), nullptr, DoNotReplaceDocumentIfJavaScriptURL);
471         m_isExecutingJavaScriptFormAction = false;
472         return;
473     }
474
475     Frame* targetFrame = findFrameForNavigation(submission->target(), &submission->state().sourceDocument());
476     if (!targetFrame) {
477         if (!DOMWindow::allowPopUp(m_frame) && !UserGestureIndicator::processingUserGesture())
478             return;
479
480         // FIXME: targetFrame can be null for two distinct reasons:
481         // 1. The frame was not found by name, so we should try opening a new window.
482         // 2. The frame was found, but navigating it was not allowed, e.g. by HTML5 sandbox or by origin checks.
483         // Continuing form submission makes no sense in the latter case.
484         // There is a repeat check after timer fires, so this is not a correctness issue.
485
486         targetFrame = &m_frame;
487     } else
488         submission->clearTarget();
489
490     if (!targetFrame->page())
491         return;
492
493     if (m_frame.tree().isDescendantOf(targetFrame))
494         m_submittedFormURL = submission->requestURL();
495
496     submission->setReferrer(outgoingReferrer());
497     submission->setOrigin(SecurityPolicy::generateOriginHeader(m_frame.document()->referrerPolicy(), submission->requestURL(), m_frame.document()->securityOrigin()));
498
499     targetFrame->navigationScheduler().scheduleFormSubmission(WTFMove(submission));
500 }
501
502 void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy)
503 {
504     if (m_frame.document() && m_frame.document()->parser())
505         m_frame.document()->parser()->stopParsing();
506
507     if (unloadEventPolicy != UnloadEventPolicyNone)
508         dispatchUnloadEvents(unloadEventPolicy);
509
510     m_isComplete = true; // to avoid calling completed() in finishedParsing()
511     m_didCallImplicitClose = true; // don't want that one either
512
513     if (m_frame.document() && m_frame.document()->parsing()) {
514         finishedParsing();
515         m_frame.document()->setParsing(false);
516     }
517
518     if (auto* document = m_frame.document()) {
519         // FIXME: Should the DatabaseManager watch for something like ActiveDOMObject::stop() rather than being special-cased here?
520         DatabaseManager::singleton().stopDatabases(*document, nullptr);
521     }
522
523     policyChecker().stopCheck();
524
525     // FIXME: This will cancel redirection timer, which really needs to be restarted when restoring the frame from b/f cache.
526     m_frame.navigationScheduler().cancel();
527 }
528
529 void FrameLoader::stop()
530 {
531     // http://bugs.webkit.org/show_bug.cgi?id=10854
532     // The frame's last ref may be removed and it will be deleted by checkCompleted().
533     Ref<Frame> protect(m_frame);
534
535     if (DocumentParser* parser = m_frame.document()->parser()) {
536         parser->stopParsing();
537         parser->finish();
538     }
539 }
540
541 void FrameLoader::willTransitionToCommitted()
542 {
543     // This function is called when a frame is still fully in place (not cached, not detached), but will be replaced.
544
545     if (m_frame.editor().hasComposition()) {
546         // The text was already present in DOM, so it's better to confirm than to cancel the composition.
547         m_frame.editor().confirmComposition();
548         if (EditorClient* editorClient = m_frame.editor().client()) {
549             editorClient->respondToChangedSelection(&m_frame);
550             editorClient->discardedComposition(&m_frame);
551         }
552     }
553 }
554
555 bool FrameLoader::closeURL()
556 {
557     history().saveDocumentState();
558
559     Document* currentDocument = m_frame.document();
560     UnloadEventPolicy unloadEventPolicy;
561     if (m_frame.page() && m_frame.page()->chrome().client().isSVGImageChromeClient()) {
562         // If this is the SVGDocument of an SVGImage, no need to dispatch events or recalcStyle.
563         unloadEventPolicy = UnloadEventPolicyNone;
564     } else {
565         // Should only send the pagehide event here if the current document exists and has not been placed in the back/forward cache.
566         unloadEventPolicy = currentDocument && currentDocument->backForwardCacheState() == Document::NotInBackForwardCache ? UnloadEventPolicyUnloadAndPageHide : UnloadEventPolicyUnloadOnly;
567     }
568
569     stopLoading(unloadEventPolicy);
570     
571     m_frame.editor().clearUndoRedoOperations();
572     return true;
573 }
574
575 bool FrameLoader::didOpenURL()
576 {
577     if (m_frame.navigationScheduler().redirectScheduledDuringLoad()) {
578         // A redirect was scheduled before the document was created.
579         // This can happen when one frame changes another frame's location.
580         return false;
581     }
582
583     m_frame.navigationScheduler().cancel();
584     m_frame.editor().clearLastEditCommand();
585
586     m_isComplete = false;
587     m_didCallImplicitClose = false;
588
589     // If we are still in the process of initializing an empty document then
590     // its frame is not in a consistent state for rendering, so avoid setJSStatusBarText
591     // since it may cause clients to attempt to render the frame.
592     if (!m_stateMachine.creatingInitialEmptyDocument()) {
593         DOMWindow* window = m_frame.document()->domWindow();
594         window->setStatus(String());
595         window->setDefaultStatus(String());
596     }
597
598     started();
599
600     return true;
601 }
602
603 void FrameLoader::didExplicitOpen()
604 {
605     m_isComplete = false;
606     m_didCallImplicitClose = false;
607
608     // Calling document.open counts as committing the first real document load.
609     if (!m_stateMachine.committedFirstRealDocumentLoad())
610         m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
611
612     if (auto* document = m_frame.document())
613         m_client->dispatchDidExplicitOpen(document->url(), document->contentType());
614     
615     // Prevent window.open(url) -- eg window.open("about:blank") -- from blowing away results
616     // from a subsequent window.document.open / window.document.write call. 
617     // Canceling redirection here works for all cases because document.open 
618     // implicitly precedes document.write.
619     m_frame.navigationScheduler().cancel();
620 }
621
622
623 void FrameLoader::cancelAndClear()
624 {
625     m_frame.navigationScheduler().cancel();
626
627     if (!m_isComplete)
628         closeURL();
629
630     clear(m_frame.document(), false);
631     m_frame.script().updatePlatformScriptObjects();
632 }
633
634 static inline bool shouldClearWindowName(const Frame& frame, const Document& newDocument)
635 {
636     if (!frame.isMainFrame())
637         return false;
638
639     if (frame.loader().opener())
640         return false;
641
642     return !newDocument.securityOrigin().isSameOriginAs(frame.document()->securityOrigin());
643 }
644
645 void FrameLoader::clear(Document* newDocument, bool clearWindowProperties, bool clearScriptObjects, bool clearFrameView, WTF::Function<void()>&& handleDOMWindowCreation)
646 {
647     m_frame.editor().clear();
648
649     bool neededClear = m_needsClear;
650     m_needsClear = false;
651
652     if (neededClear && m_frame.document()->backForwardCacheState() != Document::InBackForwardCache) {
653         m_frame.document()->cancelParsing();
654         m_frame.document()->stopActiveDOMObjects();
655         bool hadLivingRenderTree = m_frame.document()->hasLivingRenderTree();
656         m_frame.document()->prepareForDestruction();
657         if (hadLivingRenderTree)
658             m_frame.document()->adjustFocusedNodeOnNodeRemoval(*m_frame.document());
659     }
660
661     if (handleDOMWindowCreation)
662         handleDOMWindowCreation();
663
664     if (!neededClear)
665         return;
666     
667     // Do this after detaching the document so that the unload event works.
668     if (clearWindowProperties) {
669         InspectorInstrumentation::frameWindowDiscarded(m_frame, m_frame.document()->domWindow());
670         m_frame.document()->domWindow()->resetUnlessSuspendedForDocumentSuspension();
671         m_frame.windowProxy().clearJSWindowProxiesNotMatchingDOMWindow(newDocument->domWindow(), m_frame.document()->backForwardCacheState() == Document::AboutToEnterBackForwardCache);
672
673         if (shouldClearWindowName(m_frame, *newDocument))
674             m_frame.tree().setName(nullAtom());
675     }
676
677     m_frame.selection().prepareForDestruction();
678     m_frame.eventHandler().clear();
679
680     if (clearFrameView && m_frame.view())
681         m_frame.view()->clear();
682
683     // Do not drop the document before the ScriptController and view are cleared
684     // as some destructors might still try to access the document.
685     m_frame.setDocument(nullptr);
686
687     subframeLoader().clear();
688
689     if (clearWindowProperties)
690         m_frame.windowProxy().setDOMWindow(newDocument->domWindow());
691
692     if (clearScriptObjects)
693         m_frame.script().clearScriptObjects();
694
695     m_frame.script().enableEval();
696
697     m_frame.navigationScheduler().clear();
698
699     m_checkTimer.stop();
700     m_shouldCallCheckCompleted = false;
701     m_shouldCallCheckLoadComplete = false;
702
703     if (m_stateMachine.isDisplayingInitialEmptyDocument() && m_stateMachine.committedFirstRealDocumentLoad())
704         m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
705 }
706
707 void FrameLoader::receivedFirstData()
708 {
709     dispatchDidCommitLoad(WTF::nullopt, WTF::nullopt);
710     dispatchDidClearWindowObjectsInAllWorlds();
711     dispatchGlobalObjectAvailableInAllWorlds();
712
713     if (!m_documentLoader)
714         return;
715
716     auto& documentLoader = *m_documentLoader;
717     auto& title = documentLoader.title();
718     if (!title.string.isNull())
719         m_client->dispatchDidReceiveTitle(title);
720
721     ASSERT(m_frame.document());
722     auto& document = *m_frame.document();
723
724     LinkLoader::loadLinksFromHeader(documentLoader.response().httpHeaderField(HTTPHeaderName::Link), document.url(), document, LinkLoader::MediaAttributeCheck::MediaAttributeEmpty);
725
726     double delay;
727     String urlString;
728     if (!parseMetaHTTPEquivRefresh(documentLoader.response().httpHeaderField(HTTPHeaderName::Refresh), delay, urlString))
729         return;
730     auto completedURL = urlString.isEmpty() ? document.url() : document.completeURL(urlString);
731     if (!WTF::protocolIsJavaScript(completedURL))
732         m_frame.navigationScheduler().scheduleRedirect(document, delay, completedURL);
733     else {
734         auto message = "Refused to refresh " + document.url().stringCenterEllipsizedToLength() + " to a javascript: URL";
735         document.addConsoleMessage(MessageSource::Security, MessageLevel::Error, message);
736     }
737 }
738
739 void FrameLoader::setOutgoingReferrer(const URL& url)
740 {
741     m_outgoingReferrer = url.strippedForUseAsReferrer();
742 }
743
744 void FrameLoader::didBeginDocument(bool dispatch)
745 {
746     m_needsClear = true;
747     m_isComplete = false;
748     m_didCallImplicitClose = false;
749     m_frame.document()->setReadyState(Document::Loading);
750
751     if (m_pendingStateObject) {
752         m_frame.document()->statePopped(*m_pendingStateObject);
753         m_pendingStateObject = nullptr;
754     }
755
756     if (dispatch)
757         dispatchDidClearWindowObjectsInAllWorlds();
758
759     updateFirstPartyForCookies();
760     m_frame.document()->initContentSecurityPolicy();
761
762     const Settings& settings = m_frame.settings();
763     m_frame.document()->cachedResourceLoader().setImagesEnabled(settings.areImagesEnabled());
764     m_frame.document()->cachedResourceLoader().setAutoLoadImages(settings.loadsImagesAutomatically());
765
766     if (m_documentLoader) {
767         String dnsPrefetchControl = m_documentLoader->response().httpHeaderField(HTTPHeaderName::XDNSPrefetchControl);
768         if (!dnsPrefetchControl.isEmpty())
769             m_frame.document()->parseDNSPrefetchControlHeader(dnsPrefetchControl);
770
771         m_frame.document()->contentSecurityPolicy()->didReceiveHeaders(ContentSecurityPolicyResponseHeaders(m_documentLoader->response()), referrer(), ContentSecurityPolicy::ReportParsingErrors::No);
772
773         String referrerPolicy = m_documentLoader->response().httpHeaderField(HTTPHeaderName::ReferrerPolicy);
774         if (!referrerPolicy.isNull())
775             m_frame.document()->processReferrerPolicy(referrerPolicy, ReferrerPolicySource::HTTPHeader);
776
777         String headerContentLanguage = m_documentLoader->response().httpHeaderField(HTTPHeaderName::ContentLanguage);
778         if (!headerContentLanguage.isEmpty()) {
779             size_t commaIndex = headerContentLanguage.find(',');
780             headerContentLanguage.truncate(commaIndex); // notFound == -1 == don't truncate
781             headerContentLanguage = stripLeadingAndTrailingHTMLSpaces(headerContentLanguage);
782             if (!headerContentLanguage.isEmpty())
783                 m_frame.document()->setContentLanguage(headerContentLanguage);
784         }
785     }
786
787     history().restoreDocumentState();
788 }
789
790 void FrameLoader::finishedParsing()
791 {
792     LOG(Loading, "WebCoreLoading %s: Finished parsing", m_frame.tree().uniqueName().string().utf8().data());
793
794     m_frame.injectUserScripts(InjectAtDocumentEnd);
795
796     if (m_stateMachine.creatingInitialEmptyDocument())
797         return;
798
799     // This can be called from the Frame's destructor, in which case we shouldn't protect ourselves
800     // because doing so will cause us to re-enter the destructor when protector goes out of scope.
801     // Null-checking the FrameView indicates whether or not we're in the destructor.
802     RefPtr<Frame> protector = m_frame.view() ? &m_frame : 0;
803
804     m_client->dispatchDidFinishDocumentLoad();
805
806     scrollToFragmentWithParentBoundary(m_frame.document()->url());
807
808     checkCompleted();
809
810     if (!m_frame.view())
811         return; // We are being destroyed by something checkCompleted called.
812
813     // Check if the scrollbars are really needed for the content.
814     // If not, remove them, relayout, and repaint.
815     m_frame.view()->restoreScrollbar();
816 }
817
818 void FrameLoader::loadDone(LoadCompletionType type)
819 {
820     if (type == LoadCompletionType::Finish)
821         checkCompleted();
822     else
823         scheduleCheckCompleted();
824 }
825
826 void FrameLoader::subresourceLoadDone(LoadCompletionType type)
827 {
828     if (type == LoadCompletionType::Finish)
829         checkLoadComplete();
830     else
831         scheduleCheckLoadComplete();
832 }
833
834 bool FrameLoader::allChildrenAreComplete() const
835 {
836     for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling()) {
837         if (!child->loader().m_isComplete)
838             return false;
839     }
840     return true;
841 }
842
843 bool FrameLoader::allAncestorsAreComplete() const
844 {
845     for (Frame* ancestor = &m_frame; ancestor; ancestor = ancestor->tree().parent()) {
846         if (!ancestor->loader().m_isComplete)
847             return false;
848     }
849     return true;
850 }
851
852 void FrameLoader::checkCompleted()
853 {
854     RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isScriptAllowed());
855     m_shouldCallCheckCompleted = false;
856
857     // Have we completed before?
858     if (m_isComplete)
859         return;
860
861     // FIXME: It would be better if resource loads were kicked off after render tree update (or didn't complete synchronously).
862     //        https://bugs.webkit.org/show_bug.cgi?id=171729
863     if (m_frame.document()->inRenderTreeUpdate()) {
864         scheduleCheckCompleted();
865         return;
866     }
867
868     // Are we still parsing?
869     if (m_frame.document()->parsing())
870         return;
871
872     // Still waiting for images/scripts?
873     if (m_frame.document()->cachedResourceLoader().requestCount())
874         return;
875
876     // Still waiting for elements that don't go through a FrameLoader?
877     if (m_frame.document()->isDelayingLoadEvent())
878         return;
879
880     auto* scriptableParser = m_frame.document()->scriptableDocumentParser();
881     if (scriptableParser && scriptableParser->hasScriptsWaitingForStylesheets())
882         return;
883
884     // Any frame that hasn't completed yet?
885     if (!allChildrenAreComplete())
886         return;
887
888     // Important not to protect earlier in this function, because earlier parts
889     // of this function can be called in the frame's destructor, and it's not legal
890     // to ref an object while it's being destroyed.
891     Ref<Frame> protect(m_frame);
892
893     // OK, completed.
894     m_isComplete = true;
895     m_requestedHistoryItem = nullptr;
896     m_frame.document()->setReadyState(Document::Complete);
897
898     checkCallImplicitClose(); // if we didn't do it before
899
900     m_frame.navigationScheduler().startTimer();
901
902     completed();
903     if (m_frame.page())
904         checkLoadComplete();
905 }
906
907 void FrameLoader::checkTimerFired()
908 {
909     checkCompletenessNow();
910 }
911
912 void FrameLoader::checkCompletenessNow()
913 {
914     Ref<Frame> protect(m_frame);
915
916     if (Page* page = m_frame.page()) {
917         if (page->defersLoading())
918             return;
919     }
920     if (m_shouldCallCheckCompleted)
921         checkCompleted();
922     if (m_shouldCallCheckLoadComplete)
923         checkLoadComplete();
924 }
925
926 void FrameLoader::startCheckCompleteTimer()
927 {
928     if (!(m_shouldCallCheckCompleted || m_shouldCallCheckLoadComplete))
929         return;
930     if (m_checkTimer.isActive())
931         return;
932     m_checkTimer.startOneShot(0_s);
933 }
934
935 void FrameLoader::scheduleCheckCompleted()
936 {
937     m_shouldCallCheckCompleted = true;
938     startCheckCompleteTimer();
939 }
940
941 void FrameLoader::scheduleCheckLoadComplete()
942 {
943     m_shouldCallCheckLoadComplete = true;
944     startCheckCompleteTimer();
945 }
946
947 void FrameLoader::checkCallImplicitClose()
948 {
949     if (m_didCallImplicitClose || m_frame.document()->parsing() || m_frame.document()->isDelayingLoadEvent())
950         return;
951
952     if (!allChildrenAreComplete())
953         return; // still got a frame running -> too early
954
955     m_didCallImplicitClose = true;
956     m_wasUnloadEventEmitted = false;
957     m_frame.document()->implicitClose();
958 }
959
960 void FrameLoader::loadURLIntoChildFrame(const URL& url, const String& referer, Frame* childFrame)
961 {
962     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadURLIntoChildFrame: frame load started");
963
964     ASSERT(childFrame);
965
966 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
967     if (auto activeLoader = activeDocumentLoader()) {
968         if (auto subframeArchive = activeLoader->popArchiveForSubframe(childFrame->tree().uniqueName(), url)) {
969             childFrame->loader().loadArchive(RefPtr<Archive> { subframeArchive }.releaseNonNull());
970             return;
971         }
972     }
973 #endif
974
975     // If we're moving in the back/forward list, we might want to replace the content
976     // of this child frame with whatever was there at that point.
977     auto* parentItem = history().currentItem();
978     if (parentItem && parentItem->children().size() && isBackForwardLoadType(loadType()) && !m_frame.document()->loadEventFinished()) {
979         if (auto* childItem = parentItem->childItemWithTarget(childFrame->tree().uniqueName())) {
980             childFrame->loader().m_requestedHistoryItem = childItem;
981             childFrame->loader().loadDifferentDocumentItem(*childItem, nullptr, loadType(), MayAttemptCacheOnlyLoadForFormSubmissionItem, ShouldTreatAsContinuingLoad::No);
982             return;
983         }
984     }
985
986     auto* lexicalFrame = lexicalFrameFromCommonVM();
987     auto initiatedByMainFrame = lexicalFrame && lexicalFrame->isMainFrame() ? InitiatedByMainFrame::Yes : InitiatedByMainFrame::Unknown;
988
989     FrameLoadRequest frameLoadRequest { *m_frame.document(), m_frame.document()->securityOrigin(), { url }, "_self"_s, LockHistory::No, LockBackForwardList::Yes, ReferrerPolicy::EmptyString, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ShouldOpenExternalURLsPolicy::ShouldNotAllow, initiatedByMainFrame };
990     childFrame->loader().loadURL(WTFMove(frameLoadRequest), referer, FrameLoadType::RedirectWithLockedBackForwardList, nullptr, { }, WTF::nullopt, [] { });
991 }
992
993 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
994
995 void FrameLoader::loadArchive(Ref<Archive>&& archive)
996 {
997     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadArchive: frame load started");
998
999     ArchiveResource* mainResource = archive->mainResource();
1000     ASSERT(mainResource);
1001     if (!mainResource)
1002         return;
1003
1004     ResourceResponse response(URL(), mainResource->mimeType(), mainResource->data().size(), mainResource->textEncoding());
1005     SubstituteData substituteData(&mainResource->data(), URL(), response, SubstituteData::SessionHistoryVisibility::Hidden);
1006     
1007     ResourceRequest request(mainResource->url());
1008
1009     auto documentLoader = m_client->createDocumentLoader(request, substituteData);
1010     documentLoader->setArchive(WTFMove(archive));
1011     load(documentLoader.get());
1012 }
1013
1014 #endif // ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
1015
1016 String FrameLoader::outgoingReferrer() const
1017 {
1018     // See http://www.whatwg.org/specs/web-apps/current-work/#fetching-resources
1019     // for why we walk the parent chain for srcdoc documents.
1020     Frame* frame = &m_frame;
1021     while (frame && frame->document()->isSrcdocDocument()) {
1022         frame = frame->tree().parent();
1023         // Srcdoc documents cannot be top-level documents, by definition,
1024         // because they need to be contained in iframes with the srcdoc.
1025         ASSERT(frame);
1026     }
1027     if (!frame)
1028         return emptyString();
1029     return frame->loader().m_outgoingReferrer;
1030 }
1031
1032 String FrameLoader::outgoingOrigin() const
1033 {
1034     return m_frame.document()->securityOrigin().toString();
1035 }
1036
1037 bool FrameLoader::checkIfFormActionAllowedByCSP(const URL& url, bool didReceiveRedirectResponse) const
1038 {
1039     if (m_submittedFormURL.isEmpty())
1040         return true;
1041
1042     auto redirectResponseReceived = didReceiveRedirectResponse ? ContentSecurityPolicy::RedirectResponseReceived::Yes : ContentSecurityPolicy::RedirectResponseReceived::No;
1043     return m_frame.document()->contentSecurityPolicy()->allowFormAction(url, redirectResponseReceived);
1044 }
1045
1046 Frame* FrameLoader::opener()
1047 {
1048     return m_opener;
1049 }
1050
1051 void FrameLoader::setOpener(Frame* opener)
1052 {
1053     if (m_opener && !opener)
1054         m_client->didDisownOpener();
1055
1056     if (m_opener) {
1057         // When setOpener is called in ~FrameLoader, opener's m_frameLoader is already cleared.
1058         auto& openerFrameLoader = m_opener == &m_frame ? *this : m_opener->loader();
1059         openerFrameLoader.m_openedFrames.remove(&m_frame);
1060     }
1061     if (opener) {
1062         opener->loader().m_openedFrames.add(&m_frame);
1063         if (auto* page = m_frame.page())
1064             page->setOpenedByDOMWithOpener();
1065     }
1066     m_opener = opener;
1067
1068     if (m_frame.document())
1069         m_frame.document()->initSecurityContext();
1070 }
1071
1072 // FIXME: This does not belong in FrameLoader!
1073 void FrameLoader::handleFallbackContent()
1074 {
1075     HTMLFrameOwnerElement* owner = m_frame.ownerElement();
1076     if (!is<HTMLObjectElement>(owner))
1077         return;
1078     downcast<HTMLObjectElement>(*owner).renderFallbackContent();
1079 }
1080
1081 void FrameLoader::provisionalLoadStarted()
1082 {
1083     if (m_stateMachine.firstLayoutDone())
1084         m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
1085     m_frame.navigationScheduler().cancel(NewLoadInProgress::Yes);
1086     m_client->provisionalLoadStarted();
1087
1088     if (m_frame.isMainFrame()) {
1089         tracePoint(MainResourceLoadDidStartProvisional);
1090
1091         if (auto* page = m_frame.page())
1092             page->didStartProvisionalLoad();
1093     }
1094 }
1095
1096 void FrameLoader::resetMultipleFormSubmissionProtection()
1097 {
1098     m_submittedFormURL = URL();
1099 }
1100
1101 void FrameLoader::updateFirstPartyForCookies()
1102 {
1103     if (m_frame.tree().parent())
1104         setFirstPartyForCookies(m_frame.tree().parent()->document()->firstPartyForCookies());
1105     else
1106         setFirstPartyForCookies(m_frame.document()->url());
1107 }
1108
1109 void FrameLoader::setFirstPartyForCookies(const URL& url)
1110 {
1111     for (Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext(&m_frame))
1112         frame->document()->setFirstPartyForCookies(url);
1113
1114     RegistrableDomain registrableDomain(url);
1115     for (Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext(&m_frame)) {
1116         if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(frame->document()->url()) || registrableDomain.matches(frame->document()->url()))
1117             frame->document()->setSiteForCookies(url);
1118     }
1119 }
1120
1121 // This does the same kind of work that didOpenURL does, except it relies on the fact
1122 // that a higher level already checked that the URLs match and the scrolling is the right thing to do.
1123 void FrameLoader::loadInSameDocument(const URL& url, SerializedScriptValue* stateObject, bool isNewNavigation)
1124 {
1125     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadInSameDocument: frame load started");
1126
1127     // If we have a state object, we cannot also be a new navigation.
1128     ASSERT(!stateObject || (stateObject && !isNewNavigation));
1129
1130     // Update the data source's request with the new URL to fake the URL change
1131     URL oldURL = m_frame.document()->url();
1132     m_frame.document()->setURL(url);
1133     setOutgoingReferrer(url);
1134     documentLoader()->replaceRequestURLForSameDocumentNavigation(url);
1135     if (isNewNavigation && !shouldTreatURLAsSameAsCurrent(url) && !stateObject) {
1136         // NB: must happen after replaceRequestURLForSameDocumentNavigation(), since we add 
1137         // based on the current request. Must also happen before we openURL and displace the 
1138         // scroll position, since adding the BF item will save away scroll state.
1139         
1140         // NB2: If we were loading a long, slow doc, and the user fragment navigated before
1141         // it was done, currItem is now set the that slow doc, and prevItem is whatever was
1142         // before it.  Adding the b/f item will bump the slow doc down to prevItem, even
1143         // though its load is not yet done.  I think this all works out OK, for one because
1144         // we have already saved away the scroll and doc state for the long slow load,
1145         // but it's not an obvious case.
1146
1147         history().updateBackForwardListForFragmentScroll();
1148     }
1149     
1150     bool hashChange = equalIgnoringFragmentIdentifier(url, oldURL) && url.fragmentIdentifier() != oldURL.fragmentIdentifier();
1151     
1152     history().updateForSameDocumentNavigation();
1153
1154     // If we were in the autoscroll/panScroll mode we want to stop it before following the link to the anchor
1155     if (hashChange)
1156         m_frame.eventHandler().stopAutoscrollTimer();
1157     
1158     // It's important to model this as a load that starts and immediately finishes.
1159     // Otherwise, the parent frame may think we never finished loading.
1160     started();
1161
1162     if (auto* ownerElement = m_frame.ownerElement()) {
1163         auto* ownerRenderer = ownerElement->renderer();
1164         auto* view = m_frame.view();
1165         if (is<RenderWidget>(ownerRenderer) && view)
1166             downcast<RenderWidget>(*ownerRenderer).setWidget(view);
1167     }
1168
1169     // We need to scroll to the fragment whether or not a hash change occurred, since
1170     // the user might have scrolled since the previous navigation.
1171     scrollToFragmentWithParentBoundary(url, isNewNavigation);
1172     
1173     m_isComplete = false;
1174     checkCompleted();
1175
1176     if (isNewNavigation) {
1177         // This will clear previousItem from the rest of the frame tree that didn't
1178         // doing any loading. We need to make a pass on this now, since for fragment
1179         // navigation we'll not go through a real load and reach Completed state.
1180         checkLoadComplete();
1181     }
1182
1183     m_client->dispatchDidNavigateWithinPage();
1184
1185     m_frame.document()->statePopped(stateObject ? Ref<SerializedScriptValue> { *stateObject } : SerializedScriptValue::nullValue());
1186     m_client->dispatchDidPopStateWithinPage();
1187     
1188     if (hashChange) {
1189         m_frame.document()->enqueueHashchangeEvent(oldURL, url);
1190         m_client->dispatchDidChangeLocationWithinPage();
1191     }
1192     
1193     // FrameLoaderClient::didFinishLoad() tells the internal load delegate the load finished with no error
1194     m_client->didFinishLoad();
1195 }
1196
1197 bool FrameLoader::isComplete() const
1198 {
1199     return m_isComplete;
1200 }
1201
1202 void FrameLoader::completed()
1203 {
1204     Ref<Frame> protect(m_frame);
1205
1206     for (Frame* descendant = m_frame.tree().traverseNext(&m_frame); descendant; descendant = descendant->tree().traverseNext(&m_frame))
1207         descendant->navigationScheduler().startTimer();
1208
1209     if (Frame* parent = m_frame.tree().parent())
1210         parent->loader().checkCompleted();
1211
1212     if (m_frame.view())
1213         m_frame.view()->maintainScrollPositionAtAnchor(nullptr);
1214 }
1215
1216 void FrameLoader::started()
1217 {
1218     for (Frame* frame = &m_frame; frame; frame = frame->tree().parent())
1219         frame->loader().m_isComplete = false;
1220 }
1221
1222 void FrameLoader::prepareForLoadStart()
1223 {
1224     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "prepareForLoadStart: Starting frame load");
1225
1226     m_progressTracker->progressStarted();
1227     m_client->dispatchDidStartProvisionalLoad();
1228
1229     if (AXObjectCache::accessibilityEnabled()) {
1230         if (AXObjectCache* cache = m_frame.document()->existingAXObjectCache()) {
1231             AXObjectCache::AXLoadingEvent loadingEvent = loadType() == FrameLoadType::Reload ? AXObjectCache::AXLoadingReloaded : AXObjectCache::AXLoadingStarted;
1232             cache->frameLoadingEventNotification(&m_frame, loadingEvent);
1233         }
1234     }
1235 }
1236
1237 void FrameLoader::setupForReplace()
1238 {
1239     m_client->revertToProvisionalState(m_documentLoader.get());
1240     setState(FrameStateProvisional);
1241     m_provisionalDocumentLoader = m_documentLoader;
1242     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "setupForReplace: Setting provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
1243     m_documentLoader = nullptr;
1244     detachChildren();
1245 }
1246
1247 void FrameLoader::loadFrameRequest(FrameLoadRequest&& request, Event* event, RefPtr<FormState>&& formState, Optional<AdClickAttribution>&& adClickAttribution)
1248 {
1249     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadFrameRequest: frame load started");
1250
1251     // Protect frame from getting blown away inside dispatchBeforeLoadEvent in loadWithDocumentLoader.
1252     auto protectFrame = makeRef(m_frame);
1253
1254     URL url = request.resourceRequest().url();
1255
1256     ASSERT(m_frame.document());
1257     if (!request.requesterSecurityOrigin().canDisplay(url)) {
1258         reportLocalLoadFailed(&m_frame, url.stringCenterEllipsizedToLength());
1259         return;
1260     }
1261
1262     String argsReferrer = request.resourceRequest().httpReferrer();
1263     if (argsReferrer.isEmpty())
1264         argsReferrer = outgoingReferrer();
1265
1266     ReferrerPolicy referrerPolicy = request.referrerPolicy();
1267     if (referrerPolicy == ReferrerPolicy::EmptyString)
1268         referrerPolicy = m_frame.document()->referrerPolicy();
1269     String referrer = SecurityPolicy::generateReferrerHeader(referrerPolicy, url, argsReferrer);
1270
1271     FrameLoadType loadType;
1272     if (request.resourceRequest().cachePolicy() == ResourceRequestCachePolicy::ReloadIgnoringCacheData)
1273         loadType = FrameLoadType::Reload;
1274     else if (request.lockBackForwardList() == LockBackForwardList::Yes)
1275         loadType = FrameLoadType::RedirectWithLockedBackForwardList;
1276     else
1277         loadType = FrameLoadType::Standard;
1278
1279     auto completionHandler = [this, protectedFrame = makeRef(m_frame), formState = makeWeakPtr(formState.get()), frameName = request.frameName()] {
1280         // FIXME: It's possible this targetFrame will not be the same frame that was targeted by the actual
1281         // load if frame names have changed.
1282         Frame* sourceFrame = formState ? formState->sourceDocument().frame() : &m_frame;
1283         if (!sourceFrame)
1284             sourceFrame = &m_frame;
1285         Frame* targetFrame = sourceFrame->loader().findFrameForNavigation(frameName);
1286         if (targetFrame && targetFrame != sourceFrame) {
1287             if (Page* page = targetFrame->page())
1288                 page->chrome().focus();
1289         }
1290     };
1291
1292     if (request.resourceRequest().httpMethod() == "POST")
1293         loadPostRequest(WTFMove(request), referrer, loadType, event, WTFMove(formState), WTFMove(completionHandler));
1294     else
1295         loadURL(WTFMove(request), referrer, loadType, event, WTFMove(formState), WTFMove(adClickAttribution), WTFMove(completionHandler));
1296 }
1297
1298 static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& currentFrame, InitiatedByMainFrame initiatedByMainFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
1299 {
1300     if (UserGestureIndicator::processingUserGesture())
1301         return ShouldOpenExternalURLsPolicy::ShouldAllow;
1302
1303     if (initiatedByMainFrame == InitiatedByMainFrame::Yes)
1304         return propagatedPolicy;
1305
1306     if (!currentFrame.isMainFrame())
1307         return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
1308
1309     return propagatedPolicy;
1310 }
1311
1312 static ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicyToApply(Frame& currentFrame, const FrameLoadRequest& frameLoadRequest)
1313 {
1314     return shouldOpenExternalURLsPolicyToApply(currentFrame, frameLoadRequest.initiatedByMainFrame(), frameLoadRequest.shouldOpenExternalURLsPolicy());
1315 }
1316
1317 static void applyShouldOpenExternalURLsPolicyToNewDocumentLoader(Frame& frame, DocumentLoader& documentLoader, InitiatedByMainFrame initiatedByMainFrame, ShouldOpenExternalURLsPolicy propagatedPolicy)
1318 {
1319     documentLoader.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(frame, initiatedByMainFrame, propagatedPolicy));
1320 }
1321
1322 static void applyShouldOpenExternalURLsPolicyToNewDocumentLoader(Frame& frame, DocumentLoader& documentLoader, const FrameLoadRequest& frameLoadRequest)
1323 {
1324     documentLoader.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(frame, frameLoadRequest));
1325 }
1326
1327 bool FrameLoader::isNavigationAllowed() const
1328 {
1329     return m_pageDismissalEventBeingDispatched == PageDismissalType::None && !m_frame.script().willReplaceWithResultOfExecutingJavascriptURL() && NavigationDisabler::isNavigationAllowed(m_frame);
1330 }
1331
1332 bool FrameLoader::isStopLoadingAllowed() const
1333 {
1334     return m_pageDismissalEventBeingDispatched == PageDismissalType::None;
1335 }
1336
1337 void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& referrer, FrameLoadType newLoadType, Event* event, RefPtr<FormState>&& formState, Optional<AdClickAttribution>&& adClickAttribution, CompletionHandler<void()>&& completionHandler)
1338 {
1339     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadURL: frame load started");
1340
1341     CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
1342     if (m_inStopAllLoaders || m_inClearProvisionalLoadForPolicyCheck)
1343         return;
1344
1345     Ref<Frame> protect(m_frame);
1346
1347     // Anchor target is ignored when the download attribute is set since it will download the hyperlink rather than follow it.
1348     String effectiveFrameName = frameLoadRequest.downloadAttribute().isNull() ? frameLoadRequest.frameName() : String();
1349     AllowNavigationToInvalidURL allowNavigationToInvalidURL = frameLoadRequest.allowNavigationToInvalidURL();
1350     NewFrameOpenerPolicy openerPolicy = frameLoadRequest.newFrameOpenerPolicy();
1351     LockHistory lockHistory = frameLoadRequest.lockHistory();
1352     bool isFormSubmission = formState;
1353
1354     const URL& newURL = frameLoadRequest.resourceRequest().url();
1355     ResourceRequest request(newURL);
1356     if (!referrer.isEmpty()) {
1357         request.setHTTPReferrer(referrer);
1358         auto referrerOrigin = SecurityOrigin::createFromString(referrer);
1359         addHTTPOriginIfNeeded(request, referrerOrigin->toString());
1360     }
1361     if (&m_frame.tree().top() != &m_frame)
1362         request.setDomainForCachePartition(m_frame.tree().top().document()->domainForCachePartition());
1363
1364     addExtraFieldsToRequest(request, newLoadType, true);
1365     if (isReload(newLoadType))
1366         request.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
1367
1368     ASSERT(newLoadType != FrameLoadType::Same);
1369
1370     // The search for a target frame is done earlier in the case of form submission.
1371     Frame* targetFrame = isFormSubmission ? nullptr : findFrameForNavigation(effectiveFrameName);
1372     if (targetFrame && targetFrame != &m_frame) {
1373         frameLoadRequest.setFrameName("_self");
1374         targetFrame->loader().loadURL(WTFMove(frameLoadRequest), referrer, newLoadType, event, WTFMove(formState), WTFMove(adClickAttribution), completionHandlerCaller.release());
1375         return;
1376     }
1377
1378     if (!isNavigationAllowed())
1379         return;
1380
1381     NavigationAction action { frameLoadRequest.requester(), request, frameLoadRequest.initiatedByMainFrame(), newLoadType, isFormSubmission, event, frameLoadRequest.shouldOpenExternalURLsPolicy(), frameLoadRequest.downloadAttribute() };
1382     action.setLockHistory(lockHistory);
1383     action.setLockBackForwardList(frameLoadRequest.lockBackForwardList());
1384     if (adClickAttribution && m_frame.isMainFrame())
1385         action.setAdClickAttribution(WTFMove(*adClickAttribution));
1386
1387     if (!targetFrame && !effectiveFrameName.isEmpty()) {
1388         action = action.copyWithShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, frameLoadRequest));
1389         policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request), WTFMove(formState), effectiveFrameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, PolicyChecker::ShouldContinue shouldContinue) mutable {
1390             continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
1391             completionHandler();
1392         });
1393         return;
1394     }
1395
1396     RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
1397
1398     bool sameURL = shouldTreatURLAsSameAsCurrent(newURL);
1399     const String& httpMethod = request.httpMethod();
1400     
1401     // Make sure to do scroll to fragment processing even if the URL is
1402     // exactly the same so pages with '#' links and DHTML side effects
1403     // work properly.
1404     if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, newLoadType, newURL)) {
1405         oldDocumentLoader->setTriggeringAction(WTFMove(action));
1406         oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
1407         policyChecker().stopCheck();
1408         policyChecker().setLoadType(newLoadType);
1409         RELEASE_ASSERT(!isBackForwardLoadType(newLoadType) || history().provisionalItem());
1410         policyChecker().checkNavigationPolicy(WTFMove(request), ResourceResponse { } /* redirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, NavigationPolicyDecision navigationPolicyDecision) {
1411             continueFragmentScrollAfterNavigationPolicy(request, navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad);
1412         }, PolicyDecisionMode::Synchronous);
1413         return;
1414     }
1415
1416     // Must grab this now, since this load may stop the previous load and clear this flag.
1417     bool isRedirect = m_quickRedirectComing;
1418 #if USE(SYSTEM_PREVIEW)
1419     bool isSystemPreview = frameLoadRequest.isSystemPreview();
1420     if (isSystemPreview)
1421         request.setSystemPreviewInfo(frameLoadRequest.systemPreviewInfo());
1422 #endif
1423     loadWithNavigationAction(request, WTFMove(action), lockHistory, newLoadType, WTFMove(formState), allowNavigationToInvalidURL, frameLoadRequest.downloadAttribute(), [this, isRedirect, sameURL, newLoadType, protectedFrame = makeRef(m_frame), completionHandler = completionHandlerCaller.release()] () mutable {
1424         if (isRedirect) {
1425             m_quickRedirectComing = false;
1426             if (m_provisionalDocumentLoader)
1427                 m_provisionalDocumentLoader->setIsClientRedirect(true);
1428             else if (m_policyDocumentLoader)
1429                 m_policyDocumentLoader->setIsClientRedirect(true);
1430         } else if (sameURL && !isReload(newLoadType)) {
1431             // Example of this case are sites that reload the same URL with a different cookie
1432             // driving the generated content, or a master frame with links that drive a target
1433             // frame, where the user has clicked on the same link repeatedly.
1434             m_loadType = FrameLoadType::Same;
1435         }
1436         completionHandler();
1437     });
1438 }
1439
1440 SubstituteData FrameLoader::defaultSubstituteDataForURL(const URL& url)
1441 {
1442     if (!shouldTreatURLAsSrcdocDocument(url))
1443         return SubstituteData();
1444     auto& srcdoc = m_frame.ownerElement()->attributeWithoutSynchronization(srcdocAttr);
1445     ASSERT(!srcdoc.isNull());
1446     CString encodedSrcdoc = srcdoc.string().utf8();
1447
1448     ResourceResponse response(URL(), "text/html"_s, encodedSrcdoc.length(), "UTF-8"_s);
1449     return SubstituteData(SharedBuffer::create(encodedSrcdoc.data(), encodedSrcdoc.length()), URL(), response, SubstituteData::SessionHistoryVisibility::Hidden);
1450 }
1451
1452 void FrameLoader::load(FrameLoadRequest&& request)
1453 {
1454     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "load (FrameLoadRequest): frame load started");
1455
1456     if (m_inStopAllLoaders || m_inClearProvisionalLoadForPolicyCheck)
1457         return;
1458
1459     if (!request.frameName().isEmpty()) {
1460         Frame* frame = findFrameForNavigation(request.frameName());
1461         if (frame) {
1462             request.setShouldCheckNewWindowPolicy(false);
1463             if (&frame->loader() != this) {
1464                 frame->loader().load(WTFMove(request));
1465                 return;
1466             }
1467         }
1468     }
1469
1470     if (request.shouldCheckNewWindowPolicy()) {
1471         NavigationAction action { request.requester(), request.resourceRequest(), InitiatedByMainFrame::Unknown, NavigationType::Other, request.shouldOpenExternalURLsPolicy() };
1472         policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request.resourceRequest()), { }, request.frameName(), [this] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, PolicyChecker::ShouldContinue shouldContinue) {
1473             continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);
1474         });
1475
1476         return;
1477     }
1478
1479     if (!request.hasSubstituteData())
1480         request.setSubstituteData(defaultSubstituteDataForURL(request.resourceRequest().url()));
1481
1482     Ref<DocumentLoader> loader = m_client->createDocumentLoader(request.resourceRequest(), request.substituteData());
1483     loader->setAllowsWebArchiveForMainFrame(request.isRequestFromClientOrUserInput());
1484     loader->setAllowsDataURLsForMainFrame(request.isRequestFromClientOrUserInput());
1485     addSameSiteInfoToRequestIfNeeded(loader->request());
1486     applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, request);
1487
1488     if (request.shouldTreatAsContinuingLoad()) {
1489         loader->setClientRedirectSourceForHistory(request.clientRedirectSourceForHistory());
1490         if (request.lockBackForwardList() == LockBackForwardList::Yes) {
1491             loader->setIsClientRedirect(true);
1492             m_loadType = FrameLoadType::RedirectWithLockedBackForwardList;
1493         }
1494     }
1495
1496     SetForScope<LoadContinuingState> continuingLoadGuard(m_currentLoadContinuingState, request.shouldTreatAsContinuingLoad() ? LoadContinuingState::ContinuingWithRequest : LoadContinuingState::NotContinuing);
1497     load(loader.get());
1498 }
1499
1500 void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, NavigationAction&& action, LockHistory lockHistory, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, const String& downloadAttribute, CompletionHandler<void()>&& completionHandler)
1501 {
1502     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadWithNavigationAction: frame load started");
1503
1504     Ref<DocumentLoader> loader = m_client->createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
1505     loader->setDownloadAttribute(downloadAttribute);
1506     applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, action.initiatedByMainFrame(), action.shouldOpenExternalURLsPolicy());
1507
1508     if (lockHistory == LockHistory::Yes && m_documentLoader)
1509         loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory().string() : m_documentLoader->clientRedirectSourceForHistory());
1510
1511     loader->setTriggeringAction(WTFMove(action));
1512     if (m_documentLoader)
1513         loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
1514
1515     loadWithDocumentLoader(loader.ptr(), type, WTFMove(formState), allowNavigationToInvalidURL, ShouldTreatAsContinuingLoad::No, WTFMove(completionHandler));
1516 }
1517
1518 void FrameLoader::load(DocumentLoader& newDocumentLoader)
1519 {
1520     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "load (DocumentLoader): frame load started");
1521
1522     ResourceRequest& r = newDocumentLoader.request();
1523     addExtraFieldsToMainResourceRequest(r);
1524     FrameLoadType type;
1525
1526     if (shouldTreatURLAsSameAsCurrent(newDocumentLoader.originalRequest().url())) {
1527         r.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
1528         type = FrameLoadType::Same;
1529     } else if (shouldTreatURLAsSameAsCurrent(newDocumentLoader.unreachableURL()) && isReload(m_loadType))
1530         type = m_loadType;
1531     else if (m_loadType == FrameLoadType::RedirectWithLockedBackForwardList && ((!newDocumentLoader.unreachableURL().isEmpty() && newDocumentLoader.substituteData().isValid()) || shouldTreatCurrentLoadAsContinuingLoad()))
1532         type = FrameLoadType::RedirectWithLockedBackForwardList;
1533     else
1534         type = FrameLoadType::Standard;
1535
1536     if (m_documentLoader)
1537         newDocumentLoader.setOverrideEncoding(m_documentLoader->overrideEncoding());
1538     
1539     // When we loading alternate content for an unreachable URL that we're
1540     // visiting in the history list, we treat it as a reload so the history list 
1541     // is appropriately maintained.
1542     //
1543     // FIXME: This seems like a dangerous overloading of the meaning of "FrameLoadType::Reload" ...
1544     // shouldn't a more explicit type of reload be defined, that means roughly 
1545     // "load without affecting history" ? 
1546     if (shouldReloadToHandleUnreachableURL(newDocumentLoader)) {
1547         // shouldReloadToHandleUnreachableURL returns true only when the original load type is back-forward.
1548         // In this case we should save the document state now. Otherwise the state can be lost because load type is
1549         // changed and updateForBackForwardNavigation() will not be called when loading is committed.
1550         history().saveDocumentAndScrollState();
1551
1552         ASSERT(type == FrameLoadType::Standard);
1553         type = FrameLoadType::Reload;
1554     }
1555
1556     loadWithDocumentLoader(&newDocumentLoader, type, nullptr, AllowNavigationToInvalidURL::Yes, ShouldTreatAsContinuingLoad::No);
1557 }
1558
1559 void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType type, RefPtr<FormState>&& formState, AllowNavigationToInvalidURL allowNavigationToInvalidURL, ShouldTreatAsContinuingLoad, CompletionHandler<void()>&& completionHandler)
1560 {
1561     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadWithDocumentLoader: frame load started");
1562
1563     // Retain because dispatchBeforeLoadEvent may release the last reference to it.
1564     Ref<Frame> protect(m_frame);
1565
1566     CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
1567
1568     ASSERT(m_client->hasWebView());
1569
1570     // Unfortunately the view must be non-nil, this is ultimately due
1571     // to parser requiring a FrameView.  We should fix this dependency.
1572
1573     ASSERT(m_frame.view());
1574
1575     if (!isNavigationAllowed())
1576         return;
1577
1578     if (m_frame.document())
1579         m_previousURL = m_frame.document()->url();
1580
1581     const URL& newURL = loader->request().url();
1582
1583     // Only the first iframe navigation or the first iframe navigation after about:blank should be reported.
1584     // https://www.w3.org/TR/resource-timing-2/#resources-included-in-the-performanceresourcetiming-interface
1585     if (m_shouldReportResourceTimingToParentFrame && !m_previousURL.isNull() && m_previousURL != WTF::blankURL())
1586         m_shouldReportResourceTimingToParentFrame = false;
1587
1588     // Log main frame navigation types.
1589     if (m_frame.isMainFrame()) {
1590         if (auto* page = m_frame.page()) {
1591             FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadWithDocumentLoader: main frame load started");
1592             page->mainFrameLoadStarted(newURL, type);
1593             page->performanceLogging().didReachPointOfInterest(PerformanceLogging::MainFrameLoadStarted);
1594         }
1595     }
1596
1597     policyChecker().setLoadType(type);
1598     RELEASE_ASSERT(!isBackForwardLoadType(type) || history().provisionalItem());
1599     bool isFormSubmission = formState;
1600
1601     const String& httpMethod = loader->request().httpMethod();
1602
1603     if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, policyChecker().loadType(), newURL)) {
1604         RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
1605         NavigationAction action { *m_frame.document(), loader->request(), InitiatedByMainFrame::Unknown, policyChecker().loadType(), isFormSubmission };
1606
1607         oldDocumentLoader->setTriggeringAction(WTFMove(action));
1608         oldDocumentLoader->setLastCheckedRequest(ResourceRequest());
1609         policyChecker().stopCheck();
1610         RELEASE_ASSERT(!isBackForwardLoadType(policyChecker().loadType()) || history().provisionalItem());
1611         policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), ResourceResponse { }  /* redirectResponse */, oldDocumentLoader.get(), WTFMove(formState), [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, NavigationPolicyDecision navigationPolicyDecision) {
1612             continueFragmentScrollAfterNavigationPolicy(request, navigationPolicyDecision == NavigationPolicyDecision::ContinueLoad);
1613         }, PolicyDecisionMode::Synchronous);
1614         return;
1615     }
1616
1617     if (Frame* parent = m_frame.tree().parent())
1618         loader->setOverrideEncoding(parent->loader().documentLoader()->overrideEncoding());
1619
1620     policyChecker().stopCheck();
1621     setPolicyDocumentLoader(loader);
1622     if (loader->triggeringAction().isEmpty())
1623         loader->setTriggeringAction({ *m_frame.document(), loader->request(), InitiatedByMainFrame::Unknown, policyChecker().loadType(), isFormSubmission });
1624
1625     if (Element* ownerElement = m_frame.ownerElement()) {
1626         // We skip dispatching the beforeload event if we've already
1627         // committed a real document load because the event would leak
1628         // subsequent activity by the frame which the parent frame isn't
1629         // supposed to learn. For example, if the child frame navigated to
1630         // a new URL, the parent frame shouldn't learn the URL.
1631         if (!m_stateMachine.committedFirstRealDocumentLoad()
1632             && !ownerElement->dispatchBeforeLoadEvent(loader->request().url().string())) {
1633             continueLoadAfterNavigationPolicy(loader->request(), formState.get(), NavigationPolicyDecision::IgnoreLoad, allowNavigationToInvalidURL);
1634             return;
1635         }
1636     }
1637
1638     m_frame.navigationScheduler().cancel(NewLoadInProgress::Yes);
1639
1640     if (shouldTreatCurrentLoadAsContinuingLoad()) {
1641         continueLoadAfterNavigationPolicy(loader->request(), formState.get(), NavigationPolicyDecision::ContinueLoad, allowNavigationToInvalidURL);
1642         return;
1643     }
1644
1645     RELEASE_ASSERT(!isBackForwardLoadType(policyChecker().loadType()) || history().provisionalItem());
1646     policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), ResourceResponse { } /* redirectResponse */, loader, WTFMove(formState), [this, protectedFrame = makeRef(m_frame), allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, NavigationPolicyDecision navigationPolicyDecision) mutable {
1647         continueLoadAfterNavigationPolicy(request, formState.get(), navigationPolicyDecision, allowNavigationToInvalidURL);
1648         completionHandler();
1649     }, PolicyDecisionMode::Asynchronous);
1650 }
1651
1652 void FrameLoader::clearProvisionalLoadForPolicyCheck()
1653 {
1654     if (!m_policyDocumentLoader || !m_provisionalDocumentLoader || m_inClearProvisionalLoadForPolicyCheck)
1655         return;
1656
1657     SetForScope<bool> change(m_inClearProvisionalLoadForPolicyCheck, true);
1658     m_provisionalDocumentLoader->stopLoading();
1659     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "clearProvisionalLoadForPolicyCheck: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
1660     setProvisionalDocumentLoader(nullptr);
1661 }
1662
1663 void FrameLoader::reportLocalLoadFailed(Frame* frame, const String& url)
1664 {
1665     ASSERT(!url.isEmpty());
1666     if (!frame)
1667         return;
1668
1669     frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to load local resource: " + url);
1670 }
1671
1672 void FrameLoader::reportBlockedPortFailed(Frame* frame, const String& url)
1673 {
1674     ASSERT(!url.isEmpty());
1675     if (!frame)
1676         return;
1677     
1678     frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to use restricted network port: " + url);
1679 }
1680
1681 void FrameLoader::reportAuthenticationChallengeBlocked(Frame* frame, const URL& url, const String& reason)
1682 {
1683     if (!frame)
1684         return;
1685
1686     frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, makeString("Blocked ", url.stringCenterEllipsizedToLength(), " from asking for credentials because ", reason, '.'));
1687 }
1688
1689 const ResourceRequest& FrameLoader::initialRequest() const
1690 {
1691     return activeDocumentLoader()->originalRequest();
1692 }
1693
1694 bool FrameLoader::willLoadMediaElementURL(URL& url, Node& initiatorNode)
1695 {
1696 #if PLATFORM(IOS_FAMILY)
1697     // MobileStore depends on the iOS 4.0 era client delegate method because webView:resource:willSendRequest:redirectResponse:fromDataSource
1698     // doesn't let them tell when a load request is coming from a media element. See <rdar://problem/8266916> for more details.
1699     if (IOSApplication::isMobileStore())
1700         return m_client->shouldLoadMediaElementURL(url);
1701 #endif
1702
1703     ResourceRequest request(url);
1704     request.setInspectorInitiatorNodeIdentifier(InspectorInstrumentation::identifierForNode(initiatorNode));
1705
1706     unsigned long identifier;
1707     ResourceError error;
1708     requestFromDelegate(request, identifier, error);
1709     notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, ResourceResponse(url, String(), -1, String()), 0, -1, -1, error);
1710
1711     url = request.url();
1712
1713     return error.isNull();
1714 }
1715
1716 bool FrameLoader::shouldReloadToHandleUnreachableURL(DocumentLoader& docLoader)
1717 {
1718     URL unreachableURL = docLoader.unreachableURL();
1719
1720     if (unreachableURL.isEmpty())
1721         return false;
1722
1723     if (!isBackForwardLoadType(policyChecker().loadType()))
1724         return false;
1725
1726     // We only treat unreachableURLs specially during the delegate callbacks
1727     // for provisional load errors and navigation policy decisions. The former
1728     // case handles well-formed URLs that can't be loaded, and the latter
1729     // case handles malformed URLs and unknown schemes. Loading alternate content
1730     // at other times behaves like a standard load.
1731     if (policyChecker().delegateIsDecidingNavigationPolicy() || policyChecker().delegateIsHandlingUnimplementablePolicy())
1732         return m_policyDocumentLoader && unreachableURL == m_policyDocumentLoader->request().url();
1733
1734     return unreachableURL == m_provisionalLoadErrorBeingHandledURL;
1735 }
1736
1737 void FrameLoader::reloadWithOverrideEncoding(const String& encoding)
1738 {
1739     if (!m_documentLoader)
1740         return;
1741
1742     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "reloadWithOverrideEncoding: frame load started");
1743
1744     ResourceRequest request = m_documentLoader->request();
1745     URL unreachableURL = m_documentLoader->unreachableURL();
1746     if (!unreachableURL.isEmpty())
1747         request.setURL(unreachableURL);
1748
1749     // FIXME: If the resource is a result of form submission and is not cached, the form will be silently resubmitted.
1750     // We should ask the user for confirmation in this case.
1751     request.setCachePolicy(ResourceRequestCachePolicy::ReturnCacheDataElseLoad);
1752
1753     Ref<DocumentLoader> loader = m_client->createDocumentLoader(request, defaultSubstituteDataForURL(request.url()));
1754     applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, InitiatedByMainFrame::Unknown, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
1755
1756     setPolicyDocumentLoader(loader.ptr());
1757
1758     loader->setOverrideEncoding(encoding);
1759
1760     loadWithDocumentLoader(loader.ptr(), FrameLoadType::Reload, { }, AllowNavigationToInvalidURL::Yes, ShouldTreatAsContinuingLoad::No);
1761 }
1762
1763 void FrameLoader::reload(OptionSet<ReloadOption> options)
1764 {
1765     if (!m_documentLoader)
1766         return;
1767
1768     // If a window is created by javascript, its main frame can have an empty but non-nil URL.
1769     // Reloading in this case will lose the current contents (see 4151001).
1770     if (m_documentLoader->request().url().isEmpty())
1771         return;
1772
1773     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "reload: frame load started");
1774
1775     // Replace error-page URL with the URL we were trying to reach.
1776     ResourceRequest initialRequest = m_documentLoader->request();
1777     URL unreachableURL = m_documentLoader->unreachableURL();
1778     if (!unreachableURL.isEmpty())
1779         initialRequest.setURL(unreachableURL);
1780
1781     // Create a new document loader for the reload, this will become m_documentLoader eventually,
1782     // but first it has to be the "policy" document loader, and then the "provisional" document loader.
1783     Ref<DocumentLoader> loader = m_client->createDocumentLoader(initialRequest, defaultSubstituteDataForURL(initialRequest.url()));
1784     loader->setAllowsWebArchiveForMainFrame(m_documentLoader->allowsWebArchiveForMainFrame());
1785     loader->setAllowsDataURLsForMainFrame(m_documentLoader->allowsDataURLsForMainFrame());
1786     applyShouldOpenExternalURLsPolicyToNewDocumentLoader(m_frame, loader, InitiatedByMainFrame::Unknown, m_documentLoader->shouldOpenExternalURLsPolicyToPropagate());
1787
1788     loader->setUserContentExtensionsEnabled(!options.contains(ReloadOption::DisableContentBlockers));
1789     
1790     ResourceRequest& request = loader->request();
1791
1792     // FIXME: We don't have a mechanism to revalidate the main resource without reloading at the moment.
1793     request.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
1794
1795     addSameSiteInfoToRequestIfNeeded(request);
1796
1797     // If we're about to re-post, set up action so the application can warn the user.
1798     if (request.httpMethod() == "POST")
1799         loader->setTriggeringAction({ *m_frame.document(), request, InitiatedByMainFrame::Unknown, NavigationType::FormResubmitted });
1800
1801     loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
1802
1803     auto frameLoadTypeForReloadOptions = [] (auto options) {
1804         if (options & ReloadOption::FromOrigin)
1805             return FrameLoadType::ReloadFromOrigin;
1806         if (options & ReloadOption::ExpiredOnly)
1807             return FrameLoadType::ReloadExpiredOnly;
1808         return FrameLoadType::Reload;
1809     };
1810     
1811     loadWithDocumentLoader(loader.ptr(), frameLoadTypeForReloadOptions(options), { }, AllowNavigationToInvalidURL::Yes, ShouldTreatAsContinuingLoad::No);
1812 }
1813
1814 void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItemPolicy, StopLoadingPolicy stopLoadingPolicy)
1815 {
1816     if (m_frame.document() && m_frame.document()->backForwardCacheState() == Document::InBackForwardCache)
1817         return;
1818
1819     if (stopLoadingPolicy == StopLoadingPolicy::PreventDuringUnloadEvents && !isStopLoadingAllowed())
1820         return;
1821
1822     // If this method is called from within this method, infinite recursion can occur (3442218). Avoid this.
1823     if (m_inStopAllLoaders)
1824         return;
1825
1826     // This method might dispatch events.
1827     RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isScriptAllowed());
1828
1829     // Calling stopLoading() on the provisional document loader can blow away
1830     // the frame from underneath.
1831     Ref<Frame> protect(m_frame);
1832
1833     m_inStopAllLoaders = true;
1834
1835     policyChecker().stopCheck();
1836
1837     // If no new load is in progress, we should clear the provisional item from history
1838     // before we call stopLoading.
1839     if (clearProvisionalItemPolicy == ShouldClearProvisionalItem)
1840         history().setProvisionalItem(nullptr);
1841
1842     for (RefPtr<Frame> child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
1843         child->loader().stopAllLoaders(clearProvisionalItemPolicy);
1844     if (m_provisionalDocumentLoader)
1845         m_provisionalDocumentLoader->stopLoading();
1846     if (m_documentLoader)
1847         m_documentLoader->stopLoading();
1848     if (m_frame.page() && !m_frame.page()->chrome().client().isSVGImageChromeClient())
1849         platformStrategies()->loaderStrategy()->browsingContextRemoved(frame());
1850
1851     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "stopAllLoaders: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
1852     setProvisionalDocumentLoader(nullptr);
1853
1854     m_inStopAllLoaders = false;    
1855 }
1856
1857 void FrameLoader::stopForBackForwardCache()
1858 {
1859     // Stop provisional loads in subframes (The one in the main frame is about to be committed).
1860     if (!m_frame.isMainFrame()) {
1861         if (m_provisionalDocumentLoader)
1862             m_provisionalDocumentLoader->stopLoading();
1863         FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "stopForBackForwardCache: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
1864         setProvisionalDocumentLoader(nullptr);
1865     }
1866
1867     // Stop current loads.
1868     if (m_documentLoader)
1869         m_documentLoader->stopLoading();
1870
1871     for (RefPtr<Frame> child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
1872         child->loader().stopForBackForwardCache();
1873
1874     // We cancel pending navigations & policy checks *after* cancelling loads because cancelling loads might end up
1875     // running script, which could schedule new navigations.
1876     policyChecker().stopCheck();
1877     m_frame.navigationScheduler().cancel();
1878 }
1879
1880 void FrameLoader::stopAllLoadersAndCheckCompleteness()
1881 {
1882     stopAllLoaders();
1883
1884     if (!m_checkTimer.isActive())
1885         return;
1886
1887     m_checkTimer.stop();
1888     m_checkingLoadCompleteForDetachment = true;
1889     checkCompletenessNow();
1890     m_checkingLoadCompleteForDetachment = false;
1891 }
1892
1893 void FrameLoader::stopForUserCancel(bool deferCheckLoadComplete)
1894 {
1895     // Calling stopAllLoaders can cause the frame to be deallocated, including the frame loader.
1896     Ref<Frame> protectedFrame(m_frame);
1897
1898     stopAllLoaders();
1899
1900 #if PLATFORM(IOS_FAMILY)
1901     // Lay out immediately when stopping to immediately clear the old page if we just committed this one
1902     // but haven't laid out/painted yet.
1903     // FIXME: Is this behavior specific to iOS? Or should we expose a setting to toggle this behavior?
1904     if (m_frame.view() && !m_frame.view()->didFirstLayout())
1905         m_frame.view()->layoutContext().layout();
1906 #endif
1907
1908     if (deferCheckLoadComplete)
1909         scheduleCheckLoadComplete();
1910     else if (m_frame.page())
1911         checkLoadComplete();
1912 }
1913
1914 DocumentLoader* FrameLoader::activeDocumentLoader() const
1915 {
1916     if (m_state == FrameStateProvisional)
1917         return m_provisionalDocumentLoader.get();
1918     return m_documentLoader.get();
1919 }
1920
1921 bool FrameLoader::isLoading() const
1922 {
1923     DocumentLoader* docLoader = activeDocumentLoader();
1924     if (!docLoader)
1925         return false;
1926     return docLoader->isLoading();
1927 }
1928
1929 bool FrameLoader::frameHasLoaded() const
1930 {
1931     return m_stateMachine.committedFirstRealDocumentLoad() || (m_provisionalDocumentLoader && !m_stateMachine.creatingInitialEmptyDocument()); 
1932 }
1933
1934 void FrameLoader::setDocumentLoader(DocumentLoader* loader)
1935 {
1936     if (!loader && !m_documentLoader)
1937         return;
1938
1939     if (loader == m_documentLoader)
1940         return;
1941     
1942     ASSERT(loader != m_documentLoader);
1943     ASSERT(!loader || loader->frameLoader() == this);
1944
1945     m_client->prepareForDataSourceReplacement();
1946     detachChildren();
1947
1948     // detachChildren() can trigger this frame's unload event, and therefore
1949     // script can run and do just about anything. For example, an unload event that calls
1950     // document.write("") on its parent frame can lead to a recursive detachChildren()
1951     // invocation for this frame. In that case, we can end up at this point with a
1952     // loader that hasn't been deleted but has been detached from its frame. Such a
1953     // DocumentLoader has been sufficiently detached that we'll end up in an inconsistent
1954     // state if we try to use it.
1955     if (loader && !loader->frame())
1956         return;
1957
1958     if (m_documentLoader)
1959         m_documentLoader->detachFromFrame();
1960
1961     m_documentLoader = loader;
1962 }
1963
1964 void FrameLoader::setPolicyDocumentLoader(DocumentLoader* loader)
1965 {
1966     if (m_policyDocumentLoader == loader)
1967         return;
1968
1969     if (loader)
1970         loader->attachToFrame(m_frame);
1971     if (m_policyDocumentLoader
1972             && m_policyDocumentLoader != m_provisionalDocumentLoader
1973             && m_policyDocumentLoader != m_documentLoader)
1974         m_policyDocumentLoader->detachFromFrame();
1975
1976     m_policyDocumentLoader = loader;
1977 }
1978
1979 void FrameLoader::setProvisionalDocumentLoader(DocumentLoader* loader)
1980 {
1981     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "setProvisionalDocumentLoader: Setting provisional document loader (m_provisionalDocumentLoader=%p)", loader);
1982
1983     ASSERT(!loader || !m_provisionalDocumentLoader);
1984     ASSERT(!loader || loader->frameLoader() == this);
1985
1986     if (m_provisionalDocumentLoader && m_provisionalDocumentLoader != m_documentLoader)
1987         m_provisionalDocumentLoader->detachFromFrame();
1988
1989     m_provisionalDocumentLoader = loader;
1990 }
1991
1992 void FrameLoader::setState(FrameState newState)
1993 {
1994     FrameState oldState = m_state;
1995     m_state = newState;
1996     
1997     if (newState == FrameStateProvisional)
1998         provisionalLoadStarted();
1999     else if (newState == FrameStateComplete) {
2000         frameLoadCompleted();
2001         if (m_documentLoader)
2002             m_documentLoader->stopRecordingResponses();
2003         if (m_frame.isMainFrame() && oldState != newState) {
2004             FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "setState: main frame load completed");
2005             m_frame.page()->performanceLogging().didReachPointOfInterest(PerformanceLogging::MainFrameLoadCompleted);
2006         }
2007     }
2008 }
2009
2010 void FrameLoader::clearProvisionalLoad()
2011 {
2012     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "clearProvisionalLoad: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
2013     setProvisionalDocumentLoader(nullptr);
2014     m_progressTracker->progressCompleted();
2015     setState(FrameStateComplete);
2016 }
2017
2018 void FrameLoader::commitProvisionalLoad()
2019 {
2020     RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
2021     Ref<Frame> protect(m_frame);
2022
2023     std::unique_ptr<CachedPage> cachedPage;
2024     if (m_loadingFromCachedPage && history().provisionalItem())
2025         cachedPage = BackForwardCache::singleton().take(*history().provisionalItem(), m_frame.page());
2026
2027     LOG(BackForwardCache, "WebCoreLoading %s: About to commit provisional load from previous URL '%s' to new URL '%s' with cached page %p", m_frame.tree().uniqueName().string().utf8().data(),
2028         m_frame.document() ? m_frame.document()->url().stringCenterEllipsizedToLength().utf8().data() : "",
2029         pdl ? pdl->url().stringCenterEllipsizedToLength().utf8().data() : "<no provisional DocumentLoader>", cachedPage.get());
2030
2031     willTransitionToCommitted();
2032
2033     if (!m_frame.tree().parent() && history().currentItem() && history().currentItem() != history().provisionalItem()) {
2034         // Check to see if we need to cache the page we are navigating away from into the back/forward cache.
2035         // We are doing this here because we know for sure that a new page is about to be loaded.
2036         BackForwardCache::singleton().addIfCacheable(*history().currentItem(), m_frame.page());
2037         
2038         WebCore::jettisonExpensiveObjectsOnTopLevelNavigation();
2039     }
2040
2041     if (m_loadType != FrameLoadType::Replace)
2042         closeOldDataSources();
2043
2044     if (!cachedPage && !m_stateMachine.creatingInitialEmptyDocument())
2045         m_client->makeRepresentation(pdl.get());
2046
2047     transitionToCommitted(cachedPage.get());
2048
2049     if (pdl && m_documentLoader) {
2050         // Check if the destination page is allowed to access the previous page's timing information.
2051         Ref<SecurityOrigin> securityOrigin(SecurityOrigin::create(pdl->request().url()));
2052         m_documentLoader->timing().setHasSameOriginAsPreviousDocument(securityOrigin.get().canRequest(m_previousURL));
2053     }
2054
2055     // Call clientRedirectCancelledOrFinished() here so that the frame load delegate is notified that the redirect's
2056     // status has changed, if there was a redirect.  The frame load delegate may have saved some state about
2057     // the redirect in its -webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:.  Since we are
2058     // just about to commit a new page, there cannot possibly be a pending redirect at this point.
2059     if (m_sentRedirectNotification)
2060         clientRedirectCancelledOrFinished(NewLoadInProgress::No);
2061     
2062     if (cachedPage && cachedPage->document()) {
2063 #if PLATFORM(IOS_FAMILY)
2064         // FIXME: CachedPage::restore() would dispatch viewport change notification. However UIKit expects load
2065         // commit to happen before any changes to viewport arguments and dealing with this there is difficult.
2066         m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(true);
2067 #endif
2068         willRestoreFromCachedPage();
2069
2070         // Start request for the main resource and dispatch didReceiveResponse before the load is committed for
2071         // consistency with all other loads. See https://bugs.webkit.org/show_bug.cgi?id=150927.
2072         ResourceError mainResouceError;
2073         unsigned long mainResourceIdentifier;
2074         ResourceRequest mainResourceRequest(cachedPage->documentLoader()->request());
2075         requestFromDelegate(mainResourceRequest, mainResourceIdentifier, mainResouceError);
2076         notifier().dispatchDidReceiveResponse(cachedPage->documentLoader(), mainResourceIdentifier, cachedPage->documentLoader()->response());
2077
2078         Optional<HasInsecureContent> hasInsecureContent = cachedPage->cachedMainFrame()->hasInsecureContent();
2079         Optional<UsedLegacyTLS> usedLegacyTLS = cachedPage->cachedMainFrame()->usedLegacyTLS();
2080
2081         dispatchDidCommitLoad(hasInsecureContent, usedLegacyTLS);
2082
2083         // FIXME: This API should be turned around so that we ground CachedPage into the Page.
2084         cachedPage->restore(*m_frame.page());
2085
2086 #if PLATFORM(IOS_FAMILY)
2087         m_frame.page()->chrome().setDispatchViewportDataDidChangeSuppressed(false);
2088         m_frame.page()->chrome().dispatchViewportPropertiesDidChange(m_frame.page()->viewportArguments());
2089 #endif
2090         m_frame.page()->chrome().dispatchDisabledAdaptationsDidChange(m_frame.page()->disabledAdaptations());
2091
2092         auto& title = m_documentLoader->title();
2093         if (!title.string.isNull())
2094             m_client->dispatchDidReceiveTitle(title);
2095
2096         // Send remaining notifications for the main resource.
2097         notifier().sendRemainingDelegateMessages(m_documentLoader.get(), mainResourceIdentifier, mainResourceRequest, ResourceResponse(),
2098             nullptr, static_cast<int>(m_documentLoader->response().expectedContentLength()), 0, mainResouceError);
2099
2100         checkCompleted();
2101     } else
2102         didOpenURL();
2103
2104     LOG(Loading, "WebCoreLoading %s: Finished committing provisional load to URL %s", m_frame.tree().uniqueName().string().utf8().data(),
2105         m_frame.document() ? m_frame.document()->url().stringCenterEllipsizedToLength().utf8().data() : "");
2106
2107     if (m_loadType == FrameLoadType::Standard && m_documentLoader && m_documentLoader->isClientRedirect())
2108         history().updateForClientRedirect();
2109
2110     if (m_loadingFromCachedPage) {
2111         // Note, didReceiveDocType is expected to be called for cached pages. See <rdar://problem/5906758> for more details.
2112         if (auto* page = m_frame.page())
2113             page->chrome().didReceiveDocType(m_frame);
2114         m_frame.document()->resume(ReasonForSuspension::BackForwardCache);
2115
2116         // Force a layout to update view size and thereby update scrollbars.
2117 #if PLATFORM(IOS_FAMILY)
2118         if (!m_client->forceLayoutOnRestoreFromBackForwardCache())
2119             m_frame.view()->forceLayout();
2120 #else
2121         m_frame.view()->forceLayout();
2122 #endif
2123
2124         // Main resource delegates were already sent, so we skip the first response here.
2125         for (unsigned i = 1; i < m_documentLoader->responses().size(); ++i) {
2126             const auto& response = m_documentLoader->responses()[i];
2127             // FIXME: If the WebKit client changes or cancels the request, this is not respected.
2128             ResourceError error;
2129             unsigned long identifier;
2130             ResourceRequest request(response.url());
2131             requestFromDelegate(request, identifier, error);
2132             // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
2133             // However, with today's computers and networking speeds, this won't happen in practice.
2134             // Could be an issue with a giant local file.
2135             notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, response, 0, static_cast<int>(response.expectedContentLength()), 0, error);
2136         }
2137
2138         // FIXME: Why only this frame and not parent frames?
2139         checkLoadCompleteForThisFrame();
2140     }
2141 }
2142
2143 void FrameLoader::transitionToCommitted(CachedPage* cachedPage)
2144 {
2145     ASSERT(m_client->hasWebView());
2146     ASSERT(m_state == FrameStateProvisional);
2147
2148     if (m_state != FrameStateProvisional)
2149         return;
2150
2151     if (FrameView* view = m_frame.view()) {
2152         if (ScrollAnimator* scrollAnimator = view->existingScrollAnimator())
2153             scrollAnimator->cancelAnimations();
2154     }
2155
2156     m_client->setCopiesOnScroll();
2157     history().updateForCommit();
2158
2159     // The call to closeURL() invokes the unload event handler, which can execute arbitrary
2160     // JavaScript. If the script initiates a new load, we need to abandon the current load,
2161     // or the two will stomp each other.
2162     DocumentLoader* pdl = m_provisionalDocumentLoader.get();
2163     if (m_documentLoader)
2164         closeURL();
2165     if (pdl != m_provisionalDocumentLoader)
2166         return;
2167
2168     if (m_documentLoader)
2169         m_documentLoader->stopLoadingSubresources();
2170     if (m_documentLoader)
2171         m_documentLoader->stopLoadingPlugIns();
2172
2173     // Setting our document loader invokes the unload event handler of our child frames.
2174     // Script can do anything. If the script initiates a new load, we need to abandon the
2175     // current load or the two will stomp each other.
2176     setDocumentLoader(m_provisionalDocumentLoader.get());
2177     if (pdl != m_provisionalDocumentLoader)
2178         return;
2179     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "transitionToCommitted: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
2180     setProvisionalDocumentLoader(nullptr);
2181
2182     // Nothing else can interrupt this commit - set the Provisional->Committed transition in stone
2183     setState(FrameStateCommittedPage);
2184
2185     // Handle adding the URL to the back/forward list.
2186     DocumentLoader* dl = m_documentLoader.get();
2187
2188     switch (m_loadType) {
2189     case FrameLoadType::Forward:
2190     case FrameLoadType::Back:
2191     case FrameLoadType::IndexedBackForward:
2192         if (m_frame.page()) {
2193             // If the first load within a frame is a navigation within a back/forward list that was attached
2194             // without any of the items being loaded then we need to update the history in a similar manner as
2195             // for a standard load with the exception of updating the back/forward list (<rdar://problem/8091103>).
2196             if (!m_stateMachine.committedFirstRealDocumentLoad() && m_frame.isMainFrame())
2197                 history().updateForStandardLoad(HistoryController::UpdateAllExceptBackForwardList);
2198
2199             history().updateForBackForwardNavigation();
2200
2201             // For cached pages, CachedFrame::restore will take care of firing the popstate event with the history item's state object
2202             if (history().currentItem() && !cachedPage)
2203                 m_pendingStateObject = history().currentItem()->stateObject();
2204
2205             // Create a document view for this document, or used the cached view.
2206             if (cachedPage) {
2207                 DocumentLoader* cachedDocumentLoader = cachedPage->documentLoader();
2208                 ASSERT(cachedDocumentLoader);
2209                 cachedDocumentLoader->attachToFrame(m_frame);
2210                 m_client->transitionToCommittedFromCachedFrame(cachedPage->cachedMainFrame());
2211             } else
2212                 m_client->transitionToCommittedForNewPage();
2213         }
2214         break;
2215
2216     case FrameLoadType::Reload:
2217     case FrameLoadType::ReloadFromOrigin:
2218     case FrameLoadType::ReloadExpiredOnly:
2219     case FrameLoadType::Same:
2220     case FrameLoadType::Replace:
2221         history().updateForReload();
2222         m_client->transitionToCommittedForNewPage();
2223         break;
2224
2225     case FrameLoadType::Standard:
2226         history().updateForStandardLoad();
2227         if (m_frame.view())
2228             m_frame.view()->setScrollbarsSuppressed(true);
2229         m_client->transitionToCommittedForNewPage();
2230         break;
2231
2232     case FrameLoadType::RedirectWithLockedBackForwardList:
2233         history().updateForRedirectWithLockedBackForwardList();
2234         m_client->transitionToCommittedForNewPage();
2235         break;
2236     }
2237
2238     m_documentLoader->writer().setMIMEType(dl->responseMIMEType());
2239
2240     // Tell the client we've committed this URL.
2241     ASSERT(m_frame.view());
2242
2243     if (m_stateMachine.creatingInitialEmptyDocument())
2244         return;
2245
2246     if (!m_stateMachine.committedFirstRealDocumentLoad())
2247         m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocumentPostCommit);
2248 }
2249
2250 void FrameLoader::clientRedirectCancelledOrFinished(NewLoadInProgress newLoadInProgress)
2251 {
2252     // Note that -webView:didCancelClientRedirectForFrame: is called on the frame load delegate even if
2253     // the redirect succeeded.  We should either rename this API, or add a new method, like
2254     // -webView:didFinishClientRedirectForFrame:
2255     m_client->dispatchDidCancelClientRedirect();
2256
2257     if (newLoadInProgress == NewLoadInProgress::No)
2258         m_quickRedirectComing = false;
2259
2260     m_sentRedirectNotification = false;
2261 }
2262
2263 void FrameLoader::clientRedirected(const URL& url, double seconds, WallTime fireDate, LockBackForwardList lockBackForwardList)
2264 {
2265     m_client->dispatchWillPerformClientRedirect(url, seconds, fireDate, lockBackForwardList);
2266     
2267     // Remember that we sent a redirect notification to the frame load delegate so that when we commit
2268     // the next provisional load, we can send a corresponding -webView:didCancelClientRedirectForFrame:
2269     m_sentRedirectNotification = true;
2270     
2271     // If a "quick" redirect comes in, we set a special mode so we treat the next
2272     // load as part of the original navigation. If we don't have a document loader, we have
2273     // no "original" load on which to base a redirect, so we treat the redirect as a normal load.
2274     // Loads triggered by JavaScript form submissions never count as quick redirects.
2275     m_quickRedirectComing = (lockBackForwardList == LockBackForwardList::Yes || history().currentItemShouldBeReplaced()) && m_documentLoader && !m_isExecutingJavaScriptFormAction;
2276 }
2277
2278 bool FrameLoader::shouldReload(const URL& currentURL, const URL& destinationURL)
2279 {
2280     // This function implements the rule: "Don't reload if navigating by fragment within
2281     // the same URL, but do reload if going to a new URL or to the same URL with no
2282     // fragment identifier at all."
2283     if (!destinationURL.hasFragmentIdentifier())
2284         return true;
2285     return !equalIgnoringFragmentIdentifier(currentURL, destinationURL);
2286 }
2287
2288 void FrameLoader::closeOldDataSources()
2289 {
2290     // FIXME: Is it important for this traversal to be postorder instead of preorder?
2291     // If so, add helpers for postorder traversal, and use them. If not, then lets not
2292     // use a recursive algorithm here.
2293     for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().nextSibling())
2294         child->loader().closeOldDataSources();
2295     
2296     if (m_documentLoader)
2297         m_client->dispatchWillClose();
2298
2299     m_client->setMainFrameDocumentReady(false); // stop giving out the actual DOMDocument to observers
2300 }
2301
2302 void FrameLoader::willRestoreFromCachedPage()
2303 {
2304     ASSERT(!m_frame.tree().parent());
2305     ASSERT(m_frame.page());
2306     ASSERT(m_frame.isMainFrame());
2307
2308     m_frame.navigationScheduler().cancel();
2309
2310     // We still have to close the previous part page.
2311     closeURL();
2312     
2313     // Delete old status bar messages (if it _was_ activated on last URL).
2314     if (m_frame.script().canExecuteScripts(NotAboutToExecuteScript)) {
2315         DOMWindow* window = m_frame.document()->domWindow();
2316         window->setStatus(String());
2317         window->setDefaultStatus(String());
2318     }
2319 }
2320
2321 void FrameLoader::open(CachedFrameBase& cachedFrame)
2322 {
2323     m_isComplete = false;
2324     
2325     // Don't re-emit the load event.
2326     m_didCallImplicitClose = true;
2327
2328     URL url = cachedFrame.url();
2329
2330     // FIXME: I suspect this block of code doesn't do anything.
2331     if (url.protocolIsInHTTPFamily() && !url.host().isEmpty() && url.path().isEmpty())
2332         url.setPath("/");
2333
2334     started();
2335     auto document = makeRef(*cachedFrame.document());
2336     ASSERT(document->domWindow());
2337
2338     clear(document.ptr(), true, true, cachedFrame.isMainFrame());
2339
2340     document->attachToCachedFrame(cachedFrame);
2341     document->setBackForwardCacheState(Document::NotInBackForwardCache);
2342
2343     m_needsClear = true;
2344     m_isComplete = false;
2345     m_didCallImplicitClose = false;
2346     setOutgoingReferrer(url);
2347
2348     FrameView* view = cachedFrame.view();
2349     
2350     // When navigating to a CachedFrame its FrameView should never be null.  If it is we'll crash in creative ways downstream.
2351     ASSERT(view);
2352     view->setWasScrolledByUser(false);
2353
2354     Optional<IntRect> previousViewFrameRect = m_frame.view() ?  m_frame.view()->frameRect() : Optional<IntRect>(WTF::nullopt);
2355     m_frame.setView(view);
2356
2357     // Use the previous ScrollView's frame rect.
2358     if (previousViewFrameRect)
2359         view->setFrameRect(previousViewFrameRect.value());
2360
2361
2362     // Setting the document builds the render tree and runs post style resolution callbacks that can do anything,
2363     // including loading a child frame before its been re-attached to the frame tree as part of this restore.
2364     // For example, the HTML object element may load its content into a frame in a post style resolution callback.
2365     Style::PostResolutionCallbackDisabler disabler(document.get());
2366     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
2367     NavigationDisabler disableNavigation { &m_frame };
2368     
2369     m_frame.setDocument(document.copyRef());
2370
2371     document->domWindow()->resumeFromBackForwardCache();
2372
2373     updateFirstPartyForCookies();
2374
2375     cachedFrame.restore();
2376 }
2377
2378 bool FrameLoader::isHostedByObjectElement() const
2379 {
2380     HTMLFrameOwnerElement* owner = m_frame.ownerElement();
2381     return owner && owner->hasTagName(objectTag);
2382 }
2383
2384 bool FrameLoader::isReplacing() const
2385 {
2386     return m_loadType == FrameLoadType::Replace;
2387 }
2388
2389 void FrameLoader::setReplacing()
2390 {
2391     m_loadType = FrameLoadType::Replace;
2392 }
2393
2394 bool FrameLoader::subframeIsLoading() const
2395 {
2396     // It's most likely that the last added frame is the last to load so we walk backwards.
2397     for (Frame* child = m_frame.tree().lastChild(); child; child = child->tree().previousSibling()) {
2398         FrameLoader& childLoader = child->loader();
2399         DocumentLoader* documentLoader = childLoader.documentLoader();
2400         if (documentLoader && documentLoader->isLoadingInAPISense())
2401             return true;
2402         documentLoader = childLoader.provisionalDocumentLoader();
2403         if (documentLoader && documentLoader->isLoadingInAPISense())
2404             return true;
2405         documentLoader = childLoader.policyDocumentLoader();
2406         if (documentLoader)
2407             return true;
2408     }
2409     return false;
2410 }
2411
2412 void FrameLoader::willChangeTitle(DocumentLoader* loader)
2413 {
2414     m_client->willChangeTitle(loader);
2415 }
2416
2417 FrameLoadType FrameLoader::loadType() const
2418 {
2419     return m_loadType;
2420 }
2421     
2422 CachePolicy FrameLoader::subresourceCachePolicy(const URL& url) const
2423 {
2424     if (Page* page = m_frame.page()) {
2425         if (page->isResourceCachingDisabledByWebInspector())
2426             return CachePolicyReload;
2427     }
2428
2429     if (m_isComplete)
2430         return CachePolicyVerify;
2431
2432     if (m_loadType == FrameLoadType::ReloadFromOrigin)
2433         return CachePolicyReload;
2434
2435     if (Frame* parentFrame = m_frame.tree().parent()) {
2436         CachePolicy parentCachePolicy = parentFrame->loader().subresourceCachePolicy(url);
2437         if (parentCachePolicy != CachePolicyVerify)
2438             return parentCachePolicy;
2439     }
2440     
2441     switch (m_loadType) {
2442     case FrameLoadType::Reload:
2443         return CachePolicyRevalidate;
2444     case FrameLoadType::Back:
2445     case FrameLoadType::Forward:
2446     case FrameLoadType::IndexedBackForward:
2447         return CachePolicyHistoryBuffer;
2448     case FrameLoadType::ReloadFromOrigin:
2449         ASSERT_NOT_REACHED(); // Already handled above.
2450         return CachePolicyReload;
2451     case FrameLoadType::RedirectWithLockedBackForwardList:
2452     case FrameLoadType::Replace:
2453     case FrameLoadType::Same:
2454     case FrameLoadType::Standard:
2455         return CachePolicyVerify;
2456     case FrameLoadType::ReloadExpiredOnly:
2457         // We know about expiration for HTTP and data. Do a normal reload otherwise.
2458         if (!url.protocolIsInHTTPFamily() && !url.protocolIsData())
2459             return CachePolicyReload;
2460         return CachePolicyVerify;
2461     }
2462
2463     RELEASE_ASSERT_NOT_REACHED();
2464     return CachePolicyVerify;
2465 }
2466
2467 void FrameLoader::dispatchDidFailProvisionalLoad(DocumentLoader& provisionalDocumentLoader, const ResourceError& error)
2468 {
2469     m_provisionalLoadErrorBeingHandledURL = provisionalDocumentLoader.url();
2470
2471 #if ENABLE(CONTENT_FILTERING)
2472     auto contentFilter = provisionalDocumentLoader.contentFilter();
2473     auto contentFilterWillContinueLoading = false;
2474 #endif
2475
2476     auto willContinueLoading = WillContinueLoading::No;
2477     if (history().provisionalItem())
2478         willContinueLoading = WillContinueLoading::Yes;
2479 #if ENABLE(CONTENT_FILTERING)
2480     if (contentFilter && contentFilter->willHandleProvisionalLoadFailure(error)) {
2481         willContinueLoading = WillContinueLoading::Yes;
2482         contentFilterWillContinueLoading = true;
2483     }
2484 #endif
2485
2486     m_client->dispatchDidFailProvisionalLoad(error, willContinueLoading);
2487
2488 #if ENABLE(CONTENT_FILTERING)
2489     if (contentFilterWillContinueLoading)
2490         contentFilter->handleProvisionalLoadFailure(error);
2491 #endif
2492
2493     m_provisionalLoadErrorBeingHandledURL = { };
2494 }
2495
2496 void FrameLoader::checkLoadCompleteForThisFrame()
2497 {
2498     ASSERT(m_client->hasWebView());
2499
2500     // FIXME: Should this check be done in checkLoadComplete instead of here?
2501     // FIXME: Why does this one check need to be repeated here, and not the many others from checkCompleted?
2502     if (m_frame.document()->isDelayingLoadEvent())
2503         return;
2504
2505     switch (m_state) {
2506         case FrameStateProvisional: {
2507             // FIXME: Prohibiting any provisional load failures from being sent to clients
2508             // while handling provisional load failures is too heavy. For example, the current
2509             // load will fail to cancel another ongoing load. That might prevent clients' page
2510             // load state being handled properly.
2511             if (!m_provisionalLoadErrorBeingHandledURL.isEmpty())
2512                 return;
2513
2514             RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
2515             if (!pdl)
2516                 return;
2517                 
2518             // If we've received any errors we may be stuck in the provisional state and actually complete.
2519             const ResourceError& error = pdl->mainDocumentError();
2520             if (error.isNull())
2521                 return;
2522
2523             // Check all children first.
2524             RefPtr<HistoryItem> item;
2525             if (Page* page = m_frame.page())
2526                 if (isBackForwardLoadType(loadType()))
2527                     // Reset the back forward list to the last committed history item at the top level.
2528                     item = page->mainFrame().loader().history().currentItem();
2529                 
2530             // Only reset if we aren't already going to a new provisional item.
2531             bool shouldReset = !history().provisionalItem();
2532             if (!pdl->isLoadingInAPISense() || pdl->isStopping()) {
2533                 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "checkLoadCompleteForThisFrame: Failed provisional load (isTimeout = %d, isCancellation = %d, errorCode = %d)", error.isTimeout(), error.isCancellation(), error.errorCode());
2534
2535                 dispatchDidFailProvisionalLoad(*pdl, error);
2536                 ASSERT(!pdl->isLoading());
2537
2538                 // If we're in the middle of loading multipart data, we need to restore the document loader.
2539                 if (isReplacing() && !m_documentLoader.get())
2540                     setDocumentLoader(m_provisionalDocumentLoader.get());
2541
2542                 // Finish resetting the load state, but only if another load hasn't been started by the
2543                 // delegate callback.
2544                 if (pdl == m_provisionalDocumentLoader)
2545                     clearProvisionalLoad();
2546                 else if (activeDocumentLoader()) {
2547                     URL unreachableURL = activeDocumentLoader()->unreachableURL();
2548                     if (!unreachableURL.isEmpty() && unreachableURL == pdl->request().url())
2549                         shouldReset = false;
2550                 }
2551             }
2552             if (shouldReset && item)
2553                 if (Page* page = m_frame.page()) {
2554                     page->backForward().setCurrentItem(*item);
2555                 }
2556             return;
2557         }
2558         
2559         case FrameStateCommittedPage: {
2560             if (!m_documentLoader)
2561                 return;
2562             if (m_documentLoader->isLoadingInAPISense() && !m_documentLoader->isStopping() && !m_checkingLoadCompleteForDetachment)
2563                 return;
2564
2565             setState(FrameStateComplete);
2566
2567             // FIXME: Is this subsequent work important if we already navigated away?
2568             // Maybe there are bugs because of that, or extra work we can skip because
2569             // the new page is ready.
2570
2571             m_client->forceLayoutForNonHTML();
2572              
2573             // If the user had a scroll point, scroll to it, overriding the anchor point if any.
2574             if (m_frame.page()) {
2575                 if (isBackForwardLoadType(m_loadType) || isReload(m_loadType))
2576                     history().restoreScrollPositionAndViewState();
2577             }
2578
2579             if (m_stateMachine.creatingInitialEmptyDocument() || !m_stateMachine.committedFirstRealDocumentLoad())
2580                 return;
2581
2582             m_progressTracker->progressCompleted();
2583             Page* page = m_frame.page();
2584             if (page) {
2585                 if (m_frame.isMainFrame()) {
2586                     tracePoint(MainResourceLoadDidEnd);
2587                     page->didFinishLoad();
2588                 }
2589             }
2590
2591             const ResourceError& error = m_documentLoader->mainDocumentError();
2592
2593             AXObjectCache::AXLoadingEvent loadingEvent;
2594             if (!error.isNull()) {
2595                 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "checkLoadCompleteForThisFrame: Finished frame load with error (isTimeout = %d, isCancellation = %d, errorCode = %d)", error.isTimeout(), error.isCancellation(), error.errorCode());
2596                 m_client->dispatchDidFailLoad(error);
2597                 loadingEvent = AXObjectCache::AXLoadingFailed;
2598             } else {
2599                 FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "checkLoadCompleteForThisFrame: Finished frame load");
2600 #if ENABLE(DATA_DETECTION)
2601                 auto* document = m_frame.document();
2602                 if (m_frame.settings().dataDetectorTypes() != DataDetectorTypeNone && document) {
2603                     if (auto* documentElement = document->documentElement()) {
2604                         RefPtr<Range> documentRange = makeRange(firstPositionInNode(documentElement), lastPositionInNode(documentElement));
2605                         m_frame.setDataDetectionResults(DataDetection::detectContentInRange(documentRange, m_frame.settings().dataDetectorTypes(), m_client->dataDetectionContext()));
2606                         if (m_frame.isMainFrame())
2607                             m_client->dispatchDidFinishDataDetection(m_frame.dataDetectionResults());
2608                     }
2609                 }
2610 #endif
2611                 m_client->dispatchDidFinishLoad();
2612                 loadingEvent = AXObjectCache::AXLoadingFinished;
2613             }
2614
2615             // Notify accessibility.
2616             if (auto* document = m_frame.document()) {
2617                 if (AXObjectCache* cache = document->existingAXObjectCache())
2618                     cache->frameLoadingEventNotification(&m_frame, loadingEvent);
2619             }
2620
2621             // The above calls to dispatchDidFinishLoad() might have detached the Frame
2622             // from its Page and also might have caused Page to be deleted.
2623             // Don't assume 'page' is still available to use.
2624             if (m_frame.isMainFrame() && m_frame.page()) {
2625                 ASSERT(&m_frame.page()->mainFrame() == &m_frame);
2626                 m_frame.page()->diagnosticLoggingClient().logDiagnosticMessageWithResult(DiagnosticLoggingKeys::pageLoadedKey(), emptyString(), error.isNull() ? DiagnosticLoggingResultPass : DiagnosticLoggingResultFail, ShouldSample::Yes);
2627             }
2628
2629             return;
2630         }
2631         
2632         case FrameStateComplete:
2633             m_loadType = FrameLoadType::Standard;
2634             frameLoadCompleted();
2635             return;
2636     }
2637
2638     ASSERT_NOT_REACHED();
2639 }
2640
2641 void FrameLoader::setOriginalURLForDownloadRequest(ResourceRequest& request)
2642 {
2643     // FIXME: Rename firstPartyForCookies back to mainDocumentURL. It was a mistake to think that it was only used for cookies.
2644     // The originalURL is defined as the URL of the page where the download was initiated.
2645     URL originalURL;
2646     auto* initiator = m_frame.document();
2647     if (initiator) {
2648         originalURL = initiator->firstPartyForCookies();
2649         // If there is no main document URL, it means that this document is newly opened and just for download purpose.
2650         // In this case, we need to set the originalURL to this document's opener's main document URL.
2651         if (originalURL.isEmpty() && opener() && opener()->document()) {
2652             originalURL = opener()->document()->firstPartyForCookies();
2653             initiator = opener()->document();
2654         }
2655     }
2656     // If the originalURL is the same as the requested URL, we are processing a download
2657     // initiated directly without a page and do not need to specify the originalURL.
2658     if (originalURL == request.url())
2659         request.setFirstPartyForCookies(URL());
2660     else
2661         request.setFirstPartyForCookies(originalURL);
2662     addSameSiteInfoToRequestIfNeeded(request, initiator);
2663 }
2664
2665 void FrameLoader::didReachLayoutMilestone(OptionSet<LayoutMilestone> milestones)
2666 {
2667     ASSERT(m_frame.isMainFrame());
2668
2669     m_client->dispatchDidReachLayoutMilestone(milestones);
2670 }
2671
2672 void FrameLoader::didFirstLayout()
2673 {
2674 #if PLATFORM(IOS_FAMILY)
2675     // Only send layout-related delegate callbacks synchronously for the main frame to
2676     // avoid reentering layout for the main frame while delivering a layout-related delegate
2677     // callback for a subframe.
2678     if (&m_frame != &m_frame.page()->mainFrame())
2679         return;
2680 #endif
2681     if (m_frame.page() && isBackForwardLoadType(m_loadType))
2682         history().restoreScrollPositionAndViewState();
2683
2684     if (m_stateMachine.committedFirstRealDocumentLoad() && !m_stateMachine.isDisplayingInitialEmptyDocument() && !m_stateMachine.firstLayoutDone())
2685         m_stateMachine.advanceTo(FrameLoaderStateMachine::FirstLayoutDone);
2686 }
2687
2688 void FrameLoader::didReachVisuallyNonEmptyState()
2689 {
2690     ASSERT(m_frame.isMainFrame());
2691     m_client->dispatchDidReachVisuallyNonEmptyState();
2692 }
2693
2694 void FrameLoader::frameLoadCompleted()
2695 {
2696     // Note: Can be called multiple times.
2697
2698     m_client->frameLoadCompleted();
2699
2700     history().updateForFrameLoadCompleted();
2701
2702     // After a canceled provisional load, firstLayoutDone is false.
2703     // Reset it to true if we're displaying a page.
2704     if (m_documentLoader && m_stateMachine.committedFirstRealDocumentLoad() && !m_stateMachine.isDisplayingInitialEmptyDocument() && !m_stateMachine.firstLayoutDone())
2705         m_stateMachine.advanceTo(FrameLoaderStateMachine::FirstLayoutDone);
2706 }
2707
2708 void FrameLoader::detachChildren()
2709 {
2710     // detachChildren() will fire the unload event in each subframe and the
2711     // HTML specification states that the parent document's ignore-opens-during-unload counter while
2712     // this event is being fired in its subframes:
2713     // https://html.spec.whatwg.org/multipage/browsers.html#unload-a-document
2714     IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
2715
2716     // detachChildren() will fire the unload event in each subframe and the
2717     // HTML specification states that navigations should be prevented during the prompt to unload algorithm:
2718     // https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate
2719     std::unique_ptr<NavigationDisabler> navigationDisabler;
2720     if (m_frame.isMainFrame())
2721         navigationDisabler = makeUnique<NavigationDisabler>(&m_frame);
2722
2723     // Any subframe inserted by unload event handlers executed in the loop below will not get unloaded
2724     // because we create a copy of the subframes list before looping. Therefore, it would be unsafe to
2725     // allow loading of subframes at this point.
2726     SubframeLoadingDisabler subframeLoadingDisabler(m_frame.document());
2727
2728     Vector<Ref<Frame>, 16> childrenToDetach;
2729     childrenToDetach.reserveInitialCapacity(m_frame.tree().childCount());
2730     for (Frame* child = m_frame.tree().lastChild(); child; child = child->tree().previousSibling())
2731         childrenToDetach.uncheckedAppend(*child);
2732     for (auto& child : childrenToDetach)
2733         child->loader().detachFromParent();
2734 }
2735
2736 void FrameLoader::closeAndRemoveChild(Frame& child)
2737 {
2738     child.tree().detachFromParent();
2739
2740     child.setView(nullptr);
2741     if (child.ownerElement() && child.page())
2742         child.page()->decrementSubframeCount();
2743     child.willDetachPage();
2744     child.detachFromPage();
2745
2746     m_frame.tree().removeChild(child);
2747 }
2748
2749 // Called every time a resource is completely loaded or an error is received.
2750 void FrameLoader::checkLoadComplete()
2751 {
2752     m_shouldCallCheckLoadComplete = false;
2753
2754     if (!m_frame.page())
2755         return;
2756
2757     ASSERT(m_client->hasWebView());
2758     
2759     // FIXME: Always traversing the entire frame tree is a bit inefficient, but 
2760     // is currently needed in order to null out the previous history item for all frames.
2761     Vector<Ref<Frame>, 16> frames;
2762     for (Frame* frame = &m_frame.mainFrame(); frame; frame = frame->tree().traverseNext())
2763         frames.append(*frame);
2764
2765     // To process children before their parents, iterate the vector backwards.
2766     for (auto frame = frames.rbegin(); frame != frames.rend(); ++frame) {
2767         if ((*frame)->page())
2768             (*frame)->loader().checkLoadCompleteForThisFrame();
2769     }
2770 }
2771
2772 int FrameLoader::numPendingOrLoadingRequests(bool recurse) const
2773 {
2774     if (!recurse)
2775         return m_frame.document()->cachedResourceLoader().requestCount();
2776
2777     int count = 0;
2778     for (Frame* frame = &m_frame; frame; frame = frame->tree().traverseNext(&m_frame))
2779         count += frame->document()->cachedResourceLoader().requestCount();
2780     return count;
2781 }
2782
2783 String FrameLoader::userAgent(const URL& url) const
2784 {
2785     String userAgent;
2786
2787     if (auto* documentLoader = m_frame.mainFrame().loader().activeDocumentLoader()) {
2788         if (m_frame.settings().needsSiteSpecificQuirks())
2789             userAgent = documentLoader->customUserAgentAsSiteSpecificQuirks();
2790         if (userAgent.isEmpty())
2791             userAgent = documentLoader->customUserAgent();
2792     }
2793
2794     InspectorInstrumentation::applyUserAgentOverride(m_frame, userAgent);
2795
2796     if (!userAgent.isEmpty())
2797         return userAgent;
2798
2799     return m_client->userAgent(url);
2800 }
2801
2802 String FrameLoader::navigatorPlatform() const
2803 {
2804     if (auto* documentLoader = m_frame.mainFrame().loader().activeDocumentLoader()) {
2805         auto& customNavigatorPlatform = documentLoader->customNavigatorPlatform();
2806         if (!customNavigatorPlatform.isEmpty())
2807             return customNavigatorPlatform;
2808     }
2809     return String();
2810 }
2811
2812 void FrameLoader::dispatchOnloadEvents()
2813 {
2814     m_client->dispatchDidDispatchOnloadEvents();
2815
2816     if (documentLoader())
2817         documentLoader()->dispatchOnloadEvents();
2818 }
2819
2820 void FrameLoader::frameDetached()
2821 {
2822     // Calling stopAllLoadersAndCheckCompleteness() can cause the frame to be deallocated, including the frame loader.
2823     Ref<Frame> protectedFrame(m_frame);
2824
2825     if (m_checkTimer.isActive()) {
2826         m_checkTimer.stop();
2827         checkCompletenessNow();
2828     }
2829
2830     if (m_frame.document()->backForwardCacheState() != Document::InBackForwardCache) {
2831         stopAllLoadersAndCheckCompleteness();
2832         m_frame.document()->stopActiveDOMObjects();
2833     }
2834
2835     detachFromParent();
2836 }
2837
2838 void FrameLoader::detachFromParent()
2839 {
2840     // Calling stopAllLoaders() can cause the frame to be deallocated, including the frame loader.
2841     Ref<Frame> protect(m_frame);
2842
2843     closeURL();
2844     history().saveScrollPositionAndViewStateToItem(history().currentItem());
2845     detachChildren();
2846     if (m_frame.document()->backForwardCacheState() != Document::InBackForwardCache) {
2847         // stopAllLoaders() needs to be called after detachChildren() if the document is not in the back/forward cache,
2848         // because detachedChildren() will trigger the unload event handlers of any child frames, and those event
2849         // handlers might start a new subresource load in this frame.
2850         stopAllLoaders(ShouldClearProvisionalItem, StopLoadingPolicy::AlwaysStopLoading);
2851     }
2852
2853     InspectorInstrumentation::frameDetachedFromParent(m_frame);
2854
2855     detachViewsAndDocumentLoader();
2856
2857     m_progressTracker = nullptr;
2858
2859     if (Frame* parent = m_frame.tree().parent()) {
2860         parent->loader().closeAndRemoveChild(m_frame);
2861         parent->loader().scheduleCheckCompleted();
2862         parent->loader().scheduleCheckLoadComplete();
2863     } else {
2864         m_frame.setView(nullptr);
2865         m_frame.willDetachPage();
2866         m_frame.detachFromPage();
2867     }
2868 }
2869
2870 void FrameLoader::detachViewsAndDocumentLoader()
2871 {
2872     m_client->detachedFromParent2();
2873     setDocumentLoader(nullptr);
2874     m_client->detachedFromParent3();
2875 }
2876     
2877 void FrameLoader::addExtraFieldsToSubresourceRequest(ResourceRequest& request)
2878 {
2879     addExtraFieldsToRequest(request, m_loadType, false);
2880 }
2881
2882 void FrameLoader::addExtraFieldsToMainResourceRequest(ResourceRequest& request)
2883 {
2884     // FIXME: Using m_loadType seems wrong for some callers.
2885     // If we are only preparing to load the main resource, that is previous load's load type!
2886     addExtraFieldsToRequest(request, m_loadType, true);
2887
2888     // Upgrade-Insecure-Requests should only be added to main resource requests
2889     addHTTPUpgradeInsecureRequestsIfNeeded(request);
2890 }
2891
2892 ResourceRequestCachePolicy FrameLoader::defaultRequestCachingPolicy(const ResourceRequest& request, FrameLoadType loadType, bool isMainResource)
2893 {
2894     if (m_overrideCachePolicyForTesting)
2895         return m_overrideCachePolicyForTesting.value();
2896
2897     if (isMainResource) {
2898         if (isReload(loadType) || request.isConditional())
2899             return ResourceRequestCachePolicy::ReloadIgnoringCacheData;
2900
2901         return ResourceRequestCachePolicy::UseProtocolCachePolicy;
2902     }
2903
2904     if (request.isConditional())
2905         return ResourceRequestCachePolicy::ReloadIgnoringCacheData;
2906
2907     if (documentLoader()->isLoadingInAPISense()) {
2908         // If we inherit cache policy from a main resource, we use the DocumentLoader's
2909         // original request cache policy for two reasons:
2910         // 1. For POST requests, we mutate the cache policy for the main resource,
2911         //    but we do not want this to apply to subresources
2912         // 2. Delegates that modify the cache policy using willSendRequest: should
2913         //    not affect any other resources. Such changes need to be done
2914         //    per request.
2915         ResourceRequestCachePolicy mainDocumentOriginalCachePolicy = documentLoader()->originalRequest().cachePolicy();
2916         // Back-forward navigations try to load main resource from cache only to avoid re-submitting form data, and start over (with a warning dialog) if that fails.
2917         // This policy is set on initial request too, but should not be inherited.
2918         return (mainDocumentOriginalCachePolicy == ResourceRequestCachePolicy::ReturnCacheDataDontLoad) ? ResourceRequestCachePolicy::ReturnCacheDataElseLoad : mainDocumentOriginalCachePolicy;
2919     }
2920
2921     return ResourceRequestCachePolicy::UseProtocolCachePolicy;
2922 }
2923
2924 void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadType loadType, bool isMainResource)
2925 {
2926     // If the request came from a previous process due to process-swap-on-navigation then we should not modify the request.
2927     if (m_currentLoadContinuingState == LoadContinuingState::ContinuingWithRequest)
2928         return;
2929
2930     // Don't set the cookie policy URL if it's already been set.
2931     // But make sure to set it on all requests regardless of protocol, as it has significance beyond the cookie policy (<rdar://problem/6616664>).
2932     bool isMainFrameMainResource = isMainResource && m_frame.isMainFrame();
2933     if (request.firstPartyForCookies().isEmpty()) {
2934         if (isMainFrameMainResource)
2935             request.setFirstPartyForCookies(request.url());
2936         else if (Document* document = m_frame.document())
2937             request.setFirstPartyForCookies(document->firstPartyForCookies());
2938     }
2939
2940     if (request.isSameSiteUnspecified()) {
2941         auto* initiator = m_frame.document();
2942         if (isMainResource) {
2943             auto* ownerFrame = m_frame.tree().parent();
2944             if (!ownerFrame && m_stateMachine.isDisplayingInitialEmptyDocument())
2945                 ownerFrame = m_opener;
2946             if (ownerFrame)
2947                 initiator = ownerFrame->document();
2948             ASSERT(ownerFrame || m_frame.isMainFrame());
2949         }
2950         addSameSiteInfoToRequestIfNeeded(request, initiator);
2951     }
2952     request.setIsTopSite(isMainFrameMainResource);
2953
2954     Page* page = frame().page();
2955     bool hasSpecificCachePolicy = request.cachePolicy() != ResourceRequestCachePolicy::UseProtocolCachePolicy;
2956
2957     if (page && page->isResourceCachingDisabledByWebInspector()) {
2958         request.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
2959         loadType = FrameLoadType::ReloadFromOrigin;
2960     } else if (!hasSpecificCachePolicy)
2961         request.setCachePolicy(defaultRequestCachingPolicy(request, loadType, isMainResource));
2962
2963     // The remaining modifications are only necessary for HTTP and HTTPS.
2964     if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
2965         return;
2966
2967     if (!hasSpecificCachePolicy && request.cachePolicy() == ResourceRequestCachePolicy::ReloadIgnoringCacheData) {
2968         if (loadType == FrameLoadType::Reload)
2969             request.setHTTPHeaderField(HTTPHeaderName::CacheControl, HTTPHeaderValues::maxAge0());
2970         else if (loadType == FrameLoadType::ReloadFromOrigin) {
2971             request.setHTTPHeaderField(HTTPHeaderName::CacheControl, HTTPHeaderValues::noCache());
2972             request.setHTTPHeaderField(HTTPHeaderName::Pragma, HTTPHeaderValues::noCache());
2973         }
2974     }
2975
2976     if (m_overrideResourceLoadPriorityForTesting)
2977         request.setPriority(m_overrideResourceLoadPriorityForTesting.value());
2978
2979     applyUserAgentIfNeeded(request);
2980
2981     // Make sure we send the Origin header.
2982     addHTTPOriginIfNeeded(request, String());
2983
2984     // Only set fallback array if it's still empty (later attempts may be incorrect, see bug 117818).
2985     if (request.responseContentDispositionEncodingFallbackArray().isEmpty()) {
2986         // Always try UTF-8. If that fails, try frame encoding (if any) and then the default.
2987         request.setResponseContentDispositionEncodingFallbackArray("UTF-8", m_frame.document()->encoding(), m_frame.settings().defaultTextEncodingName());
2988     }
2989 }
2990
2991 void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, const String& origin)
2992 {
2993     if (!request.httpOrigin().isEmpty())
2994         return;  // Request already has an Origin header.
2995
2996     // Don't send an Origin header for GET or HEAD to avoid privacy issues.
2997     // For example, if an intranet page has a hyperlink to an external web
2998     // site, we don't want to include the Origin of the request because it
2999     // will leak the internal host name. Similar privacy concerns have lead
3000     // to the widespread suppression of the Referer header at the network
3001     // layer.
3002     if (request.httpMethod() == "GET" || request.httpMethod() == "HEAD")
3003         return;
3004
3005     // For non-GET and non-HEAD methods, always send an Origin header so the
3006     // server knows we support this feature.
3007
3008     if (origin.isEmpty()) {
3009         // If we don't know what origin header to attach, we attach the value
3010         // for an empty origin.
3011         request.setHTTPOrigin(SecurityOrigin::createUnique()->toString());
3012         return;
3013     }
3014
3015     request.setHTTPOrigin(origin);
3016 }
3017
3018 // Implements the "'Same-site' and 'cross-site' Requests" algorithm from <https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-2.1>.
3019 // The algorithm is ammended to treat URLs that inherit their security origin from their owner (e.g. about:blank)
3020 // as same-site. This matches the behavior of Chrome and Firefox.
3021 void FrameLoader::addSameSiteInfoToRequestIfNeeded(ResourceRequest& request, const Document* initiator)
3022 {
3023     if (!request.isSameSiteUnspecified())
3024         return;
3025     if (!initiator) {
3026         request.setIsSameSite(true);
3027         return;
3028     }
3029     if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(request.url())) {
3030         request.setIsSameSite(true);
3031         return;
3032     }
3033     request.setIsSameSite(areRegistrableDomainsEqual(initiator->siteForCookies(), request.url()));
3034 }
3035
3036 void FrameLoader::addHTTPUpgradeInsecureRequestsIfNeeded(ResourceRequest& request)
3037 {
3038     if (request.url().protocolIs("https")) {
3039         // FIXME: Identify HSTS cases and avoid adding the header. <https://bugs.webkit.org/show_bug.cgi?id=157885>
3040         return;
3041     }
3042
3043     request.setHTTPHeaderField(HTTPHeaderName::UpgradeInsecureRequests, "1"_s);
3044 }
3045
3046 void FrameLoader::loadPostRequest(FrameLoadRequest&& request, const String& referrer, FrameLoadType loadType, Event* event, RefPtr<FormState>&& formState, CompletionHandler<void()>&& completionHandler)
3047 {
3048     FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "loadPostRequest: frame load started");
3049
3050     String frameName = request.frameName();
3051     LockHistory lockHistory = request.lockHistory();
3052     AllowNavigationToInvalidURL allowNavigationToInvalidURL = request.allowNavigationToInvalidURL();
3053     NewFrameOpenerPolicy openerPolicy = request.newFrameOpenerPolicy();
3054
3055     const ResourceRequest& inRequest = request.resourceRequest();
3056     const URL& url = inRequest.url();
3057     const String& contentType = inRequest.httpContentType();
3058     String origin = inRequest.httpOrigin();
3059
3060     ResourceRequest workingResourceRequest(url);    
3061
3062     if (!referrer.isEmpty())
3063         workingResourceRequest.setHTTPReferrer(referrer);
3064     workingResourceRequest.setHTTPOrigin(origin);
3065     workingResourceRequest.setHTTPMethod("POST");
3066     workingResourceRequest.setHTTPBody(inRequest.httpBody());
3067     workingResourceRequest.setHTTPContentType(contentType);
3068     addExtraFieldsToRequest(workingResourceRequest, loadType, true);
3069
3070     if (Document* document = m_frame.document())
3071         document->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(workingResourceRequest, ContentSecurityPolicy::InsecureRequestType::Load);
3072
3073     NavigationAction action { request.requester(), workingResourceRequest, request.initiatedByMainFrame(), loadType, true, event, request.shouldOpenExternalURLsPolicy(), request.downloadAttribute() };
3074
3075     if (!frameName.isEmpty()) {
3076         // The search for a target frame is done earlier in the case of form submission.
3077         if (auto* targetFrame = formState ? nullptr : findFrameForNavigation(frameName)) {
3078             targetFrame->loader().loadWithNavigationAction(workingResourceRequest, WTFMove(action), lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, { }, WTFMove(completionHandler));
3079             return;
3080         }
3081
3082         policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(workingResourceRequest), WTFMove(formState), frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = WTFMove(completionHandler)] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, PolicyChecker::ShouldContinue shouldContinue) mutable {
3083             continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);
3084             completionHandler();
3085         });
3086         return;
3087     }
3088
3089     // must grab this now, since this load may stop the previous load and clear this flag
3090     bool isRedirect = m_quickRedirectComing;
3091     loadWithNavigationAction(workingResourceRequest, WTFMove(action), lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, { }, [this, isRedirect, protectedFrame = makeRef(m_frame), completionHandler = WTFMove(completionHandler)] () mutable {
3092         if (isRedirect) {
3093             m_quickRedirectComing = false;
3094             if (m_provisionalDocumentLoader)
3095                 m_provisionalDocumentLoader->setIsClientRedirect(true);
3096             else if (m_policyDocumentLoader)
3097                 m_policyDocumentLoader->setIsClientRedirect(true);
3098         }
3099         completionHandler();
3100     });
3101 }
3102
3103 unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& request, ClientCredentialPolicy clientCredentialPolicy, const FetchOptions& options, const HTTPHeaderMap& originalRequestHeaders, ResourceError& error, ResourceResponse& response, RefPtr<SharedBuffer>& data)
3104 {
3105     ASSERT(m_frame.document());
3106     String referrer = SecurityPolicy::generateReferrerHeader(m_frame.document()->referrerPolicy(), request.url(), outgoingReferrer());
3107     
3108     ResourceRequest initialRequest = request;
3109     initialRequest.setTimeoutInterval(10);
3110     
3111     if (!referrer.isEmpty())
3112         initialRequest.setHTTPReferrer(referrer);
3113     addHTTPOriginIfNeeded(initialRequest, outgoingOrigin());
3114
3115     initialRequest.setFirstPartyForCookies(m_frame.mainFrame().loader().documentLoader()->request().url());
3116     
3117     addExtraFieldsToSubresourceRequest(initialRequest);
3118
3119     unsigned long identifier = 0;    
3120     ResourceRequest newRequest(initialRequest);
3121     requestFromDelegate(newRequest, identifier, error);
3122
3123 #if ENABLE(CONTENT_EXTENSIONS)
3124     if (error.isNull()) {
3125         if (auto* page = m_frame.page()) {
3126             if (m_documentLoader) {
3127                 auto results = page->userContentProvider().processContentRuleListsForLoad(newRequest.url(), ContentExtensions::ResourceType::Raw, *m_documentLoader);
3128                 bool blockedLoad = results.summary.blockedLoad;
3129                 ContentExtensions::applyResultsToRequest(WTFMove(results), page, newRequest);
3130                 if (blockedLoad) {
3131                     newRequest = { };
3132                     error = ResourceError(errorDomainWebKitInternal, 0, initialRequest.url(), emptyString());
3133                     response = { };
3134                     data = nullptr;
3135                 }
3136             }
3137         }
3138     }
3139 #endif
3140
3141     m_frame.document()->contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(newRequest, ContentSecurityPolicy::InsecureRequestType::Load);
3142     
3143     if (error.isNull()) {
3144         ASSERT(!newRequest.isNull());
3145
3146         if (!documentLoader()->applicationCacheHost().maybeLoadSynchronously(newRequest, error, response, data)) {
3147             Vector<char> buffer;
3148             platformStrategies()->loaderStrategy()->loadResourceSynchronously(*this, identifier, newRequest, clientCredentialPolicy, options, originalRequestHeaders, error, response, buffer);
3149             data = SharedBuffer::create(WTFMove(buffer));
3150             documentLoader()->applicationCacheHost().maybeLoadFallbackSynchronously(newRequest, error, response, data);
3151             ResourceLoadObserver::shared().logSubresourceLoading(&m_frame, newRequest, response,
3152                 (isScriptLikeDestination(options.destination) ? ResourceLoadObserver::FetchDestinationIsScriptLike::Yes : ResourceLoadObserver::FetchDestinationIsScriptLike::No));
3153         }
3154     }
3155     notifier().sendRemainingDelegateMessages(m_documentLoader.get(), identifier, request, response, data ? data->data() : nullptr, data ? data->size() : 0, -1, error);
3156     return identifier;
3157 }
3158
3159 const ResourceRequest& FrameLoader::originalRequest() const
3160 {
3161     return activeDocumentLoader()->originalRequestCopy();
3162 }
3163
3164 void FrameLoader::receivedMainResourceError(const ResourceError& error)
3165 {
3166     // Retain because the stop may release the last reference to it.
3167     Ref<Frame> protect(m_frame);
3168
3169     RefPtr<DocumentLoader> loader = activeDocumentLoader();
3170     // FIXME: Don't want to do this if an entirely new load is going, so should check
3171     // that both data sources on the frame are either this or nil.
3172     stop();
3173     if (m_client->shouldFallBack(error))
3174         handleFallbackContent();
3175
3176     if (m_state == FrameStateProvisional && m_provisionalDocumentLoader) {
3177         if (m_submittedFormURL == m_provisionalDocumentLoader->originalRequestCopy().url())
3178             m_submittedFormURL = URL();
3179             
3180         // We might have made a back/forward cache item, but now we're bailing out due to an error before we ever
3181         // transitioned to the new page (before WebFrameState == commit).  The goal here is to restore any state
3182         // so that the existing view (that wenever got far enough to replace) can continue being used.
3183         history().invalidateCurrentItemCachedPage();
3184         
3185         // Call clientRedirectCancelledOrFinished here so that the frame load delegate is notified that the redirect's
3186         // status has changed, if there was a redirect. The frame load delegate may have saved some state about
3187         // the redirect in its -webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:. Since we are definitely
3188         // not going to use this provisional resource, as it was cancelled, notify the frame load delegate that the redirect
3189         // has ended.
3190         if (m_sentRedirectNotification)
3191             clientRedirectCancelledOrFinished(NewLoadInProgress::No);
3192     }
3193
3194     checkCompleted();
3195     if (m_frame.page())
3196         checkLoadComplete();
3197 }
3198
3199 void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue)
3200 {
3201     m_quickRedirectComing = false;
3202
3203     if (!shouldContinue)
3204         return;
3205
3206     // Calling stopLoading() on the provisional document loader can cause the underlying
3207     // frame to be deallocated.
3208     Ref<Frame> protectedFrame(m_frame);
3209
3210     // If we have a provisional request for a different document, a fragment scroll should cancel it.
3211     if (m_provisionalDocumentLoader && !equalIgnoringFragmentIdentifier(m_provisionalDocumentLoader->request().url(), request.url())) {
3212         m_provisionalDocumentLoader->stopLoading();
3213         FRAMELOADER_RELEASE_LOG_IF_ALLOWED(ResourceLoading, "continueFragmentScrollAfterNavigationPolicy: Clearing provisional document loader (m_provisionalDocumentLoader=%p)", m_provisionalDocumentLoader.get());
3214         setProvisionalDocumentLoader(nullptr);
3215     }
3216
3217     bool isRedirect = m_quickRedirectComing || policyChecker().loadType() == FrameLoadType::RedirectWithLockedBackForwardList;
3218     loadInSameDocument(request.url(), 0, !isRedirect);
3219 }
3220
3221 bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType loadType, const URL& url)
3222 {
3223     // We don't do this if we are submitting a form with method other than "GET", explicitly reloading,
3224     // currently displaying a frameset, or if the URL does not have a fragment.
3225     // These rules were originally based on what KHTML was doing in KHTMLPart::openURL.
3226
3227     // FIXME: What about load types other than Standard and Reload?
3228
3229     return (!isFormSubmission || equalLettersIgnoringASCIICase(httpMethod, "get"))
3230         && !isReload(loadType)
3231         && loadType != FrameLoadType::Same
3232         && m_frame.document()->backForwardCacheState() != Document::InBackForwardCache
3233         && !shouldReload(m_frame.document()->url(), url)
3234         // We don't want to just scroll if a link from within a
3235         // frameset is trying to reload the frameset into _top.
3236         && !m_frame.document()->isFrameSet();
3237 }
3238
3239 static bool itemAllowsScrollRestoration(HistoryItem* historyItem)
3240 {
3241     return !historyItem || historyItem->shouldRestoreScrollPosition();
3242 }
3243
3244 static bool isSameDocumentReload(bool isNewNavigation, FrameLoadType loadType)
3245 {
3246     return !isNewNavigation && !isBackForwardLoadType(loadType);
3247 }
3248
3249 void FrameLoader::scrollToFragmentWithParentBoundary(const URL& url, bool isNewNavigation)
3250 {
3251     auto view = makeRefPtr(m_frame.view());
3252     auto document = makeRefPtr(m_frame.document());
3253     if (!view || !document)
3254         return;
3255
3256     if (isSameDocumentReload(isNewNavigation, m_loadType) || itemAllowsScrollRestoration(history().currentItem())) {
3257         // https://html.spec.whatwg.org/multipage/browsing-the-web.html#try-to-scroll-to-the-fragment
3258         if (!document->haveStylesheetsLoaded())
3259             document->setGotoAnchorNeededAfterStylesheetsLoad(true);
3260         else
3261             view->scrollToFragment(url);
3262     }
3263
3264 }
3265
3266 bool FrameLoader::shouldClose()
3267 {
3268     Page* page = m_frame.page();
3269     if (!page)
3270         return true;
3271     if (!page->chrome().canRunBeforeUnloadConfirmPanel())
3272         return true;
3273
3274     // Store all references to each subframe in advance since beforeunload's event handler may modify frame
3275     Vector<Ref<Frame>, 16> targetFrames;
3276     targetFrames.append(m_frame);
3277     for (Frame* child = m_frame.tree().firstChild(); child; child = child->tree().traverseNext(&m_frame))
3278         targetFrames.append(*child);
3279
3280     bool shouldClose = false;
3281     {
3282         NavigationDisabler navigationDisabler(&m_frame);
3283         IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
3284         size_t i;
3285
3286         for (i = 0; i < targetFrames.size(); i++) {
3287             if (!targetFrames[i]->tree().isDescendantOf(&m_frame))
3288                 continue;
3289             if (!targetFrames[i]->loader().dispatchBeforeUnloadEvent(page->chrome(), this))
3290                 break;
3291         }
3292
3293         if (i == targetFrames.size())
3294             shouldClose = true;
3295     }
3296
3297     if (!shouldClose)
3298         m_submittedFormURL = URL();
3299
3300     m_currentNavigationHasShownBeforeUnloadConfirmPanel = false;
3301     return shouldClose;
3302 }
3303
3304 void FrameLoader::dispatchUnloadEvents(UnloadEventPolicy unloadEventPolicy)
3305 {
3306     if (!m_frame.document())
3307         return;
3308
3309     if (m_pageDismissalEventBeingDispatched != PageDismissalType::None)
3310         return;
3311
3312     // We store the frame's page in a local variable because the frame might get detached inside dispatchEvent.
3313     ForbidPromptsScope forbidPrompts(m_frame.page());
3314     ForbidSynchronousLoadsScope forbidSynchronousLoads(m_frame.page());
3315     IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document());
3316
3317     if (m_didCallImplicitClose && !m_wasUnloadEventEmitted) {
3318         auto* currentFocusedElement = m_frame.document()->focusedElement();
3319         if (is<HTMLInputElement>(currentFocusedElement))
3320             downcast<HTMLInputElement>(*currentFocusedElement).endEditing();
3321         if (m_pageDismissalEventBeingDispatched == PageDismissalType::None) {
3322             if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) {
3323                 m_pageDismissalEventBeingDispatched = PageDismissalType::PageHide;
3324                 m_frame.document()->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame.document()->backForwardCacheState() == Document::AboutToEnterBackForwardCache), m_frame.document());
3325             }
3326
3327             // FIXME: update Page Visibility state here.
3328             // https://bugs.webkit.org/show_bug.cgi?id=116770
3329
3330             if (m_frame.document()->backForwardCacheState() == Document::NotInBackForwardCache) {
3331                 Ref<Event> unloadEvent(Event::create(eventNames().unloadEvent, Event::CanBubble::No, Event::IsCancelable::No));
3332                 // The DocumentLoader (and thus its LoadTiming) might get destroyed
3333                 // while dispatching the event, so protect it to prevent writing the end
3334                 // time into freed memory.
3335                 RefPtr<DocumentLoader> documentLoader = m_provisionalDocumentLoader;
3336                 m_pageDismissalEventBeingDispatched = PageDismissalType::Unload;
3337                 if (documentLoader && documentLoader->timing().startTime() && !documentLoader->timing().unloadEventStart() && !documentLoader->timing().unloadEventEnd()) {
3338                     auto& timing = documentLoader->timing();
3339                     timing.markUnloadEventStart();
3340                     m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
3341                     timing.markUnloadEventEnd();
3342                 } else
3343                     m_frame.document()->domWindow()->dispatchEvent(unloadEvent, m_frame.document());
3344             }
3345         }
3346         m_pageDismissalEventBeingDispatched = PageDismissalType::None;
3347         m_wasUnloadEventEmitted = true;
3348     }
3349
3350     // Dispatching the unload event could have made m_frame.document() null.
3351     if (!m_frame.document())
3352         return;
3353
3354     if (m_frame.document()->backForwardCacheState() != Document::NotInBackForwardCache)
3355         return;
3356
3357     // Don't remove event listeners from a transitional empty document (see bug 28716 for more information).
3358     bool keepEventListeners = m_stateMachine.isDisplayingInitialEmptyDocument() && m_provisionalDocumentLoader
3359         && m_frame.document()->isSecureTransitionTo(m_provisionalDocumentLoader->url());
3360
3361     if (!keepEventListeners)
3362         m_frame.document()->removeAllEventListeners();
3363 }
3364
3365 static bool shouldAskForNavigationConfirmation(Document& document, const BeforeUnloadEvent& event)
3366 {
3367     // Confirmation dialog should not be displayed when the allow-modals flag is not set.
3368     if (document.isSandboxed(SandboxModals))
3369         return false;
3370
3371     bool userDidInteractWithPage = document.topDocument().userDidInteractWithPage();
3372     // Web pages can request we ask for confirmation before navigating by:
3373     // - Cancelling the BeforeUnloadEvent (modern way)
3374     // - Setting the returnValue attribute on the BeforeUnloadEvent to a non-empty string.
3375     // - Returning a non-empty string from the event handler, which is then set as returnValue
3376     //   attribute on the BeforeUnloadEvent.
3377     return userDidInteractWithPage && (event.defaultPrevented() || !event.returnValue().isEmpty());
3378 }
3379
3380 bool FrameLoader::dispatchBeforeUnloadEvent(Chrome& chrome, FrameLoader* frameLoaderBeingNavigated)
3381 {
3382     DOMWindow* domWindow = m_frame.document()->domWindow();
3383     if (!domWindow)
3384         return true;
3385
3386     RefPtr<Document> document = m_frame.document();
3387     if (!document->bodyOrFrameset())
3388         return true;
3389     
3390     Ref<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
3391
3392     {
3393         SetForScope<PageDismissalType> change(m_pageDismissalEventBeingDispatched, PageDismissalType::BeforeUnload);
3394         ForbidPromptsScope forbidPrompts(m_frame.page());
3395         ForbidSynchronousLoadsScope forbidSynchronousLoads(m_frame.page());
3396         domWindow->dispatchEvent(beforeUnloadEvent, domWindow->document());
3397     }
3398
3399     if (!beforeUnloadEvent->defaultPrevented())
3400         document->defaultEventHandler(beforeUnloadEvent.get());
3401
3402     if (!shouldAskForNavigationConfirmation(*document, beforeUnloadEvent))
3403         return true;
3404
3405     // If the navigating FrameLoader has already shown a beforeunload confirmation panel for the current navigation attempt,
3406     // this frame is not allowed to cause another one to be shown.
3407     if (frameLoaderBeingNavigated->m_currentNavigationHasShownBeforeUnloadConfirmPanel) {
3408         document->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "Blocked attempt to show multiple beforeunload confirmation dialogs for the same navigation."_s);
3409         return true;
3410     }
3411
3412     // We should only display the beforeunload dialog for an iframe if its SecurityOrigin matches all
3413     // ancestor frame SecurityOrigins up through the navigating FrameLoader.
3414     if (frameLoaderBeingNavigated != this) {
3415         Frame* parentFrame = m_frame.tree().parent();
3416         while (parentFrame) {
3417             Document* parentDocument = parentFrame->document();
3418             if (!parentDocument)