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