Home | History | Annotate | Download | only in WebCoreSupport
      1 /*
      2  * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple 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
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #import "WebFrameLoaderClient.h"
     30 
     31 // Terrible hack; lets us get at the WebFrame private structure.
     32 #define private public
     33 #import "WebFrame.h"
     34 #undef private
     35 
     36 #import "DOMElementInternal.h"
     37 #import "WebBackForwardList.h"
     38 #import "WebCachedFramePlatformData.h"
     39 #import "WebChromeClient.h"
     40 #import "WebDataSourceInternal.h"
     41 #import "WebDelegateImplementationCaching.h"
     42 #import "WebDocumentInternal.h"
     43 #import "WebDocumentLoaderMac.h"
     44 #import "WebDownloadInternal.h"
     45 #import "WebDynamicScrollBarsViewInternal.h"
     46 #import "WebElementDictionary.h"
     47 #import "WebFormDelegate.h"
     48 #import "WebFrameInternal.h"
     49 #import "WebFrameLoadDelegate.h"
     50 #import "WebFrameNetworkingContext.h"
     51 #import "WebFrameViewInternal.h"
     52 #import "WebHTMLRepresentationPrivate.h"
     53 #import "WebHTMLViewInternal.h"
     54 #import "WebHistoryInternal.h"
     55 #import "WebHistoryItemInternal.h"
     56 #import "WebIconDatabaseInternal.h"
     57 #import "WebKitErrorsPrivate.h"
     58 #import "WebKitLogging.h"
     59 #import "WebKitNSStringExtras.h"
     60 #import "WebNSURLExtras.h"
     61 #import "WebNavigationData.h"
     62 #import "WebNetscapePluginPackage.h"
     63 #import "WebNetscapePluginView.h"
     64 #import "WebPanelAuthenticationHandler.h"
     65 #import "WebPluginController.h"
     66 #import "WebPluginPackage.h"
     67 #import "WebPluginViewFactoryPrivate.h"
     68 #import "WebPolicyDelegate.h"
     69 #import "WebPolicyDelegatePrivate.h"
     70 #import "WebPreferences.h"
     71 #import "WebResourceLoadDelegate.h"
     72 #import "WebScriptWorldInternal.h"
     73 #import "WebSecurityOriginInternal.h"
     74 #import "WebUIDelegate.h"
     75 #import "WebUIDelegatePrivate.h"
     76 #import "WebViewInternal.h"
     77 #import <WebCore/AuthenticationMac.h>
     78 #import <WebCore/BackForwardController.h>
     79 #import <WebCore/BlockExceptions.h>
     80 #import <WebCore/CachedFrame.h>
     81 #import <WebCore/Chrome.h>
     82 #import <WebCore/Document.h>
     83 #import <WebCore/DocumentLoader.h>
     84 #import <WebCore/EventHandler.h>
     85 #import <WebCore/FocusController.h>
     86 #import <WebCore/FormState.h>
     87 #import <WebCore/Frame.h>
     88 #import <WebCore/FrameLoader.h>
     89 #import <WebCore/FrameLoaderStateMachine.h>
     90 #import <WebCore/FrameLoaderTypes.h>
     91 #import <WebCore/FrameTree.h>
     92 #import <WebCore/FrameView.h>
     93 #import <WebCore/HTMLAppletElement.h>
     94 #import <WebCore/HTMLFormElement.h>
     95 #import <WebCore/HTMLFrameElement.h>
     96 #import <WebCore/HTMLFrameOwnerElement.h>
     97 #import <WebCore/HTMLHeadElement.h>
     98 #import <WebCore/HTMLNames.h>
     99 #import <WebCore/HTMLParserIdioms.h>
    100 #import <WebCore/HTMLPlugInElement.h>
    101 #import <WebCore/HistoryItem.h>
    102 #import <WebCore/HitTestResult.h>
    103 #import <WebCore/IconDatabase.h>
    104 #import <WebCore/LoaderNSURLExtras.h>
    105 #import <WebCore/MIMETypeRegistry.h>
    106 #import <WebCore/MouseEvent.h>
    107 #import <WebCore/Page.h>
    108 #import <WebCore/PlatformString.h>
    109 #import <WebCore/PluginViewBase.h>
    110 #import <WebCore/ResourceError.h>
    111 #import <WebCore/ResourceHandle.h>
    112 #import <WebCore/ResourceLoader.h>
    113 #import <WebCore/ResourceRequest.h>
    114 #import <WebCore/ScriptController.h>
    115 #import <WebCore/SharedBuffer.h>
    116 #import <WebCore/WebCoreObjCExtras.h>
    117 #import <WebCore/Widget.h>
    118 #import <WebKit/DOMElement.h>
    119 #import <WebKit/DOMHTMLFormElement.h>
    120 #import <WebKitSystemInterface.h>
    121 #import <runtime/InitializeThreading.h>
    122 #import <wtf/PassRefPtr.h>
    123 #import <wtf/Threading.h>
    124 
    125 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
    126 #import <WebCore/HTMLMediaElement.h>
    127 #endif
    128 
    129 #if ENABLE(JAVA_BRIDGE)
    130 #import "WebJavaPlugIn.h"
    131 #endif
    132 
    133 #if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
    134 #import "NetscapePluginHostManager.h"
    135 #import "WebHostedNetscapePluginView.h"
    136 #endif
    137 
    138 using namespace WebCore;
    139 using namespace HTMLNames;
    140 using namespace std;
    141 
    142 #if ENABLE(JAVA_BRIDGE)
    143 @interface NSView (WebJavaPluginDetails)
    144 - (jobject)pollForAppletInWindow:(NSWindow *)window;
    145 @end
    146 #endif
    147 
    148 @interface NSURLDownload (WebNSURLDownloadDetails)
    149 - (void)_setOriginatingURL:(NSURL *)originatingURL;
    150 @end
    151 
    152 // For backwards compatibility with older WebKit plug-ins.
    153 NSString *WebPluginBaseURLKey = @"WebPluginBaseURL";
    154 NSString *WebPluginAttributesKey = @"WebPluginAttributes";
    155 NSString *WebPluginContainerKey = @"WebPluginContainer";
    156 
    157 @interface WebFramePolicyListener : NSObject <WebPolicyDecisionListener, WebFormSubmissionListener> {
    158     Frame* m_frame;
    159 }
    160 - (id)initWithWebCoreFrame:(Frame*)frame;
    161 - (void)invalidate;
    162 @end
    163 
    164 static inline WebDataSource *dataSource(DocumentLoader* loader)
    165 {
    166     return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;
    167 }
    168 
    169 // Quirk for the Apple Dictionary application.
    170 //
    171 // If a top level frame has a <script> element in its <head> for a script named MainPageJavaScript.js,
    172 // then for that frame's document, ignore changes to the scrolling attribute of frames. That script
    173 // has a bug in it where it sets the scrolling attribute on frames, and that erroneous scrolling
    174 // attribute needs to be ignored to avoid showing extra scroll bars in the window.
    175 // This quirk can be removed when Apple Dictionary is fixed (see <rdar://problem/6471058>).
    176 
    177 static void applyAppleDictionaryApplicationQuirkNonInlinePart(WebFrameLoaderClient* client, const ResourceRequest& request)
    178 {
    179     if (!request.url().isLocalFile())
    180         return;
    181     if (!request.url().string().endsWith("MainPageJavaScript.js"))
    182         return;
    183     Frame* frame = core(client->webFrame());
    184     if (!frame)
    185         return;
    186     if (frame->tree()->parent())
    187         return;
    188     Document* document = frame->document();
    189     if (!document)
    190         return;
    191     HTMLHeadElement* head = document->head();
    192     if (!head)
    193         return;
    194     for (Node* c = head->firstChild(); c; c = c->nextSibling()) {
    195         if (c->hasTagName(scriptTag) && static_cast<Element*>(c)->getAttribute(srcAttr) == "MainPageJavaScript.js") {
    196             document->setFrameElementsShouldIgnoreScrolling(true);
    197             return;
    198         }
    199     }
    200 }
    201 
    202 static inline void applyAppleDictionaryApplicationQuirk(WebFrameLoaderClient* client, const ResourceRequest& request)
    203 {
    204     // Use a one-time-initialized global variable so we can quickly determine there's nothing to do in
    205     // all applications other than Apple Dictionary.
    206     static bool isAppleDictionary = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Dictionary"];
    207     if (isAppleDictionary)
    208         applyAppleDictionaryApplicationQuirkNonInlinePart(client, request);
    209 }
    210 
    211 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame *webFrame)
    212     : m_webFrame(webFrame)
    213     , m_policyFunction(0)
    214 {
    215 }
    216 
    217 void WebFrameLoaderClient::frameLoaderDestroyed()
    218 {
    219     [m_webFrame.get() _clearCoreFrame];
    220     delete this;
    221 }
    222 
    223 bool WebFrameLoaderClient::hasWebView() const
    224 {
    225     return [m_webFrame.get() webView] != nil;
    226 }
    227 
    228 void WebFrameLoaderClient::makeRepresentation(DocumentLoader* loader)
    229 {
    230     [dataSource(loader) _makeRepresentation];
    231 }
    232 
    233 bool WebFrameLoaderClient::hasHTMLView() const
    234 {
    235     if (![getWebView(m_webFrame.get()) _usesDocumentViews]) {
    236         // FIXME (Viewless): For now we just assume that all frames have an HTML view
    237         return true;
    238     }
    239 
    240     NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
    241     return [view isKindOfClass:[WebHTMLView class]];
    242 }
    243 
    244 void WebFrameLoaderClient::forceLayout()
    245 {
    246     NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView];
    247     [view setNeedsLayout:YES];
    248     [view layout];
    249 }
    250 
    251 void WebFrameLoaderClient::forceLayoutForNonHTML()
    252 {
    253     WebFrameView *thisView = m_webFrame->_private->webFrameView;
    254     if (!thisView) // Viewless mode.
    255         return;
    256     NSView <WebDocumentView> *thisDocumentView = [thisView documentView];
    257     ASSERT(thisDocumentView != nil);
    258 
    259     // Tell the just loaded document to layout.  This may be necessary
    260     // for non-html content that needs a layout message.
    261     if (!([[m_webFrame.get() _dataSource] _isDocumentHTML])) {
    262         [thisDocumentView setNeedsLayout:YES];
    263         [thisDocumentView layout];
    264         [thisDocumentView setNeedsDisplay:YES];
    265     }
    266 }
    267 
    268 void WebFrameLoaderClient::setCopiesOnScroll()
    269 {
    270     [[[m_webFrame->_private->webFrameView _scrollView] contentView] setCopiesOnScroll:YES];
    271 }
    272 
    273 void WebFrameLoaderClient::detachedFromParent2()
    274 {
    275     //remove any NetScape plugins that are children of this frame because they are about to be detached
    276     WebView *webView = getWebView(m_webFrame.get());
    277     [webView removePluginInstanceViewsFor:(m_webFrame.get())];
    278     [m_webFrame->_private->webFrameView _setWebFrame:nil]; // needed for now to be compatible w/ old behavior
    279 }
    280 
    281 void WebFrameLoaderClient::detachedFromParent3()
    282 {
    283     [m_webFrame->_private->webFrameView release];
    284     m_webFrame->_private->webFrameView = nil;
    285 }
    286 
    287 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response)
    288 {
    289     id proxy = handle->releaseProxy();
    290     ASSERT(proxy);
    291 
    292     WebView *webView = getWebView(m_webFrame.get());
    293     WebDownload *download = [WebDownload _downloadWithLoadingConnection:handle->connection()
    294                                                                 request:request.nsURLRequest()
    295                                                                response:response.nsURLResponse()
    296                                                                delegate:[webView downloadDelegate]
    297                                                                   proxy:proxy];
    298 
    299     setOriginalURLForDownload(download, initialRequest);
    300 }
    301 
    302 void WebFrameLoaderClient::setOriginalURLForDownload(WebDownload *download, const ResourceRequest& initialRequest) const
    303 {
    304     NSURLRequest *initialURLRequest = initialRequest.nsURLRequest();
    305     NSURL *originalURL = nil;
    306 
    307     // If there was no referrer, don't traverse the back/forward history
    308     // since this download was initiated directly. <rdar://problem/5294691>
    309     if ([initialURLRequest valueForHTTPHeaderField:@"Referer"]) {
    310         // find the first item in the history that was originated by the user
    311         WebView *webView = getWebView(m_webFrame.get());
    312         WebBackForwardList *history = [webView backForwardList];
    313         int backListCount = [history backListCount];
    314         for (int backIndex = 0; backIndex <= backListCount && !originalURL; backIndex++) {
    315             // FIXME: At one point we had code here to check a "was user gesture" flag.
    316             // Do we need to restore that logic?
    317             originalURL = [[history itemAtIndex:-backIndex] URL];
    318         }
    319     }
    320 
    321     if (!originalURL)
    322         originalURL = [initialURLRequest URL];
    323 
    324     if ([download respondsToSelector:@selector(_setOriginatingURL:)]) {
    325         NSString *scheme = [originalURL scheme];
    326         NSString *host = [originalURL host];
    327         if (scheme && host && [scheme length] && [host length]) {
    328             NSNumber *port = [originalURL port];
    329             if (port && [port intValue] < 0)
    330                 port = nil;
    331             NSString *hostOnlyURLString;
    332             if (port)
    333                 hostOnlyURLString = [[NSString alloc] initWithFormat:@"%@://%@:%d", scheme, host, [port intValue]];
    334             else
    335                 hostOnlyURLString = [[NSString alloc] initWithFormat:@"%@://%@", scheme, host];
    336             NSURL *hostOnlyURL = [[NSURL alloc] initWithString:hostOnlyURLString];
    337             [hostOnlyURLString release];
    338             [download _setOriginatingURL:hostOnlyURL];
    339             [hostOnlyURL release];
    340         }
    341     }
    342 }
    343 
    344 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse& response, int length)
    345 {
    346     applyAppleDictionaryApplicationQuirk(this, request);
    347 
    348     WebView *webView = getWebView(m_webFrame.get());
    349     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    350     if (!implementations->didLoadResourceFromMemoryCacheFunc)
    351         return false;
    352 
    353     CallResourceLoadDelegate(implementations->didLoadResourceFromMemoryCacheFunc, webView, @selector(webView:didLoadResourceFromMemoryCache:response:length:fromDataSource:), request.nsURLRequest(), response.nsURLResponse(), length, dataSource(loader));
    354     return true;
    355 }
    356 
    357 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
    358 {
    359     WebView *webView = getWebView(m_webFrame.get());
    360     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    361 
    362     id object = nil;
    363     BOOL shouldRelease = NO;
    364     if (implementations->identifierForRequestFunc)
    365         object = CallResourceLoadDelegate(implementations->identifierForRequestFunc, webView, @selector(webView:identifierForInitialRequest:fromDataSource:), request.nsURLRequest(), dataSource(loader));
    366     else {
    367         object = [[NSObject alloc] init];
    368         shouldRelease = YES;
    369     }
    370 
    371     [webView _addObject:object forIdentifier:identifier];
    372 
    373     if (shouldRelease)
    374         [object release];
    375 }
    376 
    377 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
    378 {
    379     applyAppleDictionaryApplicationQuirk(this, request);
    380 
    381     WebView *webView = getWebView(m_webFrame.get());
    382     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    383 
    384     if (redirectResponse.isNull())
    385         static_cast<WebDocumentLoaderMac*>(loader)->increaseLoadCount(identifier);
    386 
    387     if (implementations->willSendRequestFunc)
    388         request = (NSURLRequest *)CallResourceLoadDelegate(implementations->willSendRequestFunc, webView, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), [webView _objectForIdentifier:identifier], request.nsURLRequest(), redirectResponse.nsURLResponse(), dataSource(loader));
    389 }
    390 
    391 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier)
    392 {
    393     WebView *webView = getWebView(m_webFrame.get());
    394     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    395 
    396     if (implementations->shouldUseCredentialStorageFunc) {
    397         if (id resource = [webView _objectForIdentifier:identifier])
    398             return CallResourceLoadDelegateReturningBoolean(NO, implementations->shouldUseCredentialStorageFunc, webView, @selector(webView:resource:shouldUseCredentialStorageForDataSource:), resource, dataSource(loader));
    399     }
    400 
    401     return true;
    402 }
    403 
    404 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
    405 {
    406     WebView *webView = getWebView(m_webFrame.get());
    407     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    408 
    409     NSURLAuthenticationChallenge *webChallenge = mac(challenge);
    410 
    411     if (implementations->didReceiveAuthenticationChallengeFunc) {
    412         if (id resource = [webView _objectForIdentifier:identifier]) {
    413             CallResourceLoadDelegate(implementations->didReceiveAuthenticationChallengeFunc, webView, @selector(webView:resource:didReceiveAuthenticationChallenge:fromDataSource:), resource, webChallenge, dataSource(loader));
    414             return;
    415         }
    416     }
    417 
    418     NSWindow *window = [webView hostWindow] ? [webView hostWindow] : [webView window];
    419     [[WebPanelAuthenticationHandler sharedHandler] startAuthentication:webChallenge window:window];
    420 }
    421 
    422 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
    423 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader* loader, unsigned long identifier, const ProtectionSpace& protectionSpace)
    424 {
    425     WebView *webView = getWebView(m_webFrame.get());
    426     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    427 
    428     NSURLProtectionSpace *webProtectionSpace = mac(protectionSpace);
    429 
    430     if (implementations->canAuthenticateAgainstProtectionSpaceFunc) {
    431         if (id resource = [webView _objectForIdentifier:identifier]) {
    432             return CallResourceLoadDelegateReturningBoolean(NO, implementations->canAuthenticateAgainstProtectionSpaceFunc, webView, @selector(webView:resource:canAuthenticateAgainstProtectionSpace:forDataSource:), resource, webProtectionSpace, dataSource(loader));
    433         }
    434     }
    435 
    436     // If our resource load delegate doesn't handle the question, then only send authentication
    437     // challenges for pre-10.6 protection spaces.  This is the same as the default implementation
    438     // in CFNetwork.
    439     return (protectionSpace.authenticationScheme() < ProtectionSpaceAuthenticationSchemeClientCertificateRequested);
    440 }
    441 #endif
    442 
    443 bool WebFrameLoaderClient::shouldPaintBrokenImage(const KURL& imageURL) const
    444 {
    445     WebView *webView = getWebView(m_webFrame.get());
    446     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    447 
    448     if (implementations->shouldPaintBrokenImageForURLFunc) {
    449         NSURL* url = imageURL;
    450         return CallResourceLoadDelegateReturningBoolean(YES, implementations->shouldPaintBrokenImageForURLFunc, webView, @selector(webView:shouldPaintBrokenImageForURL:), url);
    451     }
    452     return true;
    453 }
    454 
    455 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge&challenge)
    456 {
    457     WebView *webView = getWebView(m_webFrame.get());
    458     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    459     NSURLAuthenticationChallenge *webChallenge = mac(challenge);
    460 
    461     if (implementations->didCancelAuthenticationChallengeFunc) {
    462         if (id resource = [webView _objectForIdentifier:identifier]) {
    463             CallResourceLoadDelegate(implementations->didCancelAuthenticationChallengeFunc, webView, @selector(webView:resource:didCancelAuthenticationChallenge:fromDataSource:), resource, webChallenge, dataSource(loader));
    464             return;
    465         }
    466     }
    467 
    468     [(WebPanelAuthenticationHandler *)[WebPanelAuthenticationHandler sharedHandler] cancelAuthentication:webChallenge];
    469 }
    470 
    471 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
    472 {
    473     WebView *webView = getWebView(m_webFrame.get());
    474     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    475     if (implementations->didReceiveResponseFunc) {
    476         if (id resource = [webView _objectForIdentifier:identifier])
    477             CallResourceLoadDelegate(implementations->didReceiveResponseFunc, webView, @selector(webView:resource:didReceiveResponse:fromDataSource:), resource, response.nsURLResponse(), dataSource(loader));
    478     }
    479 }
    480 
    481 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader* loader, unsigned long identifier, NSCachedURLResponse* response) const
    482 {
    483     WebView *webView = getWebView(m_webFrame.get());
    484     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    485 
    486     if (implementations->willCacheResponseFunc) {
    487         if (id resource = [webView _objectForIdentifier:identifier])
    488             return CallResourceLoadDelegate(implementations->willCacheResponseFunc, webView, @selector(webView:resource:willCacheResponse:fromDataSource:), resource, response, dataSource(loader));
    489     }
    490 
    491     return response;
    492 }
    493 
    494 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int dataLength)
    495 {
    496     WebView *webView = getWebView(m_webFrame.get());
    497     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    498     if (implementations->didReceiveContentLengthFunc) {
    499         if (id resource = [webView _objectForIdentifier:identifier])
    500             CallResourceLoadDelegate(implementations->didReceiveContentLengthFunc, webView, @selector(webView:resource:didReceiveContentLength:fromDataSource:), resource, (NSInteger)dataLength, dataSource(loader));
    501     }
    502 }
    503 
    504 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
    505 {
    506     WebView *webView = getWebView(m_webFrame.get());
    507     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    508 
    509     if (implementations->didFinishLoadingFromDataSourceFunc) {
    510         if (id resource = [webView _objectForIdentifier:identifier])
    511             CallResourceLoadDelegate(implementations->didFinishLoadingFromDataSourceFunc, webView, @selector(webView:resource:didFinishLoadingFromDataSource:), resource, dataSource(loader));
    512     }
    513 
    514     [webView _removeObjectForIdentifier:identifier];
    515 
    516     static_cast<WebDocumentLoaderMac*>(loader)->decreaseLoadCount(identifier);
    517 }
    518 
    519 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
    520 {
    521     WebView *webView = getWebView(m_webFrame.get());
    522     WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
    523 
    524     if (implementations->didFailLoadingWithErrorFromDataSourceFunc) {
    525         if (id resource = [webView _objectForIdentifier:identifier])
    526             CallResourceLoadDelegate(implementations->didFailLoadingWithErrorFromDataSourceFunc, webView, @selector(webView:resource:didFailLoadingWithError:fromDataSource:), resource, (NSError *)error, dataSource(loader));
    527     }
    528 
    529     [webView _removeObjectForIdentifier:identifier];
    530 
    531     static_cast<WebDocumentLoaderMac*>(loader)->decreaseLoadCount(identifier);
    532 }
    533 
    534 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
    535 {
    536     WebView *webView = getWebView(m_webFrame.get());
    537     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    538     if (implementations->didHandleOnloadEventsForFrameFunc)
    539         CallFrameLoadDelegate(implementations->didHandleOnloadEventsForFrameFunc, webView, @selector(webView:didHandleOnloadEventsForFrame:), m_webFrame.get());
    540 }
    541 
    542 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
    543 {
    544     WebView *webView = getWebView(m_webFrame.get());
    545     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    546     if (implementations->didReceiveServerRedirectForProvisionalLoadForFrameFunc)
    547         CallFrameLoadDelegate(implementations->didReceiveServerRedirectForProvisionalLoadForFrameFunc, webView, @selector(webView:didReceiveServerRedirectForProvisionalLoadForFrame:), m_webFrame.get());
    548 }
    549 
    550 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
    551 {
    552     WebView *webView = getWebView(m_webFrame.get());
    553     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    554     if (implementations->didCancelClientRedirectForFrameFunc)
    555         CallFrameLoadDelegate(implementations->didCancelClientRedirectForFrameFunc, webView, @selector(webView:didCancelClientRedirectForFrame:), m_webFrame.get());
    556 }
    557 
    558 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
    559 {
    560     WebView *webView = getWebView(m_webFrame.get());
    561     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    562     if (implementations->willPerformClientRedirectToURLDelayFireDateForFrameFunc) {
    563         NSURL *cocoaURL = url;
    564         CallFrameLoadDelegate(implementations->willPerformClientRedirectToURLDelayFireDateForFrameFunc, webView, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:), cocoaURL, delay, [NSDate dateWithTimeIntervalSince1970:fireDate], m_webFrame.get());
    565     }
    566 }
    567 
    568 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
    569 {
    570     WebView *webView = getWebView(m_webFrame.get());
    571     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    572     if (implementations->didChangeLocationWithinPageForFrameFunc)
    573         CallFrameLoadDelegate(implementations->didChangeLocationWithinPageForFrameFunc, webView, @selector(webView:didChangeLocationWithinPageForFrame:), m_webFrame.get());
    574 }
    575 
    576 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
    577 {
    578     WebView *webView = getWebView(m_webFrame.get());
    579     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    580     if (implementations->didPushStateWithinPageForFrameFunc)
    581         CallFrameLoadDelegate(implementations->didPushStateWithinPageForFrameFunc, webView, @selector(webView:didPushStateWithinPageForFrame:), m_webFrame.get());
    582 }
    583 
    584 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
    585 {
    586     WebView *webView = getWebView(m_webFrame.get());
    587     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    588     if (implementations->didReplaceStateWithinPageForFrameFunc)
    589         CallFrameLoadDelegate(implementations->didReplaceStateWithinPageForFrameFunc, webView, @selector(webView:didReplaceStateWithinPageForFrame:), m_webFrame.get());
    590 }
    591 
    592 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
    593 {
    594     WebView *webView = getWebView(m_webFrame.get());
    595     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    596     if (implementations->didPopStateWithinPageForFrameFunc)
    597         CallFrameLoadDelegate(implementations->didPopStateWithinPageForFrameFunc, webView, @selector(webView:didPopStateWithinPageForFrame:), m_webFrame.get());
    598 }
    599 
    600 void WebFrameLoaderClient::dispatchWillClose()
    601 {
    602     WebView *webView = getWebView(m_webFrame.get());
    603     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    604     if (implementations->willCloseFrameFunc)
    605         CallFrameLoadDelegate(implementations->willCloseFrameFunc, webView, @selector(webView:willCloseFrame:), m_webFrame.get());
    606 }
    607 
    608 void WebFrameLoaderClient::dispatchDidReceiveIcon()
    609 {
    610 #if ENABLE(ICONDATABASE)
    611     WebView *webView = getWebView(m_webFrame.get());
    612     ASSERT(m_webFrame == [webView mainFrame]);
    613     [webView _dispatchDidReceiveIconFromWebFrame:m_webFrame.get()];
    614 #endif
    615 }
    616 
    617 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
    618 {
    619     WebView *webView = getWebView(m_webFrame.get());
    620     [webView _didStartProvisionalLoadForFrame:m_webFrame.get()];
    621 
    622     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    623     if (implementations->didStartProvisionalLoadForFrameFunc)
    624         CallFrameLoadDelegate(implementations->didStartProvisionalLoadForFrameFunc, webView, @selector(webView:didStartProvisionalLoadForFrame:), m_webFrame.get());
    625 }
    626 
    627 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
    628 {
    629     WebView *webView = getWebView(m_webFrame.get());
    630     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    631     if (implementations->didReceiveTitleForFrameFunc)
    632         // FIXME: use direction of title.
    633         CallFrameLoadDelegate(implementations->didReceiveTitleForFrameFunc, webView, @selector(webView:didReceiveTitle:forFrame:), (NSString *)title.string(), m_webFrame.get());
    634 }
    635 
    636 void WebFrameLoaderClient::dispatchDidChangeIcons()
    637 {
    638      // FIXME: Implement this to allow container to update favicon.
    639 }
    640 
    641 void WebFrameLoaderClient::dispatchDidCommitLoad()
    642 {
    643     // Tell the client we've committed this URL.
    644     ASSERT([m_webFrame->_private->webFrameView documentView] != nil || ![getWebView(m_webFrame.get()) _usesDocumentViews]);
    645 
    646     WebView *webView = getWebView(m_webFrame.get());
    647     [webView _didCommitLoadForFrame:m_webFrame.get()];
    648 
    649     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    650     if (implementations->didCommitLoadForFrameFunc)
    651         CallFrameLoadDelegate(implementations->didCommitLoadForFrameFunc, webView, @selector(webView:didCommitLoadForFrame:), m_webFrame.get());
    652 }
    653 
    654 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
    655 {
    656     WebView *webView = getWebView(m_webFrame.get());
    657     [webView _didFailProvisionalLoadWithError:error forFrame:m_webFrame.get()];
    658 
    659     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    660     if (implementations->didFailProvisionalLoadWithErrorForFrameFunc)
    661         CallFrameLoadDelegate(implementations->didFailProvisionalLoadWithErrorForFrameFunc, webView, @selector(webView:didFailProvisionalLoadWithError:forFrame:), (NSError *)error, m_webFrame.get());
    662 
    663     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
    664 }
    665 
    666 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
    667 {
    668     WebView *webView = getWebView(m_webFrame.get());
    669     [webView _didFailLoadWithError:error forFrame:m_webFrame.get()];
    670 
    671     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    672     if (implementations->didFailLoadWithErrorForFrameFunc)
    673         CallFrameLoadDelegate(implementations->didFailLoadWithErrorForFrameFunc, webView, @selector(webView:didFailLoadWithError:forFrame:), (NSError *)error, m_webFrame.get());
    674 
    675     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:error];
    676 }
    677 
    678 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
    679 {
    680     WebView *webView = getWebView(m_webFrame.get());
    681     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    682     if (implementations->didFinishDocumentLoadForFrameFunc)
    683         CallFrameLoadDelegate(implementations->didFinishDocumentLoadForFrameFunc, webView, @selector(webView:didFinishDocumentLoadForFrame:), m_webFrame.get());
    684 }
    685 
    686 void WebFrameLoaderClient::dispatchDidFinishLoad()
    687 {
    688     WebView *webView = getWebView(m_webFrame.get());
    689     [webView _didFinishLoadForFrame:m_webFrame.get()];
    690 
    691     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    692     if (implementations->didFinishLoadForFrameFunc)
    693         CallFrameLoadDelegate(implementations->didFinishLoadForFrameFunc, webView, @selector(webView:didFinishLoadForFrame:), m_webFrame.get());
    694 
    695     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
    696 }
    697 
    698 void WebFrameLoaderClient::dispatchDidFirstLayout()
    699 {
    700     WebView *webView = getWebView(m_webFrame.get());
    701     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    702     if (implementations->didFirstLayoutInFrameFunc)
    703         CallFrameLoadDelegate(implementations->didFirstLayoutInFrameFunc, webView, @selector(webView:didFirstLayoutInFrame:), m_webFrame.get());
    704 
    705     // See WebFrameLoaderClient::provisionalLoadStarted.
    706     WebDynamicScrollBarsView *scrollView = [m_webFrame->_private->webFrameView _scrollView];
    707     if ([getWebView(m_webFrame.get()) drawsBackground])
    708         [scrollView setDrawsBackground:YES];
    709 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
    710     [scrollView setVerticalScrollElasticity:NSScrollElasticityAutomatic];
    711     [scrollView setHorizontalScrollElasticity:NSScrollElasticityAutomatic];
    712 #endif
    713 }
    714 
    715 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
    716 {
    717     WebView *webView = getWebView(m_webFrame.get());
    718     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    719     if (implementations->didFirstVisuallyNonEmptyLayoutInFrameFunc)
    720         CallFrameLoadDelegate(implementations->didFirstVisuallyNonEmptyLayoutInFrameFunc, webView, @selector(webView:didFirstVisuallyNonEmptyLayoutInFrame:), m_webFrame.get());
    721 }
    722 
    723 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&)
    724 {
    725     WebView *currentWebView = getWebView(m_webFrame.get());
    726     NSDictionary *features = [[NSDictionary alloc] init];
    727     WebView *newWebView = [[currentWebView _UIDelegateForwarder] webView:currentWebView
    728                                                 createWebViewWithRequest:nil
    729                                                           windowFeatures:features];
    730     [features release];
    731 
    732 #if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
    733     if (newWebView)
    734         WebKit::NetscapePluginHostManager::shared().didCreateWindow();
    735 #endif
    736 
    737     return core([newWebView mainFrame]);
    738 }
    739 
    740 void WebFrameLoaderClient::dispatchShow()
    741 {
    742     WebView *webView = getWebView(m_webFrame.get());
    743     [[webView _UIDelegateForwarder] webViewShow:webView];
    744 }
    745 
    746 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function,
    747     const ResourceResponse& response, const ResourceRequest& request)
    748 {
    749     WebView *webView = getWebView(m_webFrame.get());
    750 
    751     [[webView _policyDelegateForwarder] webView:webView
    752                         decidePolicyForMIMEType:response.mimeType()
    753                                         request:request.nsURLRequest()
    754                                           frame:m_webFrame.get()
    755                                decisionListener:setUpPolicyListener(function).get()];
    756 }
    757 
    758 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function,
    759     const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
    760 {
    761     WebView *webView = getWebView(m_webFrame.get());
    762     [[webView _policyDelegateForwarder] webView:webView
    763             decidePolicyForNewWindowAction:actionDictionary(action, formState)
    764                                    request:request.nsURLRequest()
    765                               newFrameName:frameName
    766                           decisionListener:setUpPolicyListener(function).get()];
    767 }
    768 
    769 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function,
    770     const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState)
    771 {
    772     WebView *webView = getWebView(m_webFrame.get());
    773     [[webView _policyDelegateForwarder] webView:webView
    774                 decidePolicyForNavigationAction:actionDictionary(action, formState)
    775                                         request:request.nsURLRequest()
    776                                           frame:m_webFrame.get()
    777                                decisionListener:setUpPolicyListener(function).get()];
    778 }
    779 
    780 void WebFrameLoaderClient::cancelPolicyCheck()
    781 {
    782     [m_policyListener.get() invalidate];
    783     m_policyListener = nil;
    784     m_policyFunction = 0;
    785 }
    786 
    787 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
    788 {
    789     WebView *webView = getWebView(m_webFrame.get());
    790     [[webView _policyDelegateForwarder] webView:webView unableToImplementPolicyWithError:error frame:m_webFrame.get()];
    791 }
    792 
    793 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
    794 {
    795     id <WebFormDelegate> formDelegate = [getWebView(m_webFrame.get()) _formDelegate];
    796     if (!formDelegate) {
    797         (core(m_webFrame.get())->loader()->policyChecker()->*function)(PolicyUse);
    798         return;
    799     }
    800 
    801     const StringPairVector& textFieldValues = formState->textFieldValues();
    802     size_t size = textFieldValues.size();
    803     NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:size];
    804     for (size_t i = 0; i < size; ++i)
    805         [dictionary setObject:textFieldValues[i].second forKey:textFieldValues[i].first];
    806 
    807     CallFormDelegate(getWebView(m_webFrame.get()), @selector(frame:sourceFrame:willSubmitForm:withValues:submissionListener:), m_webFrame.get(), kit(formState->sourceFrame()), kit(formState->form()), dictionary, setUpPolicyListener(function).get());
    808 
    809     [dictionary release];
    810 }
    811 
    812 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader* loader)
    813 {
    814 }
    815 
    816 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader* loader)
    817 {
    818     [dataSource(loader) _revertToProvisionalState];
    819 }
    820 
    821 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader* loader, const ResourceError& error)
    822 {
    823     [dataSource(loader) _setMainDocumentError:error];
    824 }
    825 
    826 void WebFrameLoaderClient::willChangeEstimatedProgress()
    827 {
    828     [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebEstimatedProgressKey];
    829 }
    830 
    831 void WebFrameLoaderClient::didChangeEstimatedProgress()
    832 {
    833     [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebEstimatedProgressKey];
    834 }
    835 
    836 void WebFrameLoaderClient::postProgressStartedNotification()
    837 {
    838     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressStartedNotification object:getWebView(m_webFrame.get())];
    839 }
    840 
    841 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
    842 {
    843     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressEstimateChangedNotification object:getWebView(m_webFrame.get())];
    844 }
    845 
    846 void WebFrameLoaderClient::postProgressFinishedNotification()
    847 {
    848     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewProgressFinishedNotification object:getWebView(m_webFrame.get())];
    849 }
    850 
    851 void WebFrameLoaderClient::setMainFrameDocumentReady(bool ready)
    852 {
    853     [getWebView(m_webFrame.get()) setMainFrameDocumentReady:ready];
    854 }
    855 
    856 void WebFrameLoaderClient::startDownload(const ResourceRequest& request)
    857 {
    858     // FIXME: Should download full request.
    859     WebDownload *download = [getWebView(m_webFrame.get()) _downloadURL:request.url()];
    860 
    861     setOriginalURLForDownload(download, request);
    862 }
    863 
    864 void WebFrameLoaderClient::willChangeTitle(DocumentLoader* loader)
    865 {
    866     // FIXME: Should do this only in main frame case, right?
    867     [getWebView(m_webFrame.get()) _willChangeValueForKey:_WebMainFrameTitleKey];
    868 }
    869 
    870 void WebFrameLoaderClient::didChangeTitle(DocumentLoader* loader)
    871 {
    872     // FIXME: Should do this only in main frame case, right?
    873     [getWebView(m_webFrame.get()) _didChangeValueForKey:_WebMainFrameTitleKey];
    874 }
    875 
    876 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
    877 {
    878     NSData *nsData = [[NSData alloc] initWithBytesNoCopy:(void*)data length:length freeWhenDone:NO];
    879     [dataSource(loader) _receivedData:nsData];
    880     [nsData release];
    881 }
    882 
    883 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
    884 {
    885     [dataSource(loader) _finishedLoading];
    886 }
    887 
    888 void WebFrameLoaderClient::updateGlobalHistory()
    889 {
    890     WebView* view = getWebView(m_webFrame.get());
    891     DocumentLoader* loader = core(m_webFrame.get())->loader()->documentLoader();
    892 
    893     if ([view historyDelegate]) {
    894         WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
    895         if (implementations->navigatedFunc) {
    896             WebNavigationData *data = [[WebNavigationData alloc] initWithURLString:loader->urlForHistory()
    897                                                                              title:loader->title().string()
    898                                                                    originalRequest:loader->originalRequestCopy().nsURLRequest()
    899                                                                           response:loader->response().nsURLResponse()
    900                                                                  hasSubstituteData:loader->substituteData().isValid()
    901                                                               clientRedirectSource:loader->clientRedirectSourceForHistory()];
    902 
    903             CallHistoryDelegate(implementations->navigatedFunc, view, @selector(webView:didNavigateWithNavigationData:inFrame:), data, m_webFrame.get());
    904             [data release];
    905         }
    906 
    907         return;
    908     }
    909 
    910     [[WebHistory optionalSharedHistory] _visitedURL:loader->urlForHistory()
    911                                           withTitle:loader->title().string()
    912                                              method:loader->originalRequestCopy().httpMethod()
    913                                          wasFailure:loader->urlForHistoryReflectsFailure()
    914                                  increaseVisitCount:!loader->clientRedirectSourceForHistory()]; // Do not increase visit count due to navigations that were not initiated by the user directly, avoiding growth from programmatic reloads.
    915 }
    916 
    917 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
    918 {
    919     WebView* view = getWebView(m_webFrame.get());
    920     WebHistoryDelegateImplementationCache* implementations = [view historyDelegate] ? WebViewGetHistoryDelegateImplementations(view) : 0;
    921 
    922     DocumentLoader* loader = core(m_webFrame.get())->loader()->documentLoader();
    923     ASSERT(loader->unreachableURL().isEmpty());
    924 
    925     if (!loader->clientRedirectSourceForHistory().isNull()) {
    926         if (implementations) {
    927             if (implementations->clientRedirectFunc) {
    928                 CallHistoryDelegate(implementations->clientRedirectFunc, view, @selector(webView:didPerformClientRedirectFromURL:toURL:inFrame:),
    929                     loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_webFrame.get());
    930             }
    931         } else if (WebHistoryItem *item = [[WebHistory optionalSharedHistory] _itemForURLString:loader->clientRedirectSourceForHistory()])
    932             core(item)->addRedirectURL(loader->clientRedirectDestinationForHistory());
    933     }
    934 
    935     if (!loader->serverRedirectSourceForHistory().isNull()) {
    936         if (implementations) {
    937             if (implementations->serverRedirectFunc) {
    938                 CallHistoryDelegate(implementations->serverRedirectFunc, view, @selector(webView:didPerformServerRedirectFromURL:toURL:inFrame:),
    939                     loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_webFrame.get());
    940             }
    941         } else if (WebHistoryItem *item = [[WebHistory optionalSharedHistory] _itemForURLString:loader->serverRedirectSourceForHistory()])
    942             core(item)->addRedirectURL(loader->serverRedirectDestinationForHistory());
    943     }
    944 }
    945 
    946 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
    947 {
    948     WebView* view = getWebView(m_webFrame.get());
    949     WebHistoryItem *webItem = kit(item);
    950 
    951     return [[view _policyDelegateForwarder] webView:view shouldGoToHistoryItem:webItem];
    952 }
    953 
    954 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
    955 {
    956     return true;
    957 }
    958 
    959 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
    960 {
    961 }
    962 
    963 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
    964 {
    965 }
    966 
    967 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
    968 {
    969 }
    970 
    971 void WebFrameLoaderClient::updateGlobalHistoryItemForPage()
    972 {
    973     HistoryItem* historyItem = 0;
    974 
    975     if (Page* page = core(m_webFrame.get())->page()) {
    976         if (!page->settings()->privateBrowsingEnabled())
    977             historyItem = page->backForward()->currentItem();
    978     }
    979 
    980     WebView *webView = getWebView(m_webFrame.get());
    981     [webView _setGlobalHistoryItem:historyItem];
    982 }
    983 
    984 void WebFrameLoaderClient::didDisplayInsecureContent()
    985 {
    986     WebView *webView = getWebView(m_webFrame.get());
    987     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    988     if (implementations->didDisplayInsecureContentFunc)
    989         CallFrameLoadDelegate(implementations->didDisplayInsecureContentFunc, webView, @selector(webViewDidDisplayInsecureContent:));
    990 }
    991 
    992 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL)
    993 {
    994     RetainPtr<WebSecurityOrigin> webSecurityOrigin(AdoptNS, [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:origin]);
    995 
    996     WebView *webView = getWebView(m_webFrame.get());
    997     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    998     if (implementations->didRunInsecureContentFunc)
    999         CallFrameLoadDelegate(implementations->didRunInsecureContentFunc, webView, @selector(webView:didRunInsecureContent:), webSecurityOrigin.get());
   1000 }
   1001 
   1002 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
   1003 {
   1004     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled URL:request.url()];
   1005 }
   1006 
   1007 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
   1008 {
   1009     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotUseRestrictedPort URL:request.url()];
   1010 }
   1011 
   1012 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
   1013 {
   1014     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorCannotShowURL URL:request.url()];
   1015 }
   1016 
   1017 ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest& request)
   1018 {
   1019     return [NSError _webKitErrorWithDomain:WebKitErrorDomain code:WebKitErrorFrameLoadInterruptedByPolicyChange URL:request.url()];
   1020 }
   1021 
   1022 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
   1023 {
   1024     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:WebKitErrorCannotShowMIMEType URL:response.url()];
   1025 }
   1026 
   1027 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
   1028 {
   1029     return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist URL:response.url()];
   1030 }
   1031 
   1032 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
   1033 {
   1034     NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorPlugInWillHandleLoad
   1035                                                     contentURL:response.url()
   1036                                                  pluginPageURL:nil
   1037                                                     pluginName:nil
   1038                                                       MIMEType:response.mimeType()];
   1039     return [error autorelease];
   1040 }
   1041 
   1042 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
   1043 {
   1044     // FIXME: Needs to check domain.
   1045     // FIXME: WebKitErrorPlugInWillHandleLoad is a workaround for the cancel we do to prevent
   1046     // loading plugin content twice.  See <rdar://problem/4258008>
   1047     return error.errorCode() != NSURLErrorCancelled && error.errorCode() != WebKitErrorPlugInWillHandleLoad;
   1048 }
   1049 
   1050 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest& request) const
   1051 {
   1052     Frame* frame = core(m_webFrame.get());
   1053     Page* page = frame->page();
   1054     BOOL forMainFrame = page && page->mainFrame() == frame;
   1055     return [WebView _canHandleRequest:request.nsURLRequest() forMainFrame:forMainFrame];
   1056 }
   1057 
   1058 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
   1059 {
   1060     return [getWebView(m_webFrame.get()) _canShowMIMEType:MIMEType];
   1061 }
   1062 
   1063 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
   1064 {
   1065     return [WebView canShowMIMETypeAsHTML:MIMEType];
   1066 }
   1067 
   1068 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
   1069 {
   1070     return [WebView _representationExistsForURLScheme:URLScheme];
   1071 }
   1072 
   1073 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
   1074 {
   1075     return [WebView _generatedMIMETypeForURLScheme:URLScheme];
   1076 }
   1077 
   1078 void WebFrameLoaderClient::frameLoadCompleted()
   1079 {
   1080     // Note: Can be called multiple times.
   1081 
   1082     // See WebFrameLoaderClient::provisionalLoadStarted.
   1083     if ([getWebView(m_webFrame.get()) drawsBackground])
   1084         [[m_webFrame->_private->webFrameView _scrollView] setDrawsBackground:YES];
   1085 }
   1086 
   1087 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem* item)
   1088 {
   1089     if (!item)
   1090         return;
   1091 
   1092     NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
   1093 
   1094     // we might already be detached when this is called from detachFromParent, in which
   1095     // case we don't want to override real data earlier gathered with (0,0)
   1096     if ([docView superview] && [docView conformsToProtocol:@protocol(_WebDocumentViewState)])
   1097         item->setViewState([(id <_WebDocumentViewState>)docView viewState]);
   1098 }
   1099 
   1100 void WebFrameLoaderClient::restoreViewState()
   1101 {
   1102     HistoryItem* currentItem = core(m_webFrame.get())->loader()->history()->currentItem();
   1103     ASSERT(currentItem);
   1104 
   1105     // FIXME: As the ASSERT attests, it seems we should always have a currentItem here.
   1106     // One counterexample is <rdar://problem/4917290>
   1107     // For now, to cover this issue in release builds, there is no technical harm to returning
   1108     // early and from a user standpoint - as in the above radar - the previous page load failed
   1109     // so there *is* no scroll state to restore!
   1110     if (!currentItem)
   1111         return;
   1112 
   1113     NSView <WebDocumentView> *docView = [m_webFrame->_private->webFrameView documentView];
   1114     if ([docView conformsToProtocol:@protocol(_WebDocumentViewState)]) {
   1115         id state = currentItem->viewState();
   1116         if (state) {
   1117             [(id <_WebDocumentViewState>)docView setViewState:state];
   1118         }
   1119     }
   1120 }
   1121 
   1122 void WebFrameLoaderClient::provisionalLoadStarted()
   1123 {
   1124     // Tell the scroll view not to draw a background so we can leave the contents of
   1125     // the old page showing during the beginning of the loading process.
   1126 
   1127     // This will stay set to NO until:
   1128     //    1) The load gets far enough along: WebFrameLoader::frameLoadCompleted.
   1129     //    2) The window is resized: -[WebFrameView setFrameSize:].
   1130     // or 3) The view is moved out of the window: -[WebFrameView viewDidMoveToWindow].
   1131     // Please keep the comments in these four functions in agreement with each other.
   1132 
   1133     WebDynamicScrollBarsView *scrollView = [m_webFrame->_private->webFrameView _scrollView];
   1134     [scrollView setDrawsBackground:NO];
   1135 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
   1136     [scrollView setVerticalScrollElasticity:NSScrollElasticityNone];
   1137     [scrollView setHorizontalScrollElasticity:NSScrollElasticityNone];
   1138 #endif
   1139 }
   1140 
   1141 void WebFrameLoaderClient::didFinishLoad()
   1142 {
   1143     [m_webFrame->_private->internalLoadDelegate webFrame:m_webFrame.get() didFinishLoadWithError:nil];
   1144 }
   1145 
   1146 void WebFrameLoaderClient::prepareForDataSourceReplacement()
   1147 {
   1148     if (![m_webFrame.get() _dataSource]) {
   1149         ASSERT(!core(m_webFrame.get())->tree()->childCount());
   1150         return;
   1151     }
   1152 
   1153     // Make sure that any work that is triggered by resigning first reponder can get done.
   1154     // The main example where this came up is the textDidEndEditing that is sent to the
   1155     // FormsDelegate (3223413). We need to do this before _detachChildren, since that will
   1156     // remove the views as a side-effect of freeing the frame, at which point we can't
   1157     // post the FormDelegate messages.
   1158     //
   1159     // Note that this can also take FirstResponder away from a child of our frameView that
   1160     // is not in a child frame's view.  This is OK because we are in the process
   1161     // of loading new content, which will blow away all editors in this top frame, and if
   1162     // a non-editor is firstReponder it will not be affected by endEditingFor:.
   1163     // Potentially one day someone could write a DocView whose editors were not all
   1164     // replaced by loading new content, but that does not apply currently.
   1165     NSView *frameView = m_webFrame->_private->webFrameView;
   1166     NSWindow *window = [frameView window];
   1167     NSResponder *firstResp = [window firstResponder];
   1168     if ([firstResp isKindOfClass:[NSView class]] && [(NSView *)firstResp isDescendantOf:frameView])
   1169         [window endEditingFor:firstResp];
   1170 }
   1171 
   1172 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
   1173 {
   1174     RefPtr<WebDocumentLoaderMac> loader = WebDocumentLoaderMac::create(request, substituteData);
   1175 
   1176     WebDataSource *dataSource = [[WebDataSource alloc] _initWithDocumentLoader:loader.get()];
   1177     loader->setDataSource(dataSource, getWebView(m_webFrame.get()));
   1178     [dataSource release];
   1179 
   1180     return loader.release();
   1181 }
   1182 
   1183 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
   1184 {
   1185     WebView* view = getWebView(m_webFrame.get());
   1186 
   1187     if ([view historyDelegate]) {
   1188         WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(view);
   1189         if (!implementations->setTitleFunc)
   1190             return;
   1191 
   1192         // FIXME: use direction of title.
   1193         CallHistoryDelegate(implementations->setTitleFunc, view, @selector(webView:updateHistoryTitle:forURL:), (NSString *)title.string(), (NSString *)url);
   1194         return;
   1195     }
   1196 
   1197     NSURL* nsURL = url;
   1198     nsURL = [nsURL _webkit_canonicalize];
   1199     if(!nsURL)
   1200         return;
   1201     NSString *titleNSString = title.string();
   1202 
   1203     [[[WebHistory optionalSharedHistory] itemForURL:nsURL] setTitle:titleNSString];
   1204 }
   1205 
   1206 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
   1207 {
   1208     WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData([m_webFrame->_private->webFrameView documentView]);
   1209     cachedFrame->setCachedFramePlatformData(webPlatformData);
   1210 }
   1211 
   1212 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame* cachedFrame)
   1213 {
   1214     WebCachedFramePlatformData* platformData = reinterpret_cast<WebCachedFramePlatformData*>(cachedFrame->cachedFramePlatformData());
   1215     NSView <WebDocumentView> *cachedView = platformData->webDocumentView();
   1216     ASSERT(cachedView != nil);
   1217     ASSERT(cachedFrame->documentLoader());
   1218     [cachedView setDataSource:dataSource(cachedFrame->documentLoader())];
   1219 
   1220     // clean up webkit plugin instances before WebHTMLView gets freed.
   1221     WebView *webView = getWebView(m_webFrame.get());
   1222     [webView removePluginInstanceViewsFor:(m_webFrame.get())];
   1223 
   1224     [m_webFrame->_private->webFrameView _setDocumentView:cachedView];
   1225 }
   1226 
   1227 void WebFrameLoaderClient::transitionToCommittedForNewPage()
   1228 {
   1229     WebView *webView = getWebView(m_webFrame.get());
   1230     WebDataSource *dataSource = [m_webFrame.get() _dataSource];
   1231     bool usesDocumentViews = [webView _usesDocumentViews];
   1232 
   1233     if (usesDocumentViews) {
   1234         // FIXME (Viewless): I assume we want the equivalent of this optimization for viewless mode too.
   1235         bool willProduceHTMLView = [m_webFrame->_private->webFrameView _viewClassForMIMEType:[dataSource _responseMIMEType]] == [WebHTMLView class];
   1236         bool canSkipCreation = core(m_webFrame.get())->loader()->stateMachine()->committingFirstRealLoad() && willProduceHTMLView;
   1237         if (canSkipCreation) {
   1238             [[m_webFrame->_private->webFrameView documentView] setDataSource:dataSource];
   1239             return;
   1240         }
   1241 
   1242         // Don't suppress scrollbars before the view creation if we're making the view for a non-HTML view.
   1243         if (!willProduceHTMLView)
   1244             [[m_webFrame->_private->webFrameView _scrollView] setScrollBarsSuppressed:NO repaintOnUnsuppress:NO];
   1245     }
   1246 
   1247     // clean up webkit plugin instances before WebHTMLView gets freed.
   1248     [webView removePluginInstanceViewsFor:(m_webFrame.get())];
   1249 
   1250     NSView <WebDocumentView> *documentView = nil;
   1251     if (usesDocumentViews) {
   1252         documentView = [m_webFrame->_private->webFrameView _makeDocumentViewForDataSource:dataSource];
   1253         if (!documentView)
   1254             return;
   1255     }
   1256 
   1257     // FIXME: Could we skip some of this work for a top-level view that is not a WebHTMLView?
   1258 
   1259     // If we own the view, delete the old one - otherwise the render m_frame will take care of deleting the view.
   1260     Frame* coreFrame = core(m_webFrame.get());
   1261     Page* page = coreFrame->page();
   1262     bool isMainFrame = coreFrame == page->mainFrame();
   1263     if (isMainFrame && coreFrame->view())
   1264         coreFrame->view()->setParentVisible(false);
   1265     coreFrame->setView(0);
   1266     RefPtr<FrameView> coreView;
   1267     if (usesDocumentViews)
   1268         coreView = FrameView::create(coreFrame);
   1269     else
   1270         coreView = FrameView::create(coreFrame, IntSize([webView bounds].size));
   1271     coreFrame->setView(coreView);
   1272 
   1273     [m_webFrame.get() _updateBackgroundAndUpdatesWhileOffscreen];
   1274 
   1275     if (usesDocumentViews)
   1276         [m_webFrame->_private->webFrameView _install];
   1277 
   1278     if (isMainFrame)
   1279         coreView->setParentVisible(true);
   1280 
   1281     if (usesDocumentViews) {
   1282         // Call setDataSource on the document view after it has been placed in the view hierarchy.
   1283         // This what we for the top-level view, so should do this for views in subframes as well.
   1284         [documentView setDataSource:dataSource];
   1285 
   1286         // The following is a no-op for WebHTMLRepresentation, but for custom document types
   1287         // like the ones that Safari uses for bookmarks it is the only way the DocumentLoader
   1288         // will get the proper title.
   1289         if (DocumentLoader* documentLoader = [dataSource _documentLoader])
   1290             documentLoader->setTitle(StringWithDirection([dataSource pageTitle], LTR));
   1291     }
   1292 
   1293     if (HTMLFrameOwnerElement* owner = coreFrame->ownerElement())
   1294         coreFrame->view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
   1295 
   1296     // If the document view implicitly became first responder, make sure to set the focused frame properly.
   1297     if (usesDocumentViews && [[documentView window] firstResponder] == documentView) {
   1298         page->focusController()->setFocusedFrame(coreFrame);
   1299         page->focusController()->setFocused(true);
   1300     }
   1301 }
   1302 
   1303 void WebFrameLoaderClient::didSaveToPageCache()
   1304 {
   1305 }
   1306 
   1307 void WebFrameLoaderClient::didRestoreFromPageCache()
   1308 {
   1309 }
   1310 
   1311 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool)
   1312 {
   1313 }
   1314 
   1315 RetainPtr<WebFramePolicyListener> WebFrameLoaderClient::setUpPolicyListener(FramePolicyFunction function)
   1316 {
   1317     // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
   1318 
   1319     [m_policyListener.get() invalidate];
   1320 
   1321     WebFramePolicyListener *listener = [[WebFramePolicyListener alloc] initWithWebCoreFrame:core(m_webFrame.get())];
   1322     m_policyListener = listener;
   1323     [listener release];
   1324     m_policyFunction = function;
   1325 
   1326     return listener;
   1327 }
   1328 
   1329 void WebFrameLoaderClient::receivedPolicyDecison(PolicyAction action)
   1330 {
   1331     ASSERT(m_policyListener);
   1332     ASSERT(m_policyFunction);
   1333 
   1334     FramePolicyFunction function = m_policyFunction;
   1335 
   1336     m_policyListener = nil;
   1337     m_policyFunction = 0;
   1338 
   1339     (core(m_webFrame.get())->loader()->policyChecker()->*function)(action);
   1340 }
   1341 
   1342 String WebFrameLoaderClient::userAgent(const KURL& url)
   1343 {
   1344     WebView *webView = getWebView(m_webFrame.get());
   1345     ASSERT(webView);
   1346 
   1347     // We should never get here with nil for the WebView unless there is a bug somewhere else.
   1348     // But if we do, it's better to return the empty string than just crashing on the spot.
   1349     // Most other call sites are tolerant of nil because of Objective-C behavior, but this one
   1350     // is not because the return value of _userAgentForURL is a const KURL&.
   1351     if (!webView)
   1352         return String("");
   1353 
   1354     return [webView userAgentForURL:url];
   1355 }
   1356 
   1357 static const MouseEvent* findMouseEvent(const Event* event)
   1358 {
   1359     for (const Event* e = event; e; e = e->underlyingEvent())
   1360         if (e->isMouseEvent())
   1361             return static_cast<const MouseEvent*>(e);
   1362     return 0;
   1363 }
   1364 
   1365 NSDictionary *WebFrameLoaderClient::actionDictionary(const NavigationAction& action, PassRefPtr<FormState> formState) const
   1366 {
   1367     unsigned modifierFlags = 0;
   1368     const Event* event = action.event();
   1369     if (const UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event))) {
   1370         if (keyStateEvent->ctrlKey())
   1371             modifierFlags |= NSControlKeyMask;
   1372         if (keyStateEvent->altKey())
   1373             modifierFlags |= NSAlternateKeyMask;
   1374         if (keyStateEvent->shiftKey())
   1375             modifierFlags |= NSShiftKeyMask;
   1376         if (keyStateEvent->metaKey())
   1377             modifierFlags |= NSCommandKeyMask;
   1378     }
   1379 
   1380     NSURL *originalURL = action.url();
   1381 
   1382     NSMutableDictionary *result = [NSMutableDictionary dictionaryWithObjectsAndKeys:
   1383         [NSNumber numberWithInt:action.type()], WebActionNavigationTypeKey,
   1384         [NSNumber numberWithInt:modifierFlags], WebActionModifierFlagsKey,
   1385         originalURL, WebActionOriginalURLKey,
   1386         nil];
   1387 
   1388     if (const MouseEvent* mouseEvent = findMouseEvent(event)) {
   1389         WebElementDictionary *element = [[WebElementDictionary alloc]
   1390             initWithHitTestResult:core(m_webFrame.get())->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false)];
   1391         [result setObject:element forKey:WebActionElementKey];
   1392         [element release];
   1393 
   1394         [result setObject:[NSNumber numberWithInt:mouseEvent->button()] forKey:WebActionButtonKey];
   1395     }
   1396 
   1397     if (formState) {
   1398         ASSERT(formState->form());
   1399         [result setObject:kit(formState->form()) forKey:WebActionFormKey];
   1400     }
   1401 
   1402     return result;
   1403 }
   1404 
   1405 bool WebFrameLoaderClient::canCachePage() const
   1406 {
   1407     // We can only cache HTML pages right now
   1408     return [[[m_webFrame.get() _dataSource] representation] isKindOfClass:[WebHTMLRepresentation class]];
   1409 }
   1410 
   1411 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
   1412     const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
   1413 {
   1414     BEGIN_BLOCK_OBJC_EXCEPTIONS;
   1415 
   1416     ASSERT(m_webFrame);
   1417 
   1418     WebFrameView *childView = [getWebView(m_webFrame.get()) _usesDocumentViews] ? [[WebFrameView alloc] init] : nil;
   1419 
   1420     RefPtr<Frame> result = [WebFrame _createSubframeWithOwnerElement:ownerElement frameName:name frameView:childView];
   1421     [childView release];
   1422 
   1423     WebFrame *newFrame = kit(result.get());
   1424 
   1425     if ([newFrame _dataSource])
   1426         [[newFrame _dataSource] _documentLoader]->setOverrideEncoding([[m_webFrame.get() _dataSource] _documentLoader]->overrideEncoding());
   1427 
   1428     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
   1429     if (!result->page())
   1430         return 0;
   1431 
   1432     core(m_webFrame.get())->loader()->loadURLIntoChildFrame(url, referrer, result.get());
   1433 
   1434     // The frame's onload handler may have removed it from the document.
   1435     if (!result->tree()->parent())
   1436         return 0;
   1437 
   1438     return result.release();
   1439 
   1440     END_BLOCK_OBJC_EXCEPTIONS;
   1441 
   1442     return 0;
   1443 }
   1444 
   1445 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page* oldPage)
   1446 {
   1447 }
   1448 
   1449 void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request, Page* oldPage)
   1450 {
   1451     ASSERT(oldPage != core(m_webFrame.get())->page());
   1452     ASSERT(![getWebView(m_webFrame.get()) _objectForIdentifier:identifier]);
   1453 
   1454     assignIdentifierToInitialRequest(identifier, loader, request);
   1455 
   1456     [kit(oldPage) _removeObjectForIdentifier:identifier];
   1457 }
   1458 
   1459 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeType, bool shouldPreferPlugInsForImages)
   1460 {
   1461     BEGIN_BLOCK_OBJC_EXCEPTIONS;
   1462 
   1463     // This is a quirk that ensures Tiger Mail's WebKit plug-in will load during layout
   1464     // and not attach time. (5520541)
   1465     static BOOL isTigerMail = WKAppVersionCheckLessThan(@"com.apple.mail", -1, 3.0);
   1466     if (isTigerMail && mimeType == "application/x-apple-msg-attachment")
   1467         return ObjectContentNetscapePlugin;
   1468 
   1469     String type = mimeType;
   1470 
   1471     if (type.isEmpty()) {
   1472         // Try to guess the MIME type based off the extension.
   1473         NSURL *URL = url;
   1474         NSString *extension = [[URL path] pathExtension];
   1475         if ([extension length] > 0) {
   1476             type = WKGetMIMETypeForExtension(extension);
   1477             if (type.isEmpty()) {
   1478                 // If no MIME type is specified, use a plug-in if we have one that can handle the extension.
   1479                 if (WebBasePluginPackage *package = [getWebView(m_webFrame.get()) _pluginForExtension:extension]) {
   1480                     if ([package isKindOfClass:[WebPluginPackage class]])
   1481                         return ObjectContentOtherPlugin;
   1482 #if ENABLE(NETSCAPE_PLUGIN_API)
   1483                     else {
   1484                         ASSERT([package isKindOfClass:[WebNetscapePluginPackage class]]);
   1485                         return ObjectContentNetscapePlugin;
   1486                     }
   1487 #endif
   1488                 }
   1489             }
   1490         }
   1491     }
   1492 
   1493     if (type.isEmpty())
   1494         return ObjectContentFrame; // Go ahead and hope that we can display the content.
   1495 
   1496     WebBasePluginPackage *package = [getWebView(m_webFrame.get()) _pluginForMIMEType:type];
   1497     ObjectContentType plugInType = ObjectContentNone;
   1498     if (package) {
   1499 #if ENABLE(NETSCAPE_PLUGIN_API)
   1500         if ([package isKindOfClass:[WebNetscapePluginPackage class]])
   1501             plugInType = ObjectContentNetscapePlugin;
   1502         else
   1503 #endif
   1504         {
   1505             ASSERT([package isKindOfClass:[WebPluginPackage class]]);
   1506             plugInType = ObjectContentOtherPlugin;
   1507         }
   1508     }
   1509 
   1510     if (MIMETypeRegistry::isSupportedImageMIMEType(type))
   1511         return shouldPreferPlugInsForImages && plugInType != ObjectContentNone ? plugInType : ObjectContentImage;
   1512 
   1513     if (plugInType != ObjectContentNone)
   1514         return plugInType;
   1515 
   1516     if ([m_webFrame->_private->webFrameView _viewClassForMIMEType:type])
   1517         return ObjectContentFrame;
   1518 
   1519     return ObjectContentNone;
   1520 
   1521     END_BLOCK_OBJC_EXCEPTIONS;
   1522 
   1523     return ObjectContentNone;
   1524 }
   1525 
   1526 static NSMutableArray* kit(const Vector<String>& vector)
   1527 {
   1528     unsigned len = vector.size();
   1529     NSMutableArray* array = [NSMutableArray arrayWithCapacity:len];
   1530     for (unsigned x = 0; x < len; x++)
   1531         [array addObject:vector[x]];
   1532     return array;
   1533 }
   1534 
   1535 static String parameterValue(const Vector<String>& paramNames, const Vector<String>& paramValues, const String& name)
   1536 {
   1537     size_t size = paramNames.size();
   1538     ASSERT(size == paramValues.size());
   1539     for (size_t i = 0; i < size; ++i) {
   1540         if (equalIgnoringCase(paramNames[i], name))
   1541             return paramValues[i];
   1542     }
   1543     return String();
   1544 }
   1545 
   1546 static NSView *pluginView(WebFrame *frame, WebPluginPackage *pluginPackage,
   1547     NSArray *attributeNames, NSArray *attributeValues, NSURL *baseURL,
   1548     DOMElement *element, BOOL loadManually)
   1549 {
   1550     WebHTMLView *docView = (WebHTMLView *)[[frame frameView] documentView];
   1551     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
   1552 
   1553     WebPluginController *pluginController = [docView _pluginController];
   1554 
   1555     // Store attributes in a dictionary so they can be passed to WebPlugins.
   1556     NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
   1557 
   1558     [pluginPackage load];
   1559     Class viewFactory = [pluginPackage viewFactory];
   1560 
   1561     NSView *view = nil;
   1562     NSDictionary *arguments = nil;
   1563 
   1564     if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
   1565         arguments = [NSDictionary dictionaryWithObjectsAndKeys:
   1566             baseURL, WebPlugInBaseURLKey,
   1567             attributes, WebPlugInAttributesKey,
   1568             pluginController, WebPlugInContainerKey,
   1569             [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
   1570             [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
   1571             element, WebPlugInContainingElementKey,
   1572             nil];
   1573         LOG(Plugins, "arguments:\n%@", arguments);
   1574     } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
   1575         arguments = [NSDictionary dictionaryWithObjectsAndKeys:
   1576             baseURL, WebPluginBaseURLKey,
   1577             attributes, WebPluginAttributesKey,
   1578             pluginController, WebPluginContainerKey,
   1579             element, WebPlugInContainingElementKey,
   1580             nil];
   1581         LOG(Plugins, "arguments:\n%@", arguments);
   1582     }
   1583 
   1584     view = [WebPluginController plugInViewWithArguments:arguments fromPluginPackage:pluginPackage];
   1585     [attributes release];
   1586     return view;
   1587 }
   1588 
   1589 class PluginWidget : public PluginViewBase {
   1590 public:
   1591     PluginWidget(NSView *view = 0)
   1592         : PluginViewBase(view)
   1593     {
   1594     }
   1595 
   1596 private:
   1597     virtual void invalidateRect(const IntRect& rect)
   1598     {
   1599         [platformWidget() setNeedsDisplayInRect:rect];
   1600     }
   1601 };
   1602 
   1603 #if ENABLE(NETSCAPE_PLUGIN_API)
   1604 
   1605 class NetscapePluginWidget : public PluginWidget {
   1606 public:
   1607     NetscapePluginWidget(WebBaseNetscapePluginView *view)
   1608         : PluginWidget(view)
   1609     {
   1610     }
   1611 
   1612 #if USE(ACCELERATED_COMPOSITING)
   1613     virtual PlatformLayer* platformLayer() const
   1614     {
   1615         return [(WebBaseNetscapePluginView *)platformWidget() pluginLayer];
   1616     }
   1617 #endif
   1618 
   1619     virtual void handleEvent(Event* event)
   1620     {
   1621         Frame* frame = Frame::frameForWidget(this);
   1622         if (!frame)
   1623             return;
   1624 
   1625         NSEvent* currentNSEvent = frame->eventHandler()->currentNSEvent();
   1626         if (event->type() == eventNames().mousemoveEvent)
   1627             [(WebBaseNetscapePluginView *)platformWidget() handleMouseMoved:currentNSEvent];
   1628         else if (event->type() == eventNames().mouseoverEvent)
   1629             [(WebBaseNetscapePluginView *)platformWidget() handleMouseEntered:currentNSEvent];
   1630         else if (event->type() == eventNames().mouseoutEvent)
   1631             [(WebBaseNetscapePluginView *)platformWidget() handleMouseExited:currentNSEvent];
   1632     }
   1633 
   1634 private:
   1635     virtual void notifyWidget(WidgetNotification notification)
   1636     {
   1637         switch (notification) {
   1638         case WillPaintFlattened: {
   1639             BEGIN_BLOCK_OBJC_EXCEPTIONS;
   1640             [(WebBaseNetscapePluginView *)platformWidget() cacheSnapshot];
   1641             END_BLOCK_OBJC_EXCEPTIONS;
   1642             break;
   1643         }
   1644         case DidPaintFlattened: {
   1645             BEGIN_BLOCK_OBJC_EXCEPTIONS;
   1646             [(WebBaseNetscapePluginView *)platformWidget() clearCachedSnapshot];
   1647             END_BLOCK_OBJC_EXCEPTIONS;
   1648             break;
   1649         }
   1650         }
   1651     }
   1652 };
   1653 
   1654 #if USE(PLUGIN_HOST_PROCESS)
   1655 #define NETSCAPE_PLUGIN_VIEW WebHostedNetscapePluginView
   1656 #else
   1657 #define NETSCAPE_PLUGIN_VIEW WebNetscapePluginView
   1658 #endif
   1659 
   1660 #endif // ENABLE(NETSCAPE_PLUGIN_API)
   1661 
   1662 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize& size, HTMLPlugInElement* element, const KURL& url,
   1663     const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
   1664 {
   1665     BEGIN_BLOCK_OBJC_EXCEPTIONS;
   1666 
   1667     ASSERT(paramNames.size() == paramValues.size());
   1668 
   1669     int errorCode = 0;
   1670 
   1671     WebView *webView = getWebView(m_webFrame.get());
   1672     SEL selector = @selector(webView:plugInViewWithArguments:);
   1673 
   1674     Document* document = core(m_webFrame.get())->document();
   1675     NSURL *baseURL = document->baseURL();
   1676     NSURL *pluginURL = url;
   1677 
   1678     // <rdar://problem/8366089>: AppleConnect has a bug where it does not
   1679     // understand the parameter names specified in the <object> element that
   1680     // embeds its plug-in. This site-specific hack works around the issue by
   1681     // converting the parameter names to lowercase before passing them to the
   1682     // plug-in.
   1683     Frame* frame = core(m_webFrame.get());
   1684     NSMutableArray *attributeKeys = kit(paramNames);
   1685     if (frame && frame->settings()->needsSiteSpecificQuirks() && equalIgnoringCase(mimeType, "application/x-snkp")) {
   1686         for (NSUInteger i = 0; i < [attributeKeys count]; ++i)
   1687             [attributeKeys replaceObjectAtIndex:i withObject:[[attributeKeys objectAtIndex:i] lowercaseString]];
   1688     }
   1689 
   1690     if ([[webView UIDelegate] respondsToSelector:selector]) {
   1691         NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:kit(paramValues) forKeys:attributeKeys];
   1692         NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
   1693             attributes, WebPlugInAttributesKey,
   1694             [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
   1695             [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
   1696             kit(element), WebPlugInContainingElementKey,
   1697             // FIXME: We should be passing base URL, see <https://bugs.webkit.org/show_bug.cgi?id=35215>.
   1698             pluginURL, WebPlugInBaseURLKey, // pluginURL might be nil, so add it last
   1699             nil];
   1700 
   1701         NSView *view = CallUIDelegate(webView, selector, arguments);
   1702 
   1703         [attributes release];
   1704         [arguments release];
   1705 
   1706         if (view)
   1707             return adoptRef(new PluginWidget(view));
   1708     }
   1709 
   1710     NSString *MIMEType;
   1711     WebBasePluginPackage *pluginPackage;
   1712     if (mimeType.isEmpty()) {
   1713         MIMEType = nil;
   1714         pluginPackage = nil;
   1715     } else {
   1716         MIMEType = mimeType;
   1717         pluginPackage = [webView _pluginForMIMEType:mimeType];
   1718     }
   1719 
   1720     NSString *extension = [[pluginURL path] pathExtension];
   1721     if (!pluginPackage && [extension length] && ![MIMEType length]) {
   1722         pluginPackage = [webView _pluginForExtension:extension];
   1723         if (pluginPackage) {
   1724             NSString *newMIMEType = [pluginPackage MIMETypeForExtension:extension];
   1725             if ([newMIMEType length] != 0)
   1726                 MIMEType = newMIMEType;
   1727         }
   1728     }
   1729 
   1730     NSView *view = nil;
   1731 
   1732     if (pluginPackage) {
   1733         if ([pluginPackage isKindOfClass:[WebPluginPackage class]])
   1734             view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, attributeKeys, kit(paramValues), baseURL, kit(element), loadManually);
   1735 
   1736 #if ENABLE(NETSCAPE_PLUGIN_API)
   1737         else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
   1738             WebBaseNetscapePluginView *pluginView = [[[NETSCAPE_PLUGIN_VIEW alloc]
   1739                 initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
   1740                 pluginPackage:(WebNetscapePluginPackage *)pluginPackage
   1741                 URL:pluginURL
   1742                 baseURL:baseURL
   1743                 MIMEType:MIMEType
   1744                 attributeKeys:attributeKeys
   1745                 attributeValues:kit(paramValues)
   1746                 loadManually:loadManually
   1747                 element:element] autorelease];
   1748 
   1749             return adoptRef(new NetscapePluginWidget(pluginView));
   1750         }
   1751 #endif
   1752     } else
   1753         errorCode = WebKitErrorCannotFindPlugIn;
   1754 
   1755     if (!errorCode && !view)
   1756         errorCode = WebKitErrorCannotLoadPlugIn;
   1757 
   1758     if (errorCode && m_webFrame) {
   1759         WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(webView);
   1760         if (implementations->plugInFailedWithErrorFunc) {
   1761             KURL pluginPageURL = document->completeURL(stripLeadingAndTrailingHTMLSpaces(parameterValue(paramNames, paramValues, "pluginspage")));
   1762             if (!pluginPageURL.protocolInHTTPFamily())
   1763                 pluginPageURL = KURL();
   1764             NSString *pluginName = pluginPackage ? (NSString *)[pluginPackage pluginInfo].name : nil;
   1765 
   1766             NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
   1767                                                             contentURL:pluginURL pluginPageURL:pluginPageURL pluginName:pluginName MIMEType:MIMEType];
   1768             CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, [m_webFrame.get() webView],
   1769                                      @selector(webView:plugInFailedWithError:dataSource:), error, [m_webFrame.get() _dataSource]);
   1770             [error release];
   1771         }
   1772 
   1773         return 0;
   1774     }
   1775 
   1776     ASSERT(view);
   1777     return adoptRef(new PluginWidget(view));
   1778 
   1779     END_BLOCK_OBJC_EXCEPTIONS;
   1780 
   1781     return 0;
   1782 }
   1783 
   1784 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
   1785 {
   1786     BEGIN_BLOCK_OBJC_EXCEPTIONS;
   1787 
   1788     WebHTMLRepresentation *representation = (WebHTMLRepresentation *)[[m_webFrame.get() _dataSource] representation];
   1789 
   1790     NSView *pluginView = pluginWidget->platformWidget();
   1791 
   1792 #if ENABLE(NETSCAPE_PLUGIN_API)
   1793     if ([pluginView isKindOfClass:[NETSCAPE_PLUGIN_VIEW class]])
   1794         [representation _redirectDataToManualLoader:(NETSCAPE_PLUGIN_VIEW *)pluginView forPluginView:pluginView];
   1795     else {
   1796 #else
   1797     {
   1798 #endif
   1799         WebHTMLView *documentView = (WebHTMLView *)[[m_webFrame.get() frameView] documentView];
   1800         ASSERT([documentView isKindOfClass:[WebHTMLView class]]);
   1801         [representation _redirectDataToManualLoader:[documentView _pluginController] forPluginView:pluginView];
   1802     }
   1803 
   1804     END_BLOCK_OBJC_EXCEPTIONS;
   1805 }
   1806 
   1807 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& size, HTMLAppletElement* element, const KURL& baseURL,
   1808     const Vector<String>& paramNames, const Vector<String>& paramValues)
   1809 {
   1810 #if ENABLE(JAVA_BRIDGE)
   1811     BEGIN_BLOCK_OBJC_EXCEPTIONS;
   1812 
   1813     NSView *view = nil;
   1814 
   1815     NSString *MIMEType = @"application/x-java-applet";
   1816 
   1817     WebView *webView = getWebView(m_webFrame.get());
   1818 
   1819     WebBasePluginPackage *pluginPackage = [webView _pluginForMIMEType:MIMEType];
   1820 
   1821     if (pluginPackage) {
   1822         if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
   1823             // For some reason, the Java plug-in requires that we pass the dimension of the plug-in as attributes.
   1824             NSMutableArray *names = kit(paramNames);
   1825             NSMutableArray *values = kit(paramValues);
   1826             if (parameterValue(paramNames, paramValues, "width").isNull()) {
   1827                 [names addObject:@"width"];
   1828                 [values addObject:[NSString stringWithFormat:@"%d", size.width()]];
   1829             }
   1830             if (parameterValue(paramNames, paramValues, "height").isNull()) {
   1831                 [names addObject:@"height"];
   1832                 [values addObject:[NSString stringWithFormat:@"%d", size.height()]];
   1833             }
   1834             view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, names, values, baseURL, kit(element), NO);
   1835             if (view)
   1836                 return adoptRef(new PluginWidget(view));
   1837         }
   1838 #if ENABLE(NETSCAPE_PLUGIN_API)
   1839         else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
   1840             view = [[[NETSCAPE_PLUGIN_VIEW alloc] initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
   1841                 pluginPackage:(WebNetscapePluginPackage *)pluginPackage
   1842                 URL:nil
   1843                 baseURL:baseURL
   1844                 MIMEType:MIMEType
   1845                 attributeKeys:kit(paramNames)
   1846                 attributeValues:kit(paramValues)
   1847                 loadManually:NO
   1848                 element:element] autorelease];
   1849             if (view)
   1850                 return adoptRef(new NetscapePluginWidget(static_cast<WebBaseNetscapePluginView *>(view)));
   1851         } else {
   1852             ASSERT_NOT_REACHED();
   1853         }
   1854 #endif
   1855     }
   1856 
   1857     if (!view) {
   1858         WebResourceDelegateImplementationCache* implementations = WebViewGetResourceLoadDelegateImplementations(getWebView(m_webFrame.get()));
   1859         if (implementations->plugInFailedWithErrorFunc) {
   1860             NSString *pluginName = pluginPackage ? (NSString *)[pluginPackage pluginInfo].name : nil;
   1861             NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorJavaUnavailable contentURL:nil pluginPageURL:nil pluginName:pluginName MIMEType:MIMEType];
   1862             CallResourceLoadDelegate(implementations->plugInFailedWithErrorFunc, [m_webFrame.get() webView],
   1863                                      @selector(webView:plugInFailedWithError:dataSource:), error, [m_webFrame.get() _dataSource]);
   1864             [error release];
   1865         }
   1866     }
   1867 
   1868     END_BLOCK_OBJC_EXCEPTIONS;
   1869 #endif // ENABLE(JAVA_BRIDGE)
   1870     return 0;
   1871 }
   1872 
   1873 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
   1874 PassRefPtr<Widget> WebFrameLoaderClient::createMediaPlayerProxyPlugin(const IntSize& size, HTMLMediaElement* element, const KURL& url,
   1875     const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType)
   1876 {
   1877     BEGIN_BLOCK_OBJC_EXCEPTIONS;
   1878 
   1879     ASSERT(paramNames.size() == paramValues.size());
   1880     ASSERT(mimeType);
   1881 
   1882     int errorCode = 0;
   1883     WebView *webView = getWebView(m_webFrame.get());
   1884     NSURL *URL = url;
   1885 
   1886     SEL selector = @selector(webView:plugInViewWithArguments:);
   1887 
   1888     if ([[webView UIDelegate] respondsToSelector:selector]) {
   1889         NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:kit(paramValues) forKeys:kit(paramNames)];
   1890         NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
   1891             attributes, WebPlugInAttributesKey,
   1892             [NSNumber numberWithInt:WebPlugInModeEmbed], WebPlugInModeKey,
   1893             [NSNumber numberWithBool:YES], WebPlugInShouldLoadMainResourceKey,
   1894             kit(element), WebPlugInContainingElementKey,
   1895             URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
   1896             nil];
   1897 
   1898         NSView *view = CallUIDelegate(webView, selector, arguments);
   1899 
   1900         [attributes release];
   1901         [arguments release];
   1902 
   1903         if (view)
   1904             return adoptRef(new PluginWidget(view));
   1905     }
   1906 
   1907     WebBasePluginPackage *pluginPackage = [webView _videoProxyPluginForMIMEType:mimeType];
   1908     Document* document = core(m_webFrame.get())->document();
   1909     NSURL *baseURL = document->baseURL();
   1910     NSView *view = nil;
   1911 
   1912     if (pluginPackage) {
   1913         if ([pluginPackage isKindOfClass:[WebPluginPackage class]])
   1914             view = pluginView(m_webFrame.get(), (WebPluginPackage *)pluginPackage, kit(paramNames), kit(paramValues), baseURL, kit(element), false);
   1915     } else
   1916         errorCode = WebKitErrorCannotFindPlugIn;
   1917 
   1918     if (!errorCode && !view)
   1919         errorCode = WebKitErrorCannotLoadPlugIn;
   1920 
   1921     if (errorCode) {
   1922         NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
   1923             contentURL:URL pluginPageURL:nil pluginName:[pluginPackage pluginInfo].name MIMEType:mimeType];
   1924         WebNullPluginView *nullView = [[[WebNullPluginView alloc] initWithFrame:NSMakeRect(0, 0, size.width(), size.height())
   1925             error:error DOMElement:kit(element)] autorelease];
   1926         view = nullView;
   1927         [error release];
   1928     }
   1929 
   1930     ASSERT(view);
   1931     return adoptRef(new PluginWidget(view));
   1932 
   1933     END_BLOCK_OBJC_EXCEPTIONS;
   1934 
   1935     return 0;
   1936 }
   1937 
   1938 void WebFrameLoaderClient::hideMediaPlayerProxyPlugin(Widget* widget)
   1939 {
   1940     [WebPluginController pluginViewHidden:widget->platformWidget()];
   1941 }
   1942 
   1943 void WebFrameLoaderClient::showMediaPlayerProxyPlugin(Widget* widget)
   1944 {
   1945     [WebPluginController addPlugInView:widget->platformWidget()];
   1946 }
   1947 
   1948 #endif  // ENABLE(PLUGIN_PROXY_FOR_VIDEO)
   1949 
   1950 String WebFrameLoaderClient::overrideMediaType() const
   1951 {
   1952     NSString* overrideType = [getWebView(m_webFrame.get()) mediaStyle];
   1953     if (overrideType)
   1954         return overrideType;
   1955     return String();
   1956 }
   1957 
   1958 void WebFrameLoaderClient::documentElementAvailable() {
   1959 }
   1960 
   1961 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
   1962 {
   1963     WebView *webView = getWebView(m_webFrame.get());
   1964     WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
   1965 
   1966     if (implementations->didClearWindowObjectForFrameInScriptWorldFunc) {
   1967         CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameInScriptWorldFunc,
   1968             webView, @selector(webView:didClearWindowObjectForFrame:inScriptWorld:), m_webFrame.get(), [WebScriptWorld findOrCreateWorld:world]);
   1969         return;
   1970     }
   1971 
   1972     if (world != mainThreadNormalWorld())
   1973         return;
   1974 
   1975     Frame *frame = core(m_webFrame.get());
   1976     ScriptController *script = frame->script();
   1977 
   1978     if (implementations->didClearWindowObjectForFrameFunc) {
   1979         CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameFunc, webView, @selector(webView:didClearWindowObject:forFrame:),
   1980             script->windowScriptObject(), m_webFrame.get());
   1981     } else if (implementations->windowScriptObjectAvailableFunc) {
   1982         CallFrameLoadDelegate(implementations->windowScriptObjectAvailableFunc, webView, @selector(webView:windowScriptObjectAvailable:),
   1983             script->windowScriptObject());
   1984     }
   1985 
   1986     if ([webView scriptDebugDelegate]) {
   1987         [m_webFrame.get() _detachScriptDebugger];
   1988         [m_webFrame.get() _attachScriptDebugger];
   1989     }
   1990 }
   1991 
   1992 void WebFrameLoaderClient::registerForIconNotification(bool listen)
   1993 {
   1994 #if ENABLE(ICONDATABASE)
   1995     [[m_webFrame.get() webView] _registerForIconNotification:listen];
   1996 #endif
   1997 }
   1998 
   1999 void WebFrameLoaderClient::didPerformFirstNavigation() const
   2000 {
   2001     WebPreferences *preferences = [[m_webFrame.get() webView] preferences];
   2002     if ([preferences automaticallyDetectsCacheModel] && [preferences cacheModel] < WebCacheModelDocumentBrowser)
   2003         [preferences setCacheModel:WebCacheModelDocumentBrowser];
   2004 }
   2005 
   2006 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
   2007 {
   2008     return WebFrameNetworkingContext::create(core(m_webFrame.get()));
   2009 }
   2010 
   2011 #if ENABLE(JAVA_BRIDGE)
   2012 jobject WebFrameLoaderClient::javaApplet(NSView* view)
   2013 {
   2014     if ([view respondsToSelector:@selector(webPlugInGetApplet)])
   2015         return [view webPlugInGetApplet];
   2016 
   2017     // Compatibility with older versions of Java.
   2018     // FIXME: Do we still need this?
   2019     if ([view respondsToSelector:@selector(pollForAppletInWindow:)])
   2020         return [view pollForAppletInWindow:[[m_webFrame.get() frameView] window]];
   2021 
   2022     return 0;
   2023 }
   2024 #endif
   2025 
   2026 @implementation WebFramePolicyListener
   2027 + (void)initialize
   2028 {
   2029     JSC::initializeThreading();
   2030     WTF::initializeMainThreadToProcessMainThread();
   2031 #ifndef BUILDING_ON_TIGER
   2032     WebCoreObjCFinalizeOnMainThread(self);
   2033 #endif
   2034 }
   2035 
   2036 - (id)initWithWebCoreFrame:(Frame*)frame
   2037 {
   2038     self = [self init];
   2039     if (!self)
   2040         return nil;
   2041     frame->ref();
   2042     m_frame = frame;
   2043     return self;
   2044 }
   2045 
   2046 - (void)invalidate
   2047 {
   2048     if (m_frame) {
   2049         m_frame->deref();
   2050         m_frame = 0;
   2051     }
   2052 }
   2053 
   2054 - (void)dealloc
   2055 {
   2056     if (WebCoreObjCScheduleDeallocateOnMainThread([WebFramePolicyListener class], self))
   2057         return;
   2058 
   2059     if (m_frame)
   2060         m_frame->deref();
   2061     [super dealloc];
   2062 }
   2063 
   2064 - (void)finalize
   2065 {
   2066     ASSERT_MAIN_THREAD();
   2067     if (m_frame)
   2068         m_frame->deref();
   2069     [super finalize];
   2070 }
   2071 
   2072 - (void)receivedPolicyDecision:(PolicyAction)action
   2073 {
   2074     RefPtr<Frame> frame = adoptRef(m_frame);
   2075     m_frame = 0;
   2076     if (frame)
   2077         static_cast<WebFrameLoaderClient*>(frame->loader()->client())->receivedPolicyDecison(action);
   2078 }
   2079 
   2080 - (void)ignore
   2081 {
   2082     [self receivedPolicyDecision:PolicyIgnore];
   2083 }
   2084 
   2085 - (void)download
   2086 {
   2087     [self receivedPolicyDecision:PolicyDownload];
   2088 }
   2089 
   2090 - (void)use
   2091 {
   2092     [self receivedPolicyDecision:PolicyUse];
   2093 }
   2094 
   2095 - (void)continue
   2096 {
   2097     [self receivedPolicyDecision:PolicyUse];
   2098 }
   2099 
   2100 @end
   2101