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