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