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