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