| OLD | NEW | 
 | (Empty) | 
|     1 /* |  | 
|     2  * Copyright (C) 2009 Google Inc. All rights reserved. |  | 
|     3  * |  | 
|     4  * Redistribution and use in source and binary forms, with or without |  | 
|     5  * modification, are permitted provided that the following conditions are |  | 
|     6  * met: |  | 
|     7  * |  | 
|     8  *     * Redistributions of source code must retain the above copyright |  | 
|     9  * notice, this list of conditions and the following disclaimer. |  | 
|    10  *     * Redistributions in binary form must reproduce the above |  | 
|    11  * copyright notice, this list of conditions and the following disclaimer |  | 
|    12  * in the documentation and/or other materials provided with the |  | 
|    13  * distribution. |  | 
|    14  *     * Neither the name of Google Inc. nor the names of its |  | 
|    15  * contributors may be used to endorse or promote products derived from |  | 
|    16  * this software without specific prior written permission. |  | 
|    17  * |  | 
|    18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |  | 
|    19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |  | 
|    20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |  | 
|    21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |  | 
|    22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |  | 
|    23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |  | 
|    24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |  | 
|    25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |  | 
|    26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |  | 
|    27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |  | 
|    28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | 
|    29  */ |  | 
|    30  |  | 
|    31 #include "config.h" |  | 
|    32 #include "FrameLoaderClientImpl.h" |  | 
|    33  |  | 
|    34 #include "Chrome.h" |  | 
|    35 #include "CString.h" |  | 
|    36 #include "Document.h" |  | 
|    37 #include "DocumentLoader.h" |  | 
|    38 #include "FormState.h" |  | 
|    39 #include "FrameLoader.h" |  | 
|    40 #include "FrameLoadRequest.h" |  | 
|    41 #include "HitTestResult.h" |  | 
|    42 #include "HTMLAppletElement.h" |  | 
|    43 #include "HTMLFormElement.h"  // needed by FormState.h |  | 
|    44 #include "HTMLNames.h" |  | 
|    45 #include "MIMETypeRegistry.h" |  | 
|    46 #include "MouseEvent.h" |  | 
|    47 #include "Page.h" |  | 
|    48 #include "PlatformString.h" |  | 
|    49 #include "PluginData.h" |  | 
|    50 #include "StringExtras.h" |  | 
|    51 #include "WebDataSourceImpl.h" |  | 
|    52 #include "WebDevToolsAgentPrivate.h" |  | 
|    53 #include "WebFormElement.h" |  | 
|    54 #include "WebFrameClient.h" |  | 
|    55 #include "WebFrameImpl.h" |  | 
|    56 #include "WebKit.h" |  | 
|    57 #include "WebKitClient.h" |  | 
|    58 #include "WebMimeRegistry.h" |  | 
|    59 #include "WebNode.h" |  | 
|    60 #include "WebPlugin.h" |  | 
|    61 #include "WebPluginContainerImpl.h" |  | 
|    62 #include "WebPluginLoadObserver.h" |  | 
|    63 #include "WebPluginParams.h" |  | 
|    64 #include "WebSecurityOrigin.h" |  | 
|    65 #include "WebURL.h" |  | 
|    66 #include "WebURLError.h" |  | 
|    67 #include "WebVector.h" |  | 
|    68 #include "WebViewClient.h" |  | 
|    69 #include "WebViewImpl.h" |  | 
|    70 #include "WindowFeatures.h" |  | 
|    71 #include "WrappedResourceRequest.h" |  | 
|    72 #include "WrappedResourceResponse.h" |  | 
|    73  |  | 
|    74 using namespace WebCore; |  | 
|    75  |  | 
|    76 namespace WebKit { |  | 
|    77  |  | 
|    78 // Domain for internal error codes. |  | 
|    79 static const char internalErrorDomain[] = "WebKit"; |  | 
|    80  |  | 
|    81 // An internal error code.  Used to note a policy change error resulting from |  | 
|    82 // dispatchDecidePolicyForMIMEType not passing the PolicyUse option. |  | 
|    83 enum { |  | 
|    84     PolicyChangeError = -10000, |  | 
|    85 }; |  | 
|    86  |  | 
|    87 FrameLoaderClientImpl::FrameLoaderClientImpl(WebFrameImpl* frame) |  | 
|    88     : m_webFrame(frame) |  | 
|    89     , m_hasRepresentation(false) |  | 
|    90     , m_sentInitialResponseToPlugin(false) |  | 
|    91     , m_nextNavigationPolicy(WebNavigationPolicyIgnore) |  | 
|    92 { |  | 
|    93 } |  | 
|    94  |  | 
|    95 FrameLoaderClientImpl::~FrameLoaderClientImpl() |  | 
|    96 { |  | 
|    97 } |  | 
|    98  |  | 
|    99 void FrameLoaderClientImpl::frameLoaderDestroyed() |  | 
|   100 { |  | 
|   101     // When the WebFrame was created, it had an extra reference given to it on |  | 
|   102     // behalf of the Frame.  Since the WebFrame owns us, this extra ref also |  | 
|   103     // serves to keep us alive until the FrameLoader is done with us.  The |  | 
|   104     // FrameLoader calls this method when it's going away.  Therefore, we balance |  | 
|   105     // out that extra reference, which may cause 'this' to be deleted. |  | 
|   106     m_webFrame->closing(); |  | 
|   107     m_webFrame->deref(); |  | 
|   108 } |  | 
|   109  |  | 
|   110 void FrameLoaderClientImpl::windowObjectCleared() |  | 
|   111 { |  | 
|   112     if (m_webFrame->client()) |  | 
|   113         m_webFrame->client()->didClearWindowObject(m_webFrame); |  | 
|   114  |  | 
|   115     WebViewImpl* webview = m_webFrame->viewImpl(); |  | 
|   116     if (webview->devToolsAgentPrivate()) |  | 
|   117         webview->devToolsAgentPrivate()->didClearWindowObject(m_webFrame); |  | 
|   118 } |  | 
|   119  |  | 
|   120 void FrameLoaderClientImpl::documentElementAvailable() |  | 
|   121 { |  | 
|   122     if (m_webFrame->client()) |  | 
|   123         m_webFrame->client()->didCreateDocumentElement(m_webFrame); |  | 
|   124 } |  | 
|   125  |  | 
|   126 void FrameLoaderClientImpl::didCreateScriptContextForFrame() |  | 
|   127 { |  | 
|   128     if (m_webFrame->client()) |  | 
|   129         m_webFrame->client()->didCreateScriptContext(m_webFrame); |  | 
|   130 } |  | 
|   131  |  | 
|   132 void FrameLoaderClientImpl::didDestroyScriptContextForFrame() |  | 
|   133 { |  | 
|   134     if (m_webFrame->client()) |  | 
|   135         m_webFrame->client()->didDestroyScriptContext(m_webFrame); |  | 
|   136 } |  | 
|   137  |  | 
|   138 void FrameLoaderClientImpl::didCreateIsolatedScriptContext() |  | 
|   139 { |  | 
|   140     if (m_webFrame->client()) |  | 
|   141         m_webFrame->client()->didCreateIsolatedScriptContext(m_webFrame); |  | 
|   142 } |  | 
|   143  |  | 
|   144 void FrameLoaderClientImpl::didPerformFirstNavigation() const |  | 
|   145 { |  | 
|   146 } |  | 
|   147  |  | 
|   148 void FrameLoaderClientImpl::registerForIconNotification(bool) |  | 
|   149 { |  | 
|   150 } |  | 
|   151  |  | 
|   152 void FrameLoaderClientImpl::didChangeScrollOffset() |  | 
|   153 { |  | 
|   154     if (m_webFrame->client()) |  | 
|   155         m_webFrame->client()->didChangeScrollOffset(m_webFrame); |  | 
|   156 } |  | 
|   157  |  | 
|   158 bool FrameLoaderClientImpl::allowJavaScript(bool enabledPerSettings) |  | 
|   159 { |  | 
|   160     if (m_webFrame->client()) |  | 
|   161         return m_webFrame->client()->allowScript(m_webFrame, enabledPerSettings); |  | 
|   162  |  | 
|   163     return enabledPerSettings; |  | 
|   164 } |  | 
|   165  |  | 
|   166 bool FrameLoaderClientImpl::hasWebView() const |  | 
|   167 { |  | 
|   168     return m_webFrame->viewImpl(); |  | 
|   169 } |  | 
|   170  |  | 
|   171 bool FrameLoaderClientImpl::hasFrameView() const |  | 
|   172 { |  | 
|   173     // The Mac port has this notion of a WebFrameView, which seems to be |  | 
|   174     // some wrapper around an NSView.  Since our equivalent is HWND, I guess |  | 
|   175     // we have a "frameview" whenever we have the toplevel HWND. |  | 
|   176     return m_webFrame->viewImpl(); |  | 
|   177 } |  | 
|   178  |  | 
|   179 void FrameLoaderClientImpl::makeDocumentView() |  | 
|   180 { |  | 
|   181     m_webFrame->createFrameView(); |  | 
|   182 } |  | 
|   183  |  | 
|   184 void FrameLoaderClientImpl::makeRepresentation(DocumentLoader*) |  | 
|   185 { |  | 
|   186     m_hasRepresentation = true; |  | 
|   187 } |  | 
|   188  |  | 
|   189 void FrameLoaderClientImpl::forceLayout() |  | 
|   190 { |  | 
|   191     // FIXME |  | 
|   192 } |  | 
|   193  |  | 
|   194 void FrameLoaderClientImpl::forceLayoutForNonHTML() |  | 
|   195 { |  | 
|   196     // FIXME |  | 
|   197 } |  | 
|   198  |  | 
|   199 void FrameLoaderClientImpl::setCopiesOnScroll() |  | 
|   200 { |  | 
|   201     // FIXME |  | 
|   202 } |  | 
|   203  |  | 
|   204 void FrameLoaderClientImpl::detachedFromParent2() |  | 
|   205 { |  | 
|   206     // Nothing to do here. |  | 
|   207 } |  | 
|   208  |  | 
|   209 void FrameLoaderClientImpl::detachedFromParent3() |  | 
|   210 { |  | 
|   211     // Close down the proxy.  The purpose of this change is to make the |  | 
|   212     // call to ScriptController::clearWindowShell a no-op when called from |  | 
|   213     // Frame::pageDestroyed.  Without this change, this call to clearWindowShell |  | 
|   214     // will cause a crash.  If you remove/modify this, just ensure that you can |  | 
|   215     // go to a page and then navigate to a new page without getting any asserts |  | 
|   216     // or crashes. |  | 
|   217     m_webFrame->frame()->script()->proxy()->clearForClose(); |  | 
|   218 } |  | 
|   219  |  | 
|   220 // This function is responsible for associating the |identifier| with a given |  | 
|   221 // subresource load.  The following functions that accept an |identifier| are |  | 
|   222 // called for each subresource, so they should not be dispatched to the |  | 
|   223 // WebFrame. |  | 
|   224 void FrameLoaderClientImpl::assignIdentifierToInitialRequest( |  | 
|   225     unsigned long identifier, DocumentLoader* loader, |  | 
|   226     const ResourceRequest& request) |  | 
|   227 { |  | 
|   228     if (m_webFrame->client()) { |  | 
|   229         WrappedResourceRequest webreq(request); |  | 
|   230         m_webFrame->client()->assignIdentifierToRequest( |  | 
|   231             m_webFrame, identifier, webreq); |  | 
|   232     } |  | 
|   233 } |  | 
|   234  |  | 
|   235 // Determines whether the request being loaded by |loader| is a frame or a |  | 
|   236 // subresource. A subresource in this context is anything other than a frame -- |  | 
|   237 // this includes images and xmlhttp requests.  It is important to note that a |  | 
|   238 // subresource is NOT limited to stuff loaded through the frame's subresource |  | 
|   239 // loader. Synchronous xmlhttp requests for example, do not go through the |  | 
|   240 // subresource loader, but we still label them as TargetIsSubResource. |  | 
|   241 // |  | 
|   242 // The important edge cases to consider when modifying this function are |  | 
|   243 // how synchronous resource loads are treated during load/unload threshold. |  | 
|   244 static ResourceRequest::TargetType determineTargetTypeFromLoader(DocumentLoader* loader) |  | 
|   245 { |  | 
|   246     if (loader == loader->frameLoader()->provisionalDocumentLoader()) { |  | 
|   247         if (loader->frameLoader()->isLoadingMainFrame()) |  | 
|   248             return ResourceRequest::TargetIsMainFrame; |  | 
|   249         return ResourceRequest::TargetIsSubFrame; |  | 
|   250     } |  | 
|   251     return ResourceRequest::TargetIsSubResource; |  | 
|   252 } |  | 
|   253  |  | 
|   254 void FrameLoaderClientImpl::dispatchWillSendRequest( |  | 
|   255     DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, |  | 
|   256     const ResourceResponse& redirectResponse) |  | 
|   257 { |  | 
|   258     if (loader) { |  | 
|   259         // We want to distinguish between a request for a document to be loaded into |  | 
|   260         // the main frame, a sub-frame, or the sub-objects in that document. |  | 
|   261         request.setTargetType(determineTargetTypeFromLoader(loader)); |  | 
|   262     } |  | 
|   263  |  | 
|   264     // FrameLoader::loadEmptyDocumentSynchronously() creates an empty document |  | 
|   265     // with no URL.  We don't like that, so we'll rename it to about:blank. |  | 
|   266     if (request.url().isEmpty()) |  | 
|   267         request.setURL(KURL(ParsedURLString, "about:blank")); |  | 
|   268     if (request.firstPartyForCookies().isEmpty()) |  | 
|   269         request.setFirstPartyForCookies(KURL(ParsedURLString, "about:blank")); |  | 
|   270  |  | 
|   271     // Give the WebFrameClient a crack at the request. |  | 
|   272     if (m_webFrame->client()) { |  | 
|   273         WrappedResourceRequest webreq(request); |  | 
|   274         WrappedResourceResponse webresp(redirectResponse); |  | 
|   275         m_webFrame->client()->willSendRequest( |  | 
|   276             m_webFrame, identifier, webreq, webresp); |  | 
|   277     } |  | 
|   278 } |  | 
|   279  |  | 
|   280 bool FrameLoaderClientImpl::shouldUseCredentialStorage( |  | 
|   281     DocumentLoader*, unsigned long identifier) |  | 
|   282 { |  | 
|   283     // FIXME |  | 
|   284     // Intended to pass through to a method on the resource load delegate. |  | 
|   285     // If implemented, that method controls whether the browser should ask the |  | 
|   286     // networking layer for a stored default credential for the page (say from |  | 
|   287     // the Mac OS keychain). If the method returns false, the user should be |  | 
|   288     // presented with an authentication challenge whether or not the networking |  | 
|   289     // layer has a credential stored. |  | 
|   290     // This returns true for backward compatibility: the ability to override the |  | 
|   291     // system credential store is new. (Actually, not yet fully implemented in |  | 
|   292     // WebKit, as of this writing.) |  | 
|   293     return true; |  | 
|   294 } |  | 
|   295  |  | 
|   296 void FrameLoaderClientImpl::dispatchDidReceiveAuthenticationChallenge( |  | 
|   297     DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) |  | 
|   298 { |  | 
|   299     // FIXME |  | 
|   300 } |  | 
|   301  |  | 
|   302 void FrameLoaderClientImpl::dispatchDidCancelAuthenticationChallenge( |  | 
|   303     DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) |  | 
|   304 { |  | 
|   305     // FIXME |  | 
|   306 } |  | 
|   307  |  | 
|   308 void FrameLoaderClientImpl::dispatchDidReceiveResponse(DocumentLoader* loader, |  | 
|   309                                                        unsigned long identifier, |  | 
|   310                                                        const ResourceResponse& response) |  | 
|   311 { |  | 
|   312     if (m_webFrame->client()) { |  | 
|   313         WrappedResourceResponse webresp(response); |  | 
|   314         m_webFrame->client()->didReceiveResponse(m_webFrame, identifier, webresp); |  | 
|   315     } |  | 
|   316 } |  | 
|   317  |  | 
|   318 void FrameLoaderClientImpl::dispatchDidReceiveContentLength( |  | 
|   319     DocumentLoader* loader, |  | 
|   320     unsigned long identifier, |  | 
|   321     int lengthReceived) |  | 
|   322 { |  | 
|   323 } |  | 
|   324  |  | 
|   325 // Called when a particular resource load completes |  | 
|   326 void FrameLoaderClientImpl::dispatchDidFinishLoading(DocumentLoader* loader, |  | 
|   327                                                     unsigned long identifier) |  | 
|   328 { |  | 
|   329     if (m_webFrame->client()) |  | 
|   330         m_webFrame->client()->didFinishResourceLoad(m_webFrame, identifier); |  | 
|   331 } |  | 
|   332  |  | 
|   333 void FrameLoaderClientImpl::dispatchDidFailLoading(DocumentLoader* loader, |  | 
|   334                                                   unsigned long identifier, |  | 
|   335                                                   const ResourceError& error) |  | 
|   336 { |  | 
|   337     if (m_webFrame->client()) |  | 
|   338         m_webFrame->client()->didFailResourceLoad(m_webFrame, identifier, error); |  | 
|   339 } |  | 
|   340  |  | 
|   341 void FrameLoaderClientImpl::dispatchDidFinishDocumentLoad() |  | 
|   342 { |  | 
|   343     // A frame may be reused.  This call ensures we don't hold on to our password |  | 
|   344     // listeners and their associated HTMLInputElements. |  | 
|   345     m_webFrame->clearPasswordListeners(); |  | 
|   346  |  | 
|   347     if (m_webFrame->client()) |  | 
|   348         m_webFrame->client()->didFinishDocumentLoad(m_webFrame); |  | 
|   349 } |  | 
|   350  |  | 
|   351 bool FrameLoaderClientImpl::dispatchDidLoadResourceFromMemoryCache( |  | 
|   352     DocumentLoader* loader, |  | 
|   353     const ResourceRequest& request, |  | 
|   354     const ResourceResponse& response, |  | 
|   355     int length) |  | 
|   356 { |  | 
|   357     if (m_webFrame->client()) { |  | 
|   358         WrappedResourceRequest webreq(request); |  | 
|   359         WrappedResourceResponse webresp(response); |  | 
|   360         m_webFrame->client()->didLoadResourceFromMemoryCache( |  | 
|   361             m_webFrame, webreq, webresp); |  | 
|   362     } |  | 
|   363     return false;  // Do not suppress remaining notifications |  | 
|   364 } |  | 
|   365  |  | 
|   366 void FrameLoaderClientImpl::dispatchDidLoadResourceByXMLHttpRequest( |  | 
|   367     unsigned long identifier, |  | 
|   368     const ScriptString& source) |  | 
|   369 { |  | 
|   370 } |  | 
|   371  |  | 
|   372 void FrameLoaderClientImpl::dispatchDidHandleOnloadEvents() |  | 
|   373 { |  | 
|   374     if (m_webFrame->client()) |  | 
|   375         m_webFrame->client()->didHandleOnloadEvents(m_webFrame); |  | 
|   376 } |  | 
|   377  |  | 
|   378 // Redirect Tracking |  | 
|   379 // ================= |  | 
|   380 // We want to keep track of the chain of redirects that occur during page |  | 
|   381 // loading. There are two types of redirects, server redirects which are HTTP |  | 
|   382 // response codes, and client redirects which are document.location= and meta |  | 
|   383 // refreshes. |  | 
|   384 // |  | 
|   385 // This outlines the callbacks that we get in different redirect situations, |  | 
|   386 // and how each call modifies the redirect chain. |  | 
|   387 // |  | 
|   388 // Normal page load |  | 
|   389 // ---------------- |  | 
|   390 //   dispatchDidStartProvisionalLoad() -> adds URL to the redirect list |  | 
|   391 //   dispatchDidCommitLoad()           -> DISPATCHES & clears list |  | 
|   392 // |  | 
|   393 // Server redirect (success) |  | 
|   394 // ------------------------- |  | 
|   395 //   dispatchDidStartProvisionalLoad()                    -> adds source URL |  | 
|   396 //   dispatchDidReceiveServerRedirectForProvisionalLoad() -> adds dest URL |  | 
|   397 //   dispatchDidCommitLoad()                              -> DISPATCHES |  | 
|   398 // |  | 
|   399 // Client redirect (success) |  | 
|   400 // ------------------------- |  | 
|   401 //   (on page) |  | 
|   402 //   dispatchWillPerformClientRedirect() -> saves expected redirect |  | 
|   403 //   dispatchDidStartProvisionalLoad()   -> appends redirect source (since |  | 
|   404 //                                          it matches the expected redirect) |  | 
|   405 //                                          and the current page as the dest) |  | 
|   406 //   dispatchDidCancelClientRedirect()   -> clears expected redirect |  | 
|   407 //   dispatchDidCommitLoad()             -> DISPATCHES |  | 
|   408 // |  | 
|   409 // Client redirect (cancelled) |  | 
|   410 // (e.g meta-refresh trumped by manual doc.location change, or just cancelled |  | 
|   411 // because a link was clicked that requires the meta refresh to be rescheduled |  | 
|   412 // (the SOURCE URL may have changed). |  | 
|   413 // --------------------------- |  | 
|   414 //   dispatchDidCancelClientRedirect()                 -> clears expected redirect |  | 
|   415 //   dispatchDidStartProvisionalLoad()                 -> adds only URL to redirect list |  | 
|   416 //   dispatchDidCommitLoad()                           -> DISPATCHES & clears list |  | 
|   417 //   rescheduled ? dispatchWillPerformClientRedirect() -> saves expected redirect |  | 
|   418 //               : nothing |  | 
|   419  |  | 
|   420 // Client redirect (failure) |  | 
|   421 // ------------------------- |  | 
|   422 //   (on page) |  | 
|   423 //   dispatchWillPerformClientRedirect() -> saves expected redirect |  | 
|   424 //   dispatchDidStartProvisionalLoad()   -> appends redirect source (since |  | 
|   425 //                                          it matches the expected redirect) |  | 
|   426 //                                          and the current page as the dest) |  | 
|   427 //   dispatchDidCancelClientRedirect() |  | 
|   428 //   dispatchDidFailProvisionalLoad() |  | 
|   429 // |  | 
|   430 // Load 1 -> Server redirect to 2 -> client redirect to 3 -> server redirect to 4 |  | 
|   431 // ------------------------------------------------------------------------------ |  | 
|   432 //   dispatchDidStartProvisionalLoad()                    -> adds source URL 1 |  | 
|   433 //   dispatchDidReceiveServerRedirectForProvisionalLoad() -> adds dest URL 2 |  | 
|   434 //   dispatchDidCommitLoad()                              -> DISPATCHES 1+2 |  | 
|   435 //    -- begin client redirect and NEW DATA SOURCE |  | 
|   436 //   dispatchWillPerformClientRedirect()                  -> saves expected redirect |  | 
|   437 //   dispatchDidStartProvisionalLoad()                    -> appends URL 2 and URL 3 |  | 
|   438 //   dispatchDidReceiveServerRedirectForProvisionalLoad() -> appends destination URL 4 |  | 
|   439 //   dispatchDidCancelClientRedirect()                    -> clears expected redirect |  | 
|   440 //   dispatchDidCommitLoad()                              -> DISPATCHES |  | 
|   441 // |  | 
|   442 // Interesting case with multiple location changes involving anchors. |  | 
|   443 // Load page 1 containing future client-redirect (back to 1, e.g meta refresh) > Click |  | 
|   444 // on a link back to the same page (i.e an anchor href) > |  | 
|   445 // client-redirect finally fires (with new source, set to 1#anchor) |  | 
|   446 // ----------------------------------------------------------------------------- |  | 
|   447 //   dispatchWillPerformClientRedirect(non-zero 'interval' param) -> saves expected redirect |  | 
|   448 //   -- click on anchor href |  | 
|   449 //   dispatchDidCancelClientRedirect()                            -> clears expected redirect |  | 
|   450 //   dispatchDidStartProvisionalLoad()                            -> adds 1#anchor source |  | 
|   451 //   dispatchDidCommitLoad()                                      -> DISPATCHES 1#anchor |  | 
|   452 //   dispatchWillPerformClientRedirect()                          -> saves exp. source (1#anchor) |  | 
|   453 //   -- redirect timer fires |  | 
|   454 //   dispatchDidStartProvisionalLoad()                            -> appends 1#anchor (src) and 1 (dest) |  | 
|   455 //   dispatchDidCancelClientRedirect()                            -> clears expected redirect |  | 
|   456 //   dispatchDidCommitLoad()                                      -> DISPATCHES 1#anchor + 1 |  | 
|   457 // |  | 
|   458 void FrameLoaderClientImpl::dispatchDidReceiveServerRedirectForProvisionalLoad() |  | 
|   459 { |  | 
|   460     WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl(); |  | 
|   461     if (!ds) { |  | 
|   462         // Got a server redirect when there is no provisional DS! |  | 
|   463         ASSERT_NOT_REACHED(); |  | 
|   464         return; |  | 
|   465     } |  | 
|   466  |  | 
|   467     // The server redirect may have been blocked. |  | 
|   468     if (ds->request().isNull()) |  | 
|   469         return; |  | 
|   470  |  | 
|   471     // A provisional load should have started already, which should have put an |  | 
|   472     // entry in our redirect chain. |  | 
|   473     ASSERT(ds->hasRedirectChain()); |  | 
|   474  |  | 
|   475     // The URL of the destination is on the provisional data source. We also need |  | 
|   476     // to update the redirect chain to account for this addition (we do this |  | 
|   477     // before the callback so the callback can look at the redirect chain to see |  | 
|   478     // what happened). |  | 
|   479     ds->appendRedirect(ds->request().url()); |  | 
|   480  |  | 
|   481     if (m_webFrame->client()) |  | 
|   482         m_webFrame->client()->didReceiveServerRedirectForProvisionalLoad(m_webFrame); |  | 
|   483 } |  | 
|   484  |  | 
|   485 // Called on both success and failure of a client redirect. |  | 
|   486 void FrameLoaderClientImpl::dispatchDidCancelClientRedirect() |  | 
|   487 { |  | 
|   488     // No longer expecting a client redirect. |  | 
|   489     if (m_webFrame->client()) { |  | 
|   490         m_expectedClientRedirectSrc = KURL(); |  | 
|   491         m_expectedClientRedirectDest = KURL(); |  | 
|   492         m_webFrame->client()->didCancelClientRedirect(m_webFrame); |  | 
|   493     } |  | 
|   494  |  | 
|   495     // No need to clear the redirect chain, since that data source has already |  | 
|   496     // been deleted by the time this function is called. |  | 
|   497 } |  | 
|   498  |  | 
|   499 void FrameLoaderClientImpl::dispatchWillPerformClientRedirect( |  | 
|   500     const KURL& url, |  | 
|   501     double interval, |  | 
|   502     double fireDate) |  | 
|   503 { |  | 
|   504     // Tells dispatchDidStartProvisionalLoad that if it sees this item it is a |  | 
|   505     // redirect and the source item should be added as the start of the chain. |  | 
|   506     m_expectedClientRedirectSrc = m_webFrame->url(); |  | 
|   507     m_expectedClientRedirectDest = url; |  | 
|   508  |  | 
|   509     // FIXME: bug 1135512. Webkit does not properly notify us of cancelling |  | 
|   510     // http > file client redirects. Since the FrameLoader's policy is to never |  | 
|   511     // carry out such a navigation anyway, the best thing we can do for now to |  | 
|   512     // not get confused is ignore this notification. |  | 
|   513     if (m_expectedClientRedirectDest.isLocalFile() |  | 
|   514         && m_expectedClientRedirectSrc.protocolInHTTPFamily()) { |  | 
|   515         m_expectedClientRedirectSrc = KURL(); |  | 
|   516         m_expectedClientRedirectDest = KURL(); |  | 
|   517         return; |  | 
|   518     } |  | 
|   519  |  | 
|   520     if (m_webFrame->client()) { |  | 
|   521         m_webFrame->client()->willPerformClientRedirect( |  | 
|   522             m_webFrame, |  | 
|   523             m_expectedClientRedirectSrc, |  | 
|   524             m_expectedClientRedirectDest, |  | 
|   525             static_cast<unsigned int>(interval), |  | 
|   526             static_cast<unsigned int>(fireDate)); |  | 
|   527     } |  | 
|   528 } |  | 
|   529  |  | 
|   530 void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() |  | 
|   531 { |  | 
|   532     // Anchor fragment navigations are not normal loads, so we need to synthesize |  | 
|   533     // some events for our delegate. |  | 
|   534     WebViewImpl* webView = m_webFrame->viewImpl(); |  | 
|   535     if (webView->client()) |  | 
|   536         webView->client()->didStartLoading(); |  | 
|   537  |  | 
|   538     WebDataSourceImpl* ds = m_webFrame->dataSourceImpl(); |  | 
|   539     ASSERT(ds);  // Should not be null when navigating to a reference fragment! |  | 
|   540     if (ds) { |  | 
|   541         KURL url = ds->request().url(); |  | 
|   542         KURL chainEnd; |  | 
|   543         if (ds->hasRedirectChain()) { |  | 
|   544             chainEnd = ds->endOfRedirectChain(); |  | 
|   545             ds->clearRedirectChain(); |  | 
|   546         } |  | 
|   547  |  | 
|   548         // Figure out if this location change is because of a JS-initiated |  | 
|   549         // client redirect (e.g onload/setTimeout document.location.href=). |  | 
|   550         // FIXME: (bugs 1085325, 1046841) We don't get proper redirect |  | 
|   551         // performed/cancelled notifications across anchor navigations, so the |  | 
|   552         // other redirect-tracking code in this class (see |  | 
|   553         // dispatch*ClientRedirect() and dispatchDidStartProvisionalLoad) is |  | 
|   554         // insufficient to catch and properly flag these transitions. Once a |  | 
|   555         // proper fix for this bug is identified and applied the following |  | 
|   556         // block may no longer be required. |  | 
|   557         bool wasClientRedirect = |  | 
|   558             (url == m_expectedClientRedirectDest && chainEnd == m_expectedClientRedirectSrc) |  | 
|   559             || !m_webFrame->isProcessingUserGesture(); |  | 
|   560  |  | 
|   561         if (wasClientRedirect) { |  | 
|   562             if (m_webFrame->client()) |  | 
|   563                 m_webFrame->client()->didCompleteClientRedirect(m_webFrame, chainEnd); |  | 
|   564             ds->appendRedirect(chainEnd); |  | 
|   565             // Make sure we clear the expected redirect since we just effectively |  | 
|   566             // completed it. |  | 
|   567             m_expectedClientRedirectSrc = KURL(); |  | 
|   568             m_expectedClientRedirectDest = KURL(); |  | 
|   569         } |  | 
|   570  |  | 
|   571         // Regardless of how we got here, we are navigating to a URL so we need to |  | 
|   572         // add it to the redirect chain. |  | 
|   573         ds->appendRedirect(url); |  | 
|   574     } |  | 
|   575  |  | 
|   576     bool isNewNavigation; |  | 
|   577     webView->didCommitLoad(&isNewNavigation); |  | 
|   578     if (m_webFrame->client()) |  | 
|   579         m_webFrame->client()->didChangeLocationWithinPage(m_webFrame, isNewNavigation); |  | 
|   580  |  | 
|   581     if (webView->client()) |  | 
|   582         webView->client()->didStopLoading(); |  | 
|   583 } |  | 
|   584  |  | 
|   585 void FrameLoaderClientImpl::dispatchWillClose() |  | 
|   586 { |  | 
|   587     if (m_webFrame->client()) |  | 
|   588         m_webFrame->client()->willClose(m_webFrame); |  | 
|   589 } |  | 
|   590  |  | 
|   591 void FrameLoaderClientImpl::dispatchDidReceiveIcon() |  | 
|   592 { |  | 
|   593     // The icon database is disabled, so this should never be called. |  | 
|   594     ASSERT_NOT_REACHED(); |  | 
|   595 } |  | 
|   596  |  | 
|   597 void FrameLoaderClientImpl::dispatchDidStartProvisionalLoad() |  | 
|   598 { |  | 
|   599     // In case a redirect occurs, we need this to be set so that the redirect |  | 
|   600     // handling code can tell where the redirect came from. Server redirects |  | 
|   601     // will occur on the provisional load, so we need to keep track of the most |  | 
|   602     // recent provisional load URL. |  | 
|   603     // See dispatchDidReceiveServerRedirectForProvisionalLoad. |  | 
|   604     WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl(); |  | 
|   605     if (!ds) { |  | 
|   606         ASSERT_NOT_REACHED(); |  | 
|   607         return; |  | 
|   608     } |  | 
|   609     KURL url = ds->request().url(); |  | 
|   610  |  | 
|   611     // Since the provisional load just started, we should have not gotten |  | 
|   612     // any redirects yet. |  | 
|   613     ASSERT(!ds->hasRedirectChain()); |  | 
|   614  |  | 
|   615     // If this load is what we expected from a client redirect, treat it as a |  | 
|   616     // redirect from that original page. The expected redirect urls will be |  | 
|   617     // cleared by DidCancelClientRedirect. |  | 
|   618     bool completingClientRedirect = false; |  | 
|   619     if (m_expectedClientRedirectSrc.isValid()) { |  | 
|   620         // m_expectedClientRedirectDest could be something like |  | 
|   621         // "javascript:history.go(-1)" thus we need to exclude url starts with |  | 
|   622         // "javascript:". See bug: 1080873 |  | 
|   623         ASSERT(m_expectedClientRedirectDest.protocolIs("javascript") |  | 
|   624             || m_expectedClientRedirectDest == url); |  | 
|   625         ds->appendRedirect(m_expectedClientRedirectSrc); |  | 
|   626         completingClientRedirect = true; |  | 
|   627     } |  | 
|   628     ds->appendRedirect(url); |  | 
|   629  |  | 
|   630     if (m_webFrame->client()) { |  | 
|   631         // Whatever information didCompleteClientRedirect contains should only |  | 
|   632         // be considered relevant until the next provisional load has started. |  | 
|   633         // So we first tell the client that the load started, and then tell it |  | 
|   634         // about the client redirect the load is responsible for completing. |  | 
|   635         m_webFrame->client()->didStartProvisionalLoad(m_webFrame); |  | 
|   636         if (completingClientRedirect) { |  | 
|   637             m_webFrame->client()->didCompleteClientRedirect( |  | 
|   638                 m_webFrame, m_expectedClientRedirectSrc); |  | 
|   639         } |  | 
|   640     } |  | 
|   641 } |  | 
|   642  |  | 
|   643 void FrameLoaderClientImpl::dispatchDidReceiveTitle(const String& title) |  | 
|   644 { |  | 
|   645     if (m_webFrame->client()) |  | 
|   646         m_webFrame->client()->didReceiveTitle(m_webFrame, title); |  | 
|   647 } |  | 
|   648  |  | 
|   649 void FrameLoaderClientImpl::dispatchDidCommitLoad() |  | 
|   650 { |  | 
|   651     WebViewImpl* webview = m_webFrame->viewImpl(); |  | 
|   652     bool isNewNavigation; |  | 
|   653     webview->didCommitLoad(&isNewNavigation); |  | 
|   654  |  | 
|   655     if (m_webFrame->client()) |  | 
|   656         m_webFrame->client()->didCommitProvisionalLoad(m_webFrame, isNewNavigation); |  | 
|   657  |  | 
|   658     if (webview->devToolsAgentPrivate()) |  | 
|   659         webview->devToolsAgentPrivate()->didCommitProvisionalLoad(m_webFrame, isNewNavigation); |  | 
|   660 } |  | 
|   661  |  | 
|   662 void FrameLoaderClientImpl::dispatchDidFailProvisionalLoad( |  | 
|   663     const ResourceError& error) |  | 
|   664 { |  | 
|   665  |  | 
|   666     // If a policy change occured, then we do not want to inform the plugin |  | 
|   667     // delegate.  See http://b/907789 for details.  FIXME: This means the |  | 
|   668     // plugin won't receive NPP_URLNotify, which seems like it could result in |  | 
|   669     // a memory leak in the plugin!! |  | 
|   670     if (error.domain() == internalErrorDomain |  | 
|   671         && error.errorCode() == PolicyChangeError) { |  | 
|   672         m_webFrame->didFail(cancelledError(error.failingURL()), true); |  | 
|   673         return; |  | 
|   674     } |  | 
|   675  |  | 
|   676     OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver(); |  | 
|   677     m_webFrame->didFail(error, true); |  | 
|   678     if (observer) |  | 
|   679         observer->didFailLoading(error); |  | 
|   680 } |  | 
|   681  |  | 
|   682 void FrameLoaderClientImpl::dispatchDidFailLoad(const ResourceError& error) |  | 
|   683 { |  | 
|   684     OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver(); |  | 
|   685     m_webFrame->didFail(error, false); |  | 
|   686     if (observer) |  | 
|   687         observer->didFailLoading(error); |  | 
|   688  |  | 
|   689     // Don't clear the redirect chain, this will happen in the middle of client |  | 
|   690     // redirects, and we need the context. The chain will be cleared when the |  | 
|   691     // provisional load succeeds or fails, not the "real" one. |  | 
|   692 } |  | 
|   693  |  | 
|   694 void FrameLoaderClientImpl::dispatchDidFinishLoad() |  | 
|   695 { |  | 
|   696     OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver(); |  | 
|   697  |  | 
|   698     if (m_webFrame->client()) |  | 
|   699         m_webFrame->client()->didFinishLoad(m_webFrame); |  | 
|   700  |  | 
|   701     if (observer) |  | 
|   702         observer->didFinishLoading(); |  | 
|   703  |  | 
|   704     // Don't clear the redirect chain, this will happen in the middle of client |  | 
|   705     // redirects, and we need the context. The chain will be cleared when the |  | 
|   706     // provisional load succeeds or fails, not the "real" one. |  | 
|   707 } |  | 
|   708  |  | 
|   709 void FrameLoaderClientImpl::dispatchDidFirstLayout() |  | 
|   710 { |  | 
|   711 } |  | 
|   712  |  | 
|   713 void FrameLoaderClientImpl::dispatchDidFirstVisuallyNonEmptyLayout() |  | 
|   714 { |  | 
|   715     // FIXME: called when webkit finished layout of a page that was visually non-empty. |  | 
|   716     // All resources have not necessarily finished loading. |  | 
|   717 } |  | 
|   718  |  | 
|   719 Frame* FrameLoaderClientImpl::dispatchCreatePage() |  | 
|   720 { |  | 
|   721     struct WindowFeatures features; |  | 
|   722     Page* newPage = m_webFrame->frame()->page()->chrome()->createWindow( |  | 
|   723         m_webFrame->frame(), FrameLoadRequest(), features); |  | 
|   724  |  | 
|   725     // Make sure that we have a valid disposition.  This should have been set in |  | 
|   726     // the preceeding call to dispatchDecidePolicyForNewWindowAction. |  | 
|   727     ASSERT(m_nextNavigationPolicy != WebNavigationPolicyIgnore); |  | 
|   728     WebNavigationPolicy policy = m_nextNavigationPolicy; |  | 
|   729     m_nextNavigationPolicy = WebNavigationPolicyIgnore; |  | 
|   730  |  | 
|   731     // createWindow can return null (e.g., popup blocker denies the window). |  | 
|   732     if (!newPage) |  | 
|   733         return 0; |  | 
|   734  |  | 
|   735     WebViewImpl::fromPage(newPage)->setInitialNavigationPolicy(policy); |  | 
|   736     return newPage->mainFrame(); |  | 
|   737 } |  | 
|   738  |  | 
|   739 void FrameLoaderClientImpl::dispatchShow() |  | 
|   740 { |  | 
|   741     WebViewImpl* webView = m_webFrame->viewImpl(); |  | 
|   742     if (webView && webView->client()) |  | 
|   743         webView->client()->show(webView->initialNavigationPolicy()); |  | 
|   744 } |  | 
|   745  |  | 
|   746 static bool shouldTreatAsAttachment(const ResourceResponse& response) |  | 
|   747 { |  | 
|   748     const String& contentDisposition = |  | 
|   749         response.httpHeaderField("Content-Disposition"); |  | 
|   750     if (contentDisposition.isEmpty()) |  | 
|   751         return false; |  | 
|   752  |  | 
|   753     // Some broken sites just send |  | 
|   754     // Content-Disposition: ; filename="file" |  | 
|   755     // screen those out here. |  | 
|   756     if (contentDisposition.startsWith(";")) |  | 
|   757         return false; |  | 
|   758  |  | 
|   759     if (contentDisposition.startsWith("inline", false)) |  | 
|   760         return false; |  | 
|   761  |  | 
|   762     // Some broken sites just send |  | 
|   763     // Content-Disposition: filename="file" |  | 
|   764     // without a disposition token... screen those out. |  | 
|   765     if (contentDisposition.startsWith("filename", false)) |  | 
|   766         return false; |  | 
|   767  |  | 
|   768     // Also in use is Content-Disposition: name="file" |  | 
|   769     if (contentDisposition.startsWith("name", false)) |  | 
|   770         return false; |  | 
|   771  |  | 
|   772     // We have a content-disposition of "attachment" or unknown. |  | 
|   773     // RFC 2183, section 2.8 says that an unknown disposition |  | 
|   774     // value should be treated as "attachment" |  | 
|   775     return true; |  | 
|   776 } |  | 
|   777  |  | 
|   778 void FrameLoaderClientImpl::dispatchDecidePolicyForMIMEType( |  | 
|   779      FramePolicyFunction function, |  | 
|   780      const String& mimeType, |  | 
|   781      const ResourceRequest&) |  | 
|   782 { |  | 
|   783     const ResourceResponse& response = |  | 
|   784         m_webFrame->frame()->loader()->activeDocumentLoader()->response(); |  | 
|   785  |  | 
|   786     PolicyAction action; |  | 
|   787  |  | 
|   788     int statusCode = response.httpStatusCode(); |  | 
|   789     if (statusCode == 204 || statusCode == 205) { |  | 
|   790         // The server does not want us to replace the page contents. |  | 
|   791         action = PolicyIgnore; |  | 
|   792     } else if (shouldTreatAsAttachment(response)) { |  | 
|   793         // The server wants us to download instead of replacing the page contents. |  | 
|   794         // Downloading is handled by the embedder, but we still get the initial |  | 
|   795         // response so that we can ignore it and clean up properly. |  | 
|   796         action = PolicyIgnore; |  | 
|   797     } else if (!canShowMIMEType(mimeType)) { |  | 
|   798         // Make sure that we can actually handle this type internally. |  | 
|   799         action = PolicyIgnore; |  | 
|   800     } else { |  | 
|   801         // OK, we will render this page. |  | 
|   802         action = PolicyUse; |  | 
|   803     } |  | 
|   804  |  | 
|   805     // NOTE: PolicyChangeError will be generated when action is not PolicyUse. |  | 
|   806     (m_webFrame->frame()->loader()->policyChecker()->*function)(action); |  | 
|   807 } |  | 
|   808  |  | 
|   809 void FrameLoaderClientImpl::dispatchDecidePolicyForNewWindowAction( |  | 
|   810     FramePolicyFunction function, |  | 
|   811     const NavigationAction& action, |  | 
|   812     const ResourceRequest& request, |  | 
|   813     PassRefPtr<FormState> formState, |  | 
|   814     const String& frameName) |  | 
|   815 { |  | 
|   816     WebNavigationPolicy navigationPolicy; |  | 
|   817     if (!actionSpecifiesNavigationPolicy(action, &navigationPolicy)) |  | 
|   818         navigationPolicy = WebNavigationPolicyNewForegroundTab; |  | 
|   819  |  | 
|   820     PolicyAction policyAction; |  | 
|   821     if (navigationPolicy == WebNavigationPolicyDownload) |  | 
|   822         policyAction = PolicyDownload; |  | 
|   823     else { |  | 
|   824         policyAction = PolicyUse; |  | 
|   825  |  | 
|   826         // Remember the disposition for when dispatchCreatePage is called.  It is |  | 
|   827         // unfortunate that WebCore does not provide us with any context when |  | 
|   828         // creating or showing the new window that would allow us to avoid having |  | 
|   829         // to keep this state. |  | 
|   830         m_nextNavigationPolicy = navigationPolicy; |  | 
|   831     } |  | 
|   832     (m_webFrame->frame()->loader()->policyChecker()->*function)(policyAction); |  | 
|   833 } |  | 
|   834  |  | 
|   835 void FrameLoaderClientImpl::dispatchDecidePolicyForNavigationAction( |  | 
|   836     FramePolicyFunction function, |  | 
|   837     const NavigationAction& action, |  | 
|   838     const ResourceRequest& request, |  | 
|   839     PassRefPtr<FormState> formState) { |  | 
|   840     PolicyAction policyAction = PolicyIgnore; |  | 
|   841  |  | 
|   842     // It is valid for this function to be invoked in code paths where the |  | 
|   843     // the webview is closed. |  | 
|   844     // The null check here is to fix a crash that seems strange |  | 
|   845     // (see - https://bugs.webkit.org/show_bug.cgi?id=23554). |  | 
|   846     if (m_webFrame->client() && !request.url().isNull()) { |  | 
|   847       WebNavigationPolicy navigationPolicy = WebNavigationPolicyCurrentTab; |  | 
|   848       actionSpecifiesNavigationPolicy(action, &navigationPolicy); |  | 
|   849  |  | 
|   850       // Give the delegate a chance to change the navigation policy. |  | 
|   851       const WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl(); |  | 
|   852       if (ds) { |  | 
|   853           KURL url = ds->request().url(); |  | 
|   854           if (url.protocolIs(backForwardNavigationScheme)) { |  | 
|   855               handleBackForwardNavigation(url); |  | 
|   856               navigationPolicy = WebNavigationPolicyIgnore; |  | 
|   857           } else { |  | 
|   858               bool isRedirect = ds->hasRedirectChain(); |  | 
|   859  |  | 
|   860               WebNavigationType webnavType = |  | 
|   861                   WebDataSourceImpl::toWebNavigationType(action.type()); |  | 
|   862  |  | 
|   863               RefPtr<Node> node; |  | 
|   864               for (const Event* event = action.event(); event; event = event->underlyingEvent()) { |  | 
|   865                   if (event->isMouseEvent()) { |  | 
|   866                       const MouseEvent* mouseEvent = |  | 
|   867                           static_cast<const MouseEvent*>(event); |  | 
|   868                       node = m_webFrame->frame()->eventHandler()->hitTestResultAtPoint( |  | 
|   869                           mouseEvent->absoluteLocation(), false).innerNonSharedNode(); |  | 
|   870                       break; |  | 
|   871                   } |  | 
|   872               } |  | 
|   873               WebNode originatingNode(node); |  | 
|   874  |  | 
|   875               navigationPolicy = m_webFrame->client()->decidePolicyForNavigation( |  | 
|   876                   m_webFrame, ds->request(), webnavType, originatingNode, |  | 
|   877                   navigationPolicy, isRedirect); |  | 
|   878           } |  | 
|   879       } |  | 
|   880  |  | 
|   881       if (navigationPolicy == WebNavigationPolicyCurrentTab) |  | 
|   882           policyAction = PolicyUse; |  | 
|   883       else if (navigationPolicy == WebNavigationPolicyDownload) |  | 
|   884           policyAction = PolicyDownload; |  | 
|   885       else { |  | 
|   886           if (navigationPolicy != WebNavigationPolicyIgnore) { |  | 
|   887               WrappedResourceRequest webreq(request); |  | 
|   888               m_webFrame->client()->loadURLExternally(m_webFrame, webreq, navigationPolicy); |  | 
|   889           } |  | 
|   890           policyAction = PolicyIgnore; |  | 
|   891       } |  | 
|   892     } |  | 
|   893  |  | 
|   894     (m_webFrame->frame()->loader()->policyChecker()->*function)(policyAction); |  | 
|   895 } |  | 
|   896  |  | 
|   897 void FrameLoaderClientImpl::cancelPolicyCheck() |  | 
|   898 { |  | 
|   899     // FIXME |  | 
|   900 } |  | 
|   901  |  | 
|   902 void FrameLoaderClientImpl::dispatchUnableToImplementPolicy(const ResourceError& error) |  | 
|   903 { |  | 
|   904     m_webFrame->client()->unableToImplementPolicyWithError(m_webFrame, error); |  | 
|   905 } |  | 
|   906  |  | 
|   907 void FrameLoaderClientImpl::dispatchWillSubmitForm(FramePolicyFunction function, |  | 
|   908     PassRefPtr<FormState> formState) |  | 
|   909 { |  | 
|   910     if (m_webFrame->client()) |  | 
|   911         m_webFrame->client()->willSubmitForm(m_webFrame, WebFormElement(formState->form())); |  | 
|   912     (m_webFrame->frame()->loader()->policyChecker()->*function)(PolicyUse); |  | 
|   913 } |  | 
|   914  |  | 
|   915 void FrameLoaderClientImpl::dispatchDidLoadMainResource(DocumentLoader*) |  | 
|   916 { |  | 
|   917     // FIXME |  | 
|   918 } |  | 
|   919  |  | 
|   920 void FrameLoaderClientImpl::revertToProvisionalState(DocumentLoader*) |  | 
|   921 { |  | 
|   922     m_hasRepresentation = true; |  | 
|   923 } |  | 
|   924  |  | 
|   925 void FrameLoaderClientImpl::setMainDocumentError(DocumentLoader*, |  | 
|   926                                                  const ResourceError& error) |  | 
|   927 { |  | 
|   928     if (m_pluginWidget.get()) { |  | 
|   929         if (m_sentInitialResponseToPlugin) { |  | 
|   930             m_pluginWidget->didFailLoading(error); |  | 
|   931             m_sentInitialResponseToPlugin = false; |  | 
|   932         } |  | 
|   933         m_pluginWidget = 0; |  | 
|   934     } |  | 
|   935 } |  | 
|   936  |  | 
|   937 void FrameLoaderClientImpl::postProgressStartedNotification() |  | 
|   938 { |  | 
|   939     WebViewImpl* webview = m_webFrame->viewImpl(); |  | 
|   940     if (webview && webview->client()) |  | 
|   941         webview->client()->didStartLoading(); |  | 
|   942 } |  | 
|   943  |  | 
|   944 void FrameLoaderClientImpl::postProgressEstimateChangedNotification() |  | 
|   945 { |  | 
|   946     // FIXME |  | 
|   947 } |  | 
|   948  |  | 
|   949 void FrameLoaderClientImpl::postProgressFinishedNotification() |  | 
|   950 { |  | 
|   951     // FIXME: why might the webview be null?  http://b/1234461 |  | 
|   952     WebViewImpl* webview = m_webFrame->viewImpl(); |  | 
|   953     if (webview && webview->client()) |  | 
|   954         webview->client()->didStopLoading(); |  | 
|   955 } |  | 
|   956  |  | 
|   957 void FrameLoaderClientImpl::setMainFrameDocumentReady(bool ready) |  | 
|   958 { |  | 
|   959     // FIXME |  | 
|   960 } |  | 
|   961  |  | 
|   962 // Creates a new connection and begins downloading from that (contrast this |  | 
|   963 // with |download|). |  | 
|   964 void FrameLoaderClientImpl::startDownload(const ResourceRequest& request) |  | 
|   965 { |  | 
|   966     if (m_webFrame->client()) { |  | 
|   967         WrappedResourceRequest webreq(request); |  | 
|   968         m_webFrame->client()->loadURLExternally( |  | 
|   969             m_webFrame, webreq, WebNavigationPolicyDownload); |  | 
|   970     } |  | 
|   971 } |  | 
|   972  |  | 
|   973 void FrameLoaderClientImpl::willChangeTitle(DocumentLoader*) |  | 
|   974 { |  | 
|   975     // FIXME |  | 
|   976 } |  | 
|   977  |  | 
|   978 void FrameLoaderClientImpl::didChangeTitle(DocumentLoader*) |  | 
|   979 { |  | 
|   980     // FIXME |  | 
|   981 } |  | 
|   982  |  | 
|   983 // Called whenever data is received. |  | 
|   984 void FrameLoaderClientImpl::committedLoad(DocumentLoader* loader, const char* data, int length) |  | 
|   985 { |  | 
|   986     if (!m_pluginWidget.get()) { |  | 
|   987         if (m_webFrame->client()) { |  | 
|   988             bool preventDefault = false; |  | 
|   989             m_webFrame->client()->didReceiveDocumentData(m_webFrame, data, length, preventDefault); |  | 
|   990             if (!preventDefault) |  | 
|   991                 m_webFrame->commitDocumentData(data, length); |  | 
|   992         } |  | 
|   993     } |  | 
|   994  |  | 
|   995     // If we are sending data to MediaDocument, we should stop here |  | 
|   996     // and cancel the request. |  | 
|   997     if (m_webFrame->frame()->document() |  | 
|   998         && m_webFrame->frame()->document()->isMediaDocument()) |  | 
|   999         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response())); |  | 
|  1000  |  | 
|  1001     // The plugin widget could have been created in the m_webFrame->DidReceiveData |  | 
|  1002     // function. |  | 
|  1003     if (m_pluginWidget.get()) { |  | 
|  1004         if (!m_sentInitialResponseToPlugin) { |  | 
|  1005             m_sentInitialResponseToPlugin = true; |  | 
|  1006             m_pluginWidget->didReceiveResponse( |  | 
|  1007                 m_webFrame->frame()->loader()->activeDocumentLoader()->response()); |  | 
|  1008         } |  | 
|  1009         m_pluginWidget->didReceiveData(data, length); |  | 
|  1010     } |  | 
|  1011 } |  | 
|  1012  |  | 
|  1013 void FrameLoaderClientImpl::finishedLoading(DocumentLoader* dl) |  | 
|  1014 { |  | 
|  1015     if (m_pluginWidget.get()) { |  | 
|  1016         m_pluginWidget->didFinishLoading(); |  | 
|  1017         m_pluginWidget = 0; |  | 
|  1018         m_sentInitialResponseToPlugin = false; |  | 
|  1019     } else { |  | 
|  1020         // This is necessary to create an empty document. See bug 634004. |  | 
|  1021         // However, we only want to do this if makeRepresentation has been called, to |  | 
|  1022         // match the behavior on the Mac. |  | 
|  1023         if (m_hasRepresentation) |  | 
|  1024             dl->frameLoader()->setEncoding("", false); |  | 
|  1025     } |  | 
|  1026 } |  | 
|  1027  |  | 
|  1028 void FrameLoaderClientImpl::updateGlobalHistory() |  | 
|  1029 { |  | 
|  1030 } |  | 
|  1031  |  | 
|  1032 void FrameLoaderClientImpl::updateGlobalHistoryRedirectLinks() |  | 
|  1033 { |  | 
|  1034 } |  | 
|  1035  |  | 
|  1036 bool FrameLoaderClientImpl::shouldGoToHistoryItem(HistoryItem*) const |  | 
|  1037 { |  | 
|  1038     // FIXME |  | 
|  1039     return true; |  | 
|  1040 } |  | 
|  1041  |  | 
|  1042 void FrameLoaderClientImpl::didDisplayInsecureContent() |  | 
|  1043 { |  | 
|  1044     if (m_webFrame->client()) |  | 
|  1045         m_webFrame->client()->didDisplayInsecureContent(m_webFrame); |  | 
|  1046 } |  | 
|  1047  |  | 
|  1048 void FrameLoaderClientImpl::didRunInsecureContent(SecurityOrigin* origin) |  | 
|  1049 { |  | 
|  1050     if (m_webFrame->client()) |  | 
|  1051         m_webFrame->client()->didRunInsecureContent(m_webFrame, WebSecurityOrigin(origin)); |  | 
|  1052 } |  | 
|  1053  |  | 
|  1054 ResourceError FrameLoaderClientImpl::blockedError(const ResourceRequest&) |  | 
|  1055 { |  | 
|  1056     // FIXME |  | 
|  1057     return ResourceError(); |  | 
|  1058 } |  | 
|  1059  |  | 
|  1060 ResourceError FrameLoaderClientImpl::cancelledError(const ResourceRequest& request) |  | 
|  1061 { |  | 
|  1062     if (!m_webFrame->client()) |  | 
|  1063         return ResourceError(); |  | 
|  1064  |  | 
|  1065     return m_webFrame->client()->cancelledError( |  | 
|  1066         m_webFrame, WrappedResourceRequest(request)); |  | 
|  1067 } |  | 
|  1068  |  | 
|  1069 ResourceError FrameLoaderClientImpl::cannotShowURLError(const ResourceRequest& request) |  | 
|  1070 { |  | 
|  1071     if (!m_webFrame->client()) |  | 
|  1072         return ResourceError(); |  | 
|  1073  |  | 
|  1074     return m_webFrame->client()->cannotHandleRequestError( |  | 
|  1075         m_webFrame, WrappedResourceRequest(request)); |  | 
|  1076 } |  | 
|  1077  |  | 
|  1078 ResourceError FrameLoaderClientImpl::interruptForPolicyChangeError( |  | 
|  1079     const ResourceRequest& request) |  | 
|  1080 { |  | 
|  1081     return ResourceError(internalErrorDomain, PolicyChangeError, |  | 
|  1082                          request.url().string(), String()); |  | 
|  1083 } |  | 
|  1084  |  | 
|  1085 ResourceError FrameLoaderClientImpl::cannotShowMIMETypeError(const ResourceResponse&) |  | 
|  1086 { |  | 
|  1087     // FIXME |  | 
|  1088     return ResourceError(); |  | 
|  1089 } |  | 
|  1090  |  | 
|  1091 ResourceError FrameLoaderClientImpl::fileDoesNotExistError(const ResourceResponse&) |  | 
|  1092 { |  | 
|  1093     // FIXME |  | 
|  1094     return ResourceError(); |  | 
|  1095 } |  | 
|  1096  |  | 
|  1097 ResourceError FrameLoaderClientImpl::pluginWillHandleLoadError(const ResourceResponse&) |  | 
|  1098 { |  | 
|  1099     // FIXME |  | 
|  1100     return ResourceError(); |  | 
|  1101 } |  | 
|  1102  |  | 
|  1103 bool FrameLoaderClientImpl::shouldFallBack(const ResourceError& error) |  | 
|  1104 { |  | 
|  1105     // This method is called when we fail to load the URL for an <object> tag |  | 
|  1106     // that has fallback content (child elements) and is being loaded as a frame. |  | 
|  1107     // The error parameter indicates the reason for the load failure. |  | 
|  1108     // We should let the fallback content load only if this wasn't a cancelled |  | 
|  1109     // request. |  | 
|  1110     // Note: The mac version also has a case for "WebKitErrorPluginWillHandleLoad" |  | 
|  1111     ResourceError c = cancelledError(ResourceRequest()); |  | 
|  1112     return error.errorCode() != c.errorCode() || error.domain() != c.domain(); |  | 
|  1113 } |  | 
|  1114  |  | 
|  1115 bool FrameLoaderClientImpl::canHandleRequest(const ResourceRequest& request) const |  | 
|  1116 { |  | 
|  1117     return m_webFrame->client()->canHandleRequest( |  | 
|  1118         m_webFrame, WrappedResourceRequest(request)); |  | 
|  1119 } |  | 
|  1120  |  | 
|  1121 bool FrameLoaderClientImpl::canShowMIMEType(const String& mimeType) const |  | 
|  1122 { |  | 
|  1123     // This method is called to determine if the media type can be shown |  | 
|  1124     // "internally" (i.e. inside the browser) regardless of whether or not the |  | 
|  1125     // browser or a plugin is doing the rendering. |  | 
|  1126  |  | 
|  1127     // mimeType strings are supposed to be ASCII, but if they are not for some |  | 
|  1128     // reason, then it just means that the mime type will fail all of these "is |  | 
|  1129     // supported" checks and go down the path of an unhandled mime type. |  | 
|  1130     if (webKitClient()->mimeRegistry()->supportsMIMEType(mimeType) == WebMimeRegistry::IsSupported) |  | 
|  1131         return true; |  | 
|  1132  |  | 
|  1133     // If Chrome is started with the --disable-plugins switch, pluginData is null. |  | 
|  1134     PluginData* pluginData = m_webFrame->frame()->page()->pluginData(); |  | 
|  1135  |  | 
|  1136     // See if the type is handled by an installed plugin, if so, we can show it. |  | 
|  1137     // FIXME: (http://b/1085524) This is the place to stick a preference to |  | 
|  1138     //        disable full page plugins (optionally for certain types!) |  | 
|  1139     return !mimeType.isEmpty() && pluginData && pluginData->supportsMimeType(mimeType); |  | 
|  1140 } |  | 
|  1141  |  | 
|  1142 bool FrameLoaderClientImpl::representationExistsForURLScheme(const String&) const |  | 
|  1143 { |  | 
|  1144     // FIXME |  | 
|  1145     return false; |  | 
|  1146 } |  | 
|  1147  |  | 
|  1148 String FrameLoaderClientImpl::generatedMIMETypeForURLScheme(const String& scheme) const |  | 
|  1149 { |  | 
|  1150     // This appears to generate MIME types for protocol handlers that are handled |  | 
|  1151     // internally. The only place I can find in the WebKit code that uses this |  | 
|  1152     // function is WebView::registerViewClass, where it is used as part of the |  | 
|  1153     // process by which custom view classes for certain document representations |  | 
|  1154     // are registered. |  | 
|  1155     String mimeType("x-apple-web-kit/"); |  | 
|  1156     mimeType.append(scheme.lower()); |  | 
|  1157     return mimeType; |  | 
|  1158 } |  | 
|  1159  |  | 
|  1160 void FrameLoaderClientImpl::frameLoadCompleted() |  | 
|  1161 { |  | 
|  1162     // FIXME: the mac port also conditionally calls setDrawsBackground:YES on |  | 
|  1163     // it's ScrollView here. |  | 
|  1164  |  | 
|  1165     // This comment from the Mac port: |  | 
|  1166     // Note: Can be called multiple times. |  | 
|  1167     // Even if already complete, we might have set a previous item on a frame that |  | 
|  1168     // didn't do any data loading on the past transaction. Make sure to clear these out. |  | 
|  1169  |  | 
|  1170     // FIXME: setPreviousHistoryItem() no longer exists. http://crbug.com/8566 |  | 
|  1171     // m_webFrame->frame()->loader()->setPreviousHistoryItem(0); |  | 
|  1172 } |  | 
|  1173  |  | 
|  1174 void FrameLoaderClientImpl::saveViewStateToItem(HistoryItem*) |  | 
|  1175 { |  | 
|  1176     // FIXME |  | 
|  1177 } |  | 
|  1178  |  | 
|  1179 void FrameLoaderClientImpl::restoreViewState() |  | 
|  1180 { |  | 
|  1181     // FIXME: probably scrolls to last position when you go back or forward |  | 
|  1182 } |  | 
|  1183  |  | 
|  1184 void FrameLoaderClientImpl::provisionalLoadStarted() |  | 
|  1185 { |  | 
|  1186     // FIXME: On mac, this does various caching stuff |  | 
|  1187 } |  | 
|  1188  |  | 
|  1189 void FrameLoaderClientImpl::didFinishLoad() |  | 
|  1190 { |  | 
|  1191     OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver(); |  | 
|  1192     if (observer) |  | 
|  1193         observer->didFinishLoading(); |  | 
|  1194 } |  | 
|  1195  |  | 
|  1196 void FrameLoaderClientImpl::prepareForDataSourceReplacement() |  | 
|  1197 { |  | 
|  1198     // FIXME |  | 
|  1199 } |  | 
|  1200  |  | 
|  1201 PassRefPtr<DocumentLoader> FrameLoaderClientImpl::createDocumentLoader( |  | 
|  1202     const ResourceRequest& request, |  | 
|  1203     const SubstituteData& data) |  | 
|  1204 { |  | 
|  1205     RefPtr<WebDataSourceImpl> ds = WebDataSourceImpl::create(request, data); |  | 
|  1206     if (m_webFrame->client()) |  | 
|  1207         m_webFrame->client()->didCreateDataSource(m_webFrame, ds.get()); |  | 
|  1208     return ds.release(); |  | 
|  1209 } |  | 
|  1210  |  | 
|  1211 void FrameLoaderClientImpl::setTitle(const String& title, const KURL& url) |  | 
|  1212 { |  | 
|  1213     // FIXME: inform consumer of changes to the title. |  | 
|  1214 } |  | 
|  1215  |  | 
|  1216 String FrameLoaderClientImpl::userAgent(const KURL& url) |  | 
|  1217 { |  | 
|  1218     return webKitClient()->userAgent(url); |  | 
|  1219 } |  | 
|  1220  |  | 
|  1221 void FrameLoaderClientImpl::savePlatformDataToCachedFrame(CachedFrame*) |  | 
|  1222 { |  | 
|  1223     // The page cache should be disabled. |  | 
|  1224     ASSERT_NOT_REACHED(); |  | 
|  1225 } |  | 
|  1226  |  | 
|  1227 void FrameLoaderClientImpl::transitionToCommittedFromCachedFrame(CachedFrame*) |  | 
|  1228 { |  | 
|  1229     ASSERT_NOT_REACHED(); |  | 
|  1230 } |  | 
|  1231  |  | 
|  1232 // Called when the FrameLoader goes into a state in which a new page load |  | 
|  1233 // will occur. |  | 
|  1234 void FrameLoaderClientImpl::transitionToCommittedForNewPage() |  | 
|  1235 { |  | 
|  1236     makeDocumentView(); |  | 
|  1237 } |  | 
|  1238  |  | 
|  1239 bool FrameLoaderClientImpl::canCachePage() const |  | 
|  1240 { |  | 
|  1241     // Since we manage the cache, always report this page as non-cacheable to |  | 
|  1242     // FrameLoader. |  | 
|  1243     return false; |  | 
|  1244 } |  | 
|  1245  |  | 
|  1246 // Downloading is handled in the browser process, not WebKit. If we get to this |  | 
|  1247 // point, our download detection code in the ResourceDispatcherHost is broken! |  | 
|  1248 void FrameLoaderClientImpl::download(ResourceHandle* handle, |  | 
|  1249                                      const ResourceRequest& request, |  | 
|  1250                                      const ResourceRequest& initialRequest, |  | 
|  1251                                      const ResourceResponse& response) |  | 
|  1252 { |  | 
|  1253     ASSERT_NOT_REACHED(); |  | 
|  1254 } |  | 
|  1255  |  | 
|  1256 PassRefPtr<Frame> FrameLoaderClientImpl::createFrame( |  | 
|  1257     const KURL& url, |  | 
|  1258     const String& name, |  | 
|  1259     HTMLFrameOwnerElement* ownerElement, |  | 
|  1260     const String& referrer, |  | 
|  1261     bool allowsScrolling, |  | 
|  1262     int marginWidth, |  | 
|  1263     int marginHeight) |  | 
|  1264 { |  | 
|  1265     FrameLoadRequest frameRequest(ResourceRequest(url, referrer), name); |  | 
|  1266     return m_webFrame->createChildFrame(frameRequest, ownerElement); |  | 
|  1267 } |  | 
|  1268  |  | 
|  1269 PassRefPtr<Widget> FrameLoaderClientImpl::createPlugin( |  | 
|  1270     const IntSize& size, // FIXME: how do we use this? |  | 
|  1271     HTMLPlugInElement* element, |  | 
|  1272     const KURL& url, |  | 
|  1273     const Vector<String>& paramNames, |  | 
|  1274     const Vector<String>& paramValues, |  | 
|  1275     const String& mimeType, |  | 
|  1276     bool loadManually) |  | 
|  1277 { |  | 
|  1278 #if !PLATFORM(WIN_OS) |  | 
|  1279     // WebCore asks us to make a plugin even if we don't have a |  | 
|  1280     // registered handler, with a comment saying it's so we can display |  | 
|  1281     // the broken plugin icon.  In Chromium, we normally register a |  | 
|  1282     // fallback plugin handler that allows you to install a missing |  | 
|  1283     // plugin.  Since we don't yet have a default plugin handler, we |  | 
|  1284     // need to return null here rather than going through all the |  | 
|  1285     // plugin-creation IPCs only to discover we don't have a plugin |  | 
|  1286     // registered, which causes a crash. |  | 
|  1287     // FIXME: remove me once we have a default plugin. |  | 
|  1288     if (objectContentType(url, mimeType) != ObjectContentNetscapePlugin) |  | 
|  1289         return 0; |  | 
|  1290 #endif |  | 
|  1291  |  | 
|  1292     if (!m_webFrame->client()) |  | 
|  1293         return 0; |  | 
|  1294  |  | 
|  1295     WebPluginParams params; |  | 
|  1296     params.url = url; |  | 
|  1297     params.mimeType = mimeType; |  | 
|  1298     params.attributeNames = paramNames; |  | 
|  1299     params.attributeValues = paramValues; |  | 
|  1300     params.loadManually = loadManually; |  | 
|  1301  |  | 
|  1302     WebPlugin* webPlugin = m_webFrame->client()->createPlugin(m_webFrame, params); |  | 
|  1303     if (!webPlugin) |  | 
|  1304         return 0; |  | 
|  1305  |  | 
|  1306     // The container takes ownership of the WebPlugin. |  | 
|  1307     RefPtr<WebPluginContainerImpl> container = |  | 
|  1308         WebPluginContainerImpl::create(element, webPlugin); |  | 
|  1309  |  | 
|  1310     if (!webPlugin->initialize(container.get())) |  | 
|  1311         return 0; |  | 
|  1312  |  | 
|  1313     // The element might have been removed during plugin initialization! |  | 
|  1314     if (!element->renderer()) |  | 
|  1315         return 0; |  | 
|  1316  |  | 
|  1317     return container; |  | 
|  1318 } |  | 
|  1319  |  | 
|  1320 // This method gets called when a plugin is put in place of html content |  | 
|  1321 // (e.g., acrobat reader). |  | 
|  1322 void FrameLoaderClientImpl::redirectDataToPlugin(Widget* pluginWidget) |  | 
|  1323 { |  | 
|  1324     m_pluginWidget = static_cast<WebPluginContainerImpl*>(pluginWidget); |  | 
|  1325     ASSERT(m_pluginWidget.get()); |  | 
|  1326 } |  | 
|  1327  |  | 
|  1328 PassRefPtr<Widget> FrameLoaderClientImpl::createJavaAppletWidget( |  | 
|  1329     const IntSize& size, |  | 
|  1330     HTMLAppletElement* element, |  | 
|  1331     const KURL& /* baseURL */, |  | 
|  1332     const Vector<String>& paramNames, |  | 
|  1333     const Vector<String>& paramValues) |  | 
|  1334 { |  | 
|  1335     return createPlugin(size, element, KURL(), paramNames, paramValues, |  | 
|  1336         "application/x-java-applet", false); |  | 
|  1337 } |  | 
|  1338  |  | 
|  1339 ObjectContentType FrameLoaderClientImpl::objectContentType( |  | 
|  1340     const KURL& url, |  | 
|  1341     const String& explicitMimeType) |  | 
|  1342 { |  | 
|  1343     // This code is based on Apple's implementation from |  | 
|  1344     // WebCoreSupport/WebFrameBridge.mm. |  | 
|  1345  |  | 
|  1346     String mimeType = explicitMimeType; |  | 
|  1347     if (mimeType.isEmpty()) { |  | 
|  1348         // Try to guess the MIME type based off the extension. |  | 
|  1349         String filename = url.lastPathComponent(); |  | 
|  1350         int extensionPos = filename.reverseFind('.'); |  | 
|  1351         if (extensionPos >= 0) |  | 
|  1352             mimeType = MIMETypeRegistry::getMIMETypeForPath(url.path()); |  | 
|  1353  |  | 
|  1354         if (mimeType.isEmpty()) |  | 
|  1355             return ObjectContentFrame; |  | 
|  1356     } |  | 
|  1357  |  | 
|  1358     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) |  | 
|  1359         return ObjectContentImage; |  | 
|  1360  |  | 
|  1361     // If Chrome is started with the --disable-plugins switch, pluginData is 0. |  | 
|  1362     PluginData* pluginData = m_webFrame->frame()->page()->pluginData(); |  | 
|  1363     if (pluginData && pluginData->supportsMimeType(mimeType)) |  | 
|  1364         return ObjectContentNetscapePlugin; |  | 
|  1365  |  | 
|  1366     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType)) |  | 
|  1367         return ObjectContentFrame; |  | 
|  1368  |  | 
|  1369     return ObjectContentNone; |  | 
|  1370 } |  | 
|  1371  |  | 
|  1372 String FrameLoaderClientImpl::overrideMediaType() const |  | 
|  1373 { |  | 
|  1374     // FIXME |  | 
|  1375     return String(); |  | 
|  1376 } |  | 
|  1377  |  | 
|  1378 bool FrameLoaderClientImpl::actionSpecifiesNavigationPolicy( |  | 
|  1379     const NavigationAction& action, |  | 
|  1380     WebNavigationPolicy* policy) |  | 
|  1381 { |  | 
|  1382     if ((action.type() != NavigationTypeLinkClicked) || !action.event()->isMouseEvent()) |  | 
|  1383         return false; |  | 
|  1384  |  | 
|  1385     const MouseEvent* event = static_cast<const MouseEvent*>(action.event()); |  | 
|  1386     return WebViewImpl::navigationPolicyFromMouseEvent( |  | 
|  1387         event->button(), event->ctrlKey(), event->shiftKey(), event->altKey(), |  | 
|  1388         event->metaKey(), policy); |  | 
|  1389 } |  | 
|  1390  |  | 
|  1391 void FrameLoaderClientImpl::handleBackForwardNavigation(const KURL& url) |  | 
|  1392 { |  | 
|  1393     ASSERT(url.protocolIs(backForwardNavigationScheme)); |  | 
|  1394  |  | 
|  1395     bool ok; |  | 
|  1396     int offset = url.lastPathComponent().toIntStrict(&ok); |  | 
|  1397     if (!ok) |  | 
|  1398         return; |  | 
|  1399  |  | 
|  1400     WebViewImpl* webview = m_webFrame->viewImpl(); |  | 
|  1401     if (webview->client()) |  | 
|  1402         webview->client()->navigateBackForwardSoon(offset); |  | 
|  1403 } |  | 
|  1404  |  | 
|  1405 PassOwnPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver() |  | 
|  1406 { |  | 
|  1407     WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader( |  | 
|  1408         m_webFrame->frame()->loader()->activeDocumentLoader()); |  | 
|  1409     return ds->releasePluginLoadObserver(); |  | 
|  1410 } |  | 
|  1411  |  | 
|  1412 } // namespace WebKit |  | 
| OLD | NEW |