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