3a85eb86e207c4a55129b208d0435eb04bcf502c
[WebKit-https.git] / WebKit / WebCoreSupport / WebFrameBridge.m
1 /*
2  * Copyright (C) 2005, 2006 Apple Computer, 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 "WebFrameBridge.h"
30
31 #import <JavaScriptCore/Assertions.h>
32 #import "WebBackForwardList.h"
33 #import "WebBaseNetscapePluginView.h"
34 #import "WebBasePluginPackage.h"
35 #import "WebDataSourceInternal.h"
36 #import "WebDefaultUIDelegate.h"
37 #import "WebEditingDelegate.h"
38 #import "WebFormDataStream.h"
39 #import "WebFormDelegate.h"
40 #import "WebFrameInternal.h"
41 #import "WebFrameLoadDelegate.h"
42 #import "WebFrameLoader.h"
43 #import "WebFrameViewInternal.h"
44 #import "WebHTMLRepresentationPrivate.h"
45 #import "WebHTMLViewInternal.h"
46 #import "WebHistoryItemPrivate.h"
47 #import "WebIconDatabase.h"
48 #import <WebKit/WebIconDatabasePrivate.h>
49 #import "WebJavaPlugIn.h"
50 #import "WebJavaScriptTextInputPanel.h"
51 #import "WebKitErrorsPrivate.h"
52 #import "WebKitLogging.h"
53 #import "WebKitNSStringExtras.h"
54 #import "WebKitStatisticsPrivate.h"
55 #import "WebKitSystemBits.h"
56 #import "WebLoader.h"
57 #import "WebLocalizableStrings.h"
58 #import "WebNSObjectExtras.h"
59 #import "WebNSURLExtras.h"
60 #import "WebNSURLRequestExtras.h"
61 #import "WebNSViewExtras.h"
62 #import "WebNetscapePluginEmbeddedView.h"
63 #import "WebNetscapePluginPackage.h"
64 #import "WebNullPluginView.h"
65 #import "WebPageBridge.h"
66 #import "WebPlugin.h"
67 #import "WebPluginController.h"
68 #import "WebPluginDatabase.h"
69 #import "WebPluginPackage.h"
70 #import "WebPluginViewFactoryPrivate.h"
71 #import "WebPreferencesPrivate.h"
72 #import "WebResourcePrivate.h"
73 #import "WebScriptDebugServerPrivate.h"
74 #import "WebSubresourceLoader.h"
75 #import "WebUIDelegatePrivate.h"
76 #import "WebViewInternal.h"
77 #import <Foundation/NSURLConnection.h>
78 #import <Foundation/NSURLRequest.h>
79 #import <Foundation/NSURLResponse.h>
80 #import <JavaVM/jni.h>
81 #import <WebCore/WebCoreFrameNamespaces.h>
82 #import <WebKitSystemInterface.h>
83
84 // For compatibility only with old SPI. 
85 @interface NSObject (OldWebPlugin)
86 - (void)setIsSelected:(BOOL)f;
87 @end
88
89 @interface NSApplication (DeclarationStolenFromAppKit)
90 - (void)_cycleWindowsReversed:(BOOL)reversed;
91 @end
92
93 @interface NSView (AppKitSecretsWebBridgeKnowsAbout)
94 - (NSView *)_findLastViewInKeyViewLoop;
95 @end
96
97 @interface NSURLResponse (FoundationSecretsWebBridgeKnowsAbout)
98 - (NSTimeInterval)_calculatedExpiration;
99 @end
100
101 @interface NSView (JavaPluginSecrets)
102 - (jobject)pollForAppletInWindow:(NSWindow *)window;
103 @end
104
105 NSString *WebPluginBaseURLKey =     @"WebPluginBaseURL";
106 NSString *WebPluginAttributesKey =  @"WebPluginAttributes";
107 NSString *WebPluginContainerKey =   @"WebPluginContainer";
108
109 @implementation WebFrameBridge
110
111 - (WebView *)webView
112 {
113     ASSERT([[self page] isKindOfClass:[WebPageBridge class]]);
114     return [(WebPageBridge *)[self page] webView];
115 }
116
117 - (id)initMainFrameWithPage:(WebPageBridge *)page frameName:(NSString *)name view:(WebFrameView *)view
118 {
119     self = [super initMainFrameWithPage:page];
120
121     ++WebBridgeCount;
122     
123     _frame = [[WebFrame alloc] _initWithWebFrameView:view webView:[self webView] bridge:self];
124     _loader = [[WebFrameLoader alloc] initWithClient:_frame];
125
126     [self setName:name];
127     [self initializeSettings:[[self webView] _settings]];
128     [self setTextSizeMultiplier:[[self webView] textSizeMultiplier]];
129
130     return self;
131 }
132
133 - (id)initSubframeWithOwnerElement:(WebCoreElement *)ownerElement frameName:(NSString *)name view:(WebFrameView *)view
134 {
135     self = [super initSubframeWithOwnerElement:ownerElement];
136
137     ++WebBridgeCount;
138     
139     _frame = [[WebFrame alloc] _initWithWebFrameView:view webView:[self webView] bridge:self];
140     _loader = [[WebFrameLoader alloc] initWithClient:_frame];
141
142     [self setName:name];
143     [self initializeSettings:[[self webView] _settings]];
144     [self setTextSizeMultiplier:[[self webView] textSizeMultiplier]];
145
146     return self;
147 }
148
149 #define KeyboardUIModeDidChangeNotification @"com.apple.KeyboardUIModeDidChange"
150 #define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode")
151 #define UniversalAccessDomain CFSTR("com.apple.universalaccess")
152
153 - (void)fini
154 {
155     if (_keyboardUIModeAccessed) {
156         [[NSDistributedNotificationCenter defaultCenter] 
157             removeObserver:self name:KeyboardUIModeDidChangeNotification object:nil];
158         [[NSNotificationCenter defaultCenter] 
159             removeObserver:self name:WebPreferencesChangedNotification object:nil];
160     }
161     ASSERT(_frame == nil);
162     --WebBridgeCount;
163 }
164
165 - (void)dealloc
166 {
167     [lastDashboardRegions release];
168     [_frame release];
169     [_loader release];
170     
171     [self fini];
172     [super dealloc];
173 }
174
175 - (void)finalize
176 {
177     [self fini];
178     [super finalize];
179 }
180
181 - (WebPreferences *)_preferences
182 {
183     return [[self webView] preferences];
184 }
185
186 - (void)_retrieveKeyboardUIModeFromPreferences:(NSNotification *)notification
187 {
188     CFPreferencesAppSynchronize(UniversalAccessDomain);
189
190     Boolean keyExistsAndHasValidFormat;
191     int mode = CFPreferencesGetAppIntegerValue(AppleKeyboardUIMode, UniversalAccessDomain, &keyExistsAndHasValidFormat);
192     
193     // The keyboard access mode is reported by two bits:
194     // Bit 0 is set if feature is on
195     // Bit 1 is set if full keyboard access works for any control, not just text boxes and lists
196     // We require both bits to be on.
197     // I do not know that we would ever get one bit on and the other off since
198     // checking the checkbox in system preferences which is marked as "Turn on full keyboard access"
199     // turns on both bits.
200     _keyboardUIMode = (mode & 0x2) ? WebCoreKeyboardAccessFull : WebCoreKeyboardAccessDefault;
201     
202     // check for tabbing to links
203     if ([[self _preferences] tabsToLinks]) {
204         _keyboardUIMode |= WebCoreKeyboardAccessTabsToLinks;
205     }
206 }
207
208 - (WebCoreKeyboardUIMode)keyboardUIMode
209 {
210     if (!_keyboardUIModeAccessed) {
211         _keyboardUIModeAccessed = YES;
212         [self _retrieveKeyboardUIModeFromPreferences:nil];
213         
214         [[NSDistributedNotificationCenter defaultCenter] 
215             addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:) 
216             name:KeyboardUIModeDidChangeNotification object:nil];
217
218         [[NSNotificationCenter defaultCenter] 
219             addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:) 
220                    name:WebPreferencesChangedNotification object:nil];
221     }
222     return _keyboardUIMode;
223 }
224
225 - (WebFrame *)webFrame
226 {
227     return _frame;
228 }
229
230 - (WebFrameLoader *)loader
231 {
232     return _loader;
233 }
234
235 - (WebCoreFrameBridge *)mainFrame
236 {
237     ASSERT(_frame != nil);
238     return [[[self webView] mainFrame] _bridge];
239 }
240
241 - (NSView *)documentView
242 {
243     ASSERT(_frame != nil);
244     return [[_frame frameView] documentView];
245 }
246
247 - (WebCorePageBridge *)createWindowWithURL:(NSURL *)URL
248 {
249     ASSERT(_frame != nil);
250
251     NSMutableURLRequest *request = nil;
252     if (URL != nil && ![URL _web_isEmpty]) {
253         request = [NSMutableURLRequest requestWithURL:URL];
254         [request _web_setHTTPReferrer:[self referrer]];
255     }
256
257     WebView *currentWebView = [self webView];
258     id wd = [currentWebView UIDelegate];
259     WebView *newWebView;
260     if ([wd respondsToSelector:@selector(webView:createWebViewWithRequest:)])
261         newWebView = [wd webView:currentWebView createWebViewWithRequest:request];
262     else
263         newWebView = [[WebDefaultUIDelegate sharedUIDelegate] webView:currentWebView createWebViewWithRequest:request];
264     return [newWebView _pageBridge];
265 }
266
267 - (void)showWindow
268 {
269     WebView *wv = [self webView];
270     [[wv _UIDelegateForwarder] webViewShow:wv];
271 }
272
273 - (BOOL)areToolbarsVisible
274 {
275     ASSERT(_frame != nil);
276     WebView *wv = [self webView];
277     id wd = [wv UIDelegate];
278     if ([wd respondsToSelector:@selector(webViewAreToolbarsVisible:)])
279         return [wd webViewAreToolbarsVisible:wv];
280     return [[WebDefaultUIDelegate sharedUIDelegate] webViewAreToolbarsVisible:wv];
281 }
282
283 - (void)setToolbarsVisible:(BOOL)visible
284 {
285     ASSERT(_frame != nil);
286     WebView *wv = [self webView];
287     [[wv _UIDelegateForwarder] webView:wv setToolbarsVisible:visible];
288 }
289
290 - (BOOL)areScrollbarsVisible
291 {
292     ASSERT(_frame != nil);
293     return [[_frame frameView] allowsScrolling];
294 }
295
296 - (void)setScrollbarsVisible:(BOOL)visible
297 {
298     ASSERT(_frame != nil);
299     [[_frame frameView] setAllowsScrolling:visible];
300 }
301
302 - (BOOL)isStatusbarVisible
303 {
304     ASSERT(_frame != nil);
305     WebView *wv = [self webView];
306     id wd = [wv UIDelegate];
307     if ([wd respondsToSelector:@selector(webViewIsStatusBarVisible:)])
308         return [wd webViewIsStatusBarVisible:wv];
309     return [[WebDefaultUIDelegate sharedUIDelegate] webViewIsStatusBarVisible:wv];
310 }
311
312 - (void)setStatusbarVisible:(BOOL)visible
313 {
314     ASSERT(_frame != nil);
315     WebView *wv = [self webView];
316     [[wv _UIDelegateForwarder] webView:wv setStatusBarVisible:visible];
317 }
318
319 - (void)setWindowIsResizable:(BOOL)resizable
320 {
321     ASSERT(_frame != nil);
322     WebView *webView = [self webView];
323     [[webView _UIDelegateForwarder] webView:webView setResizable:resizable];
324 }
325
326 - (BOOL)windowIsResizable
327 {
328     ASSERT(_frame != nil);
329     WebView *webView = [self webView];
330     return [[webView _UIDelegateForwarder] webViewIsResizable:webView];
331 }
332
333 - (NSResponder *)firstResponder
334 {
335     ASSERT(_frame != nil);
336     WebView *webView = [self webView];
337     return [[webView _UIDelegateForwarder] webViewFirstResponder:webView];
338 }
339
340 - (void)makeFirstResponder:(NSResponder *)view
341 {
342     ASSERT(_frame != nil);
343     WebView *webView = [self webView];
344     [webView _pushPerformingProgrammaticFocus];
345     [[webView _UIDelegateForwarder] webView:webView makeFirstResponder:view];
346     [webView _popPerformingProgrammaticFocus];
347 }
348
349 - (void)willMakeFirstResponderForNodeFocus
350 {
351     ASSERT([[[_frame frameView] documentView] isKindOfClass:[WebHTMLView class]]);
352     [(WebHTMLView *)[[_frame frameView] documentView] _willMakeFirstResponderForNodeFocus];
353 }
354
355
356 - (BOOL)textViewWasFirstResponderAtMouseDownTime:(NSTextView *)textView;
357 {
358     ASSERT(_frame != nil);
359     NSView *documentView = [[_frame frameView] documentView];
360     if (![documentView isKindOfClass:[WebHTMLView class]]) {
361         return NO;
362     }
363     WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
364     return [webHTMLView _textViewWasFirstResponderAtMouseDownTime:textView];
365 }
366
367 - (void)closeWindowSoon
368 {
369     WebView *parentWebView = [self webView];
370
371     // We need to remove the parent WebView from WebViewSets here, before it actually
372     // closes, to make sure that JavaScript code that executes before it closes
373     // can't find it. Otherwise, window.open will select a closed WebView instead of 
374     // opening a new one <rdar://problem/3572585>.
375
376     // We also need to stop the load to prevent further parsing or JavaScript execution
377     // after the window has torn down <rdar://problem/4161660>.
378   
379     // FIXME: This code assumes that the UI delegate will respond to a webViewClose
380     // message by actually closing the WebView. Safari guarantees this behavior, but other apps might not.
381     // This approach is an inherent limitation of not making a close execute immediately
382     // after a call to window.close.
383     
384     [parentWebView setGroupName:nil];
385     [parentWebView stopLoading:self];
386     [parentWebView performSelector:@selector(_closeWindow) withObject:nil afterDelay:0.0];
387 }
388
389 - (NSWindow *)window
390 {
391     ASSERT(_frame != nil);
392     return [[_frame frameView] window];
393 }
394
395 - (void)runJavaScriptAlertPanelWithMessage:(NSString *)message
396 {
397     WebView *wv = [self webView];
398     id wd = [wv UIDelegate];
399     // Check whether delegate implements new version, then whether delegate implements old version. If neither,
400     // fall back to shared delegate's implementation of new version.
401     if ([wd respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:)])
402         [wd webView:wv runJavaScriptAlertPanelWithMessage:message initiatedByFrame:_frame];
403     else if ([wd respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:)])
404         [wd webView:wv runJavaScriptAlertPanelWithMessage:message];
405     else
406         [[WebDefaultUIDelegate sharedUIDelegate] webView:wv runJavaScriptAlertPanelWithMessage:message initiatedByFrame:_frame];
407 }
408
409 - (BOOL)runJavaScriptConfirmPanelWithMessage:(NSString *)message
410 {
411     WebView *wv = [self webView];
412     id wd = [wv UIDelegate];
413     // Check whether delegate implements new version, then whether delegate implements old version. If neither,
414     // fall back to shared delegate's implementation of new version.
415     if ([wd respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:)])
416         return [wd webView:wv runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:_frame];
417     if ([wd respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:)])
418         return [wd webView:wv runJavaScriptConfirmPanelWithMessage:message];    
419     return [[WebDefaultUIDelegate sharedUIDelegate] webView:wv runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:_frame];
420 }
421
422 - (BOOL)shouldInterruptJavaScript
423 {
424     WebView *wv = [self webView];
425     id wd = [wv UIDelegate];
426     
427     if ([wd respondsToSelector:@selector(webViewShouldInterruptJavaScript:)])
428         return [wd webViewShouldInterruptJavaScript:wv];
429     return NO;
430 }
431
432 - (BOOL)canRunBeforeUnloadConfirmPanel
433 {
434     WebView *wv = [self webView];
435     id wd = [wv UIDelegate];
436     return [wd respondsToSelector:@selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:)];
437 }
438
439 - (BOOL)runBeforeUnloadConfirmPanelWithMessage:(NSString *)message
440 {
441     WebView *wv = [self webView];
442     id wd = [wv UIDelegate];
443     if ([wd respondsToSelector:@selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:)])
444         return [wd webView:wv runBeforeUnloadConfirmPanelWithMessage:message initiatedByFrame:_frame];
445     return YES;
446 }
447
448 - (BOOL)runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText returningText:(NSString **)result
449 {
450     WebView *wv = [self webView];
451     id wd = [wv UIDelegate];
452     // Check whether delegate implements new version, then whether delegate implements old version. If neither,
453     // fall back to shared delegate's implementation of new version.
454     if ([wd respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:)])
455         *result = [wd webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:_frame];
456     else if ([wd respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:)])
457         *result = [wd webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText];
458     else
459         *result = [[WebDefaultUIDelegate sharedUIDelegate] webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:_frame];
460     return *result != nil;
461 }
462
463 - (void)addMessageToConsole:(NSDictionary *)message
464 {
465     WebView *wv = [self webView];
466     id wd = [wv UIDelegate];
467     if ([wd respondsToSelector:@selector(webView:addMessageToConsole:)])
468         [wd webView:wv addMessageToConsole:message];
469 }
470
471 - (void)runOpenPanelForFileButtonWithResultListener:(id<WebCoreOpenPanelResultListener>)resultListener
472 {
473     WebView *wv = [self webView];
474     [[wv _UIDelegateForwarder] webView:wv runOpenPanelForFileButtonWithResultListener:(id<WebOpenPanelResultListener>)resultListener];
475 }
476
477 - (WebDataSource *)dataSource
478 {
479     ASSERT(_frame != nil);
480     WebDataSource *dataSource = [_frame dataSource];
481
482     ASSERT(dataSource != nil);
483
484     return dataSource;
485 }
486
487 - (void)setTitle:(NSString *)title
488 {
489     [[_loader documentLoader] setTitle:[title _webkit_stringByCollapsingNonPrintingCharacters]];
490 }
491
492 - (void)setStatusText:(NSString *)status
493 {
494     ASSERT(_frame != nil);
495     WebView *wv = [self webView];
496     [[wv _UIDelegateForwarder] webView:wv setStatusText:status];
497 }
498
499 - (void)receivedData:(NSData *)data textEncodingName:(NSString *)textEncodingName
500 {
501     // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
502     NSString *encoding = [[_loader documentLoader] overrideEncoding];
503     BOOL userChosen = encoding != nil;
504     if (encoding == nil) {
505         encoding = textEncodingName;
506     }
507     [self setEncoding:encoding userChosen:userChosen];
508
509     [self addData:data];
510 }
511
512 - (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)resourceLoader withMethod:(NSString *)method URL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders
513 {
514     // If we are no longer attached to a WebView, this must be an attempted load from an
515     // onUnload handler, so let's just block it.
516     if ([[self webFrame] webView] == nil)
517         return nil;
518
519     // Since this is a subresource, we can load any URL (we ignore the return value).
520     // But we still want to know whether we should hide the referrer or not, so we call the canLoadURL method.
521     BOOL hideReferrer;
522     [self canLoadURL:URL fromReferrer:[self referrer] hideReferrer:&hideReferrer];
523
524     return [WebSubresourceLoader startLoadingResource:resourceLoader
525                                            withMethod:method
526                                                   URL:URL
527                                         customHeaders:customHeaders
528                                              referrer:(hideReferrer ? nil : [self referrer])
529                                        forFrameLoader:_loader];
530 }
531
532 - (id <WebCoreResourceHandle>)startLoadingResource:(id <WebCoreResourceLoader>)resourceLoader withMethod:(NSString *)method URL:(NSURL *)URL customHeaders:(NSDictionary *)customHeaders postData:(NSArray *)postData
533 {
534     // If we are no longer attached to a WebView, this must be an attempted load from an
535     // onUnload handler, so let's just block it.
536     if ([[self webFrame] webView] == nil)
537         return nil;
538
539     // Since this is a subresource, we can load any URL (we ignore the return value).
540     // But we still want to know whether we should hide the referrer or not, so we call the canLoadURL method.
541     BOOL hideReferrer;
542     [self canLoadURL:URL fromReferrer:[self referrer] hideReferrer:&hideReferrer];
543
544     return [WebSubresourceLoader startLoadingResource:resourceLoader
545                                            withMethod:method 
546                                                   URL:URL
547                                         customHeaders:customHeaders
548                                              postData:postData
549                                              referrer:(hideReferrer ? nil : [self referrer])
550                                        forFrameLoader:_loader];
551 }
552
553 - (void)objectLoadedFromCacheWithURL:(NSURL *)URL response:(NSURLResponse *)response data:(NSData *)data
554 {
555     // FIXME: If the WebKit client changes or cancels the request, WebCore does not respect this and continues the load.
556     NSError *error;
557     id identifier;
558     NSURLRequest *request = [[NSURLRequest alloc] initWithURL:URL];
559     [_frame _requestFromDelegateForRequest:request identifier:&identifier error:&error];    
560     [_frame _sendRemainingDelegateMessagesWithIdentifier:identifier response:response length:[data length] error:error];
561     [request release];
562 }
563
564 - (NSData *)syncLoadResourceWithMethod:(NSString *)method URL:(NSURL *)URL customHeaders:(NSDictionary *)requestHeaders postData:(NSArray *)postData finalURL:(NSURL **)finalURL responseHeaders:(NSDictionary **)responseHeaderDict statusCode:(int *)statusCode
565 {
566     // Since this is a subresource, we can load any URL (we ignore the return value).
567     // But we still want to know whether we should hide the referrer or not, so we call the canLoadURL method.
568     BOOL hideReferrer;
569     [self canLoadURL:URL fromReferrer:[self referrer] hideReferrer:&hideReferrer];
570
571     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URL];
572     [request setTimeoutInterval:10];
573
574     // setHTTPMethod is not called for GET requests to work around <rdar://4464032>.
575     if (![method isEqualToString:@"GET"])
576         [request setHTTPMethod:method];
577
578     if (postData)        
579         webSetHTTPBody(request, postData);
580
581     NSEnumerator *e = [requestHeaders keyEnumerator];
582     NSString *key;
583     while ((key = (NSString *)[e nextObject]) != nil) {
584         [request addValue:[requestHeaders objectForKey:key] forHTTPHeaderField:key];
585     }
586     
587     if ([request _web_isConditionalRequest])
588         [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
589     else
590         [request setCachePolicy:[[[self dataSource] request] cachePolicy]];
591     if (!hideReferrer)
592         [request _web_setHTTPReferrer:[self referrer]];
593     
594     WebView *webView = [self webView];
595     [request setMainDocumentURL:[[[[webView mainFrame] dataSource] request] URL]];
596     [request _web_setHTTPUserAgent:[webView userAgentForURL:[request URL]]];
597     
598     NSError *error = nil;
599     id identifier = nil;    
600     NSURLRequest *newRequest = [_frame _requestFromDelegateForRequest:request identifier:&identifier error:&error];
601     
602     NSURLResponse *response = nil;
603     NSData *result = nil;
604     if (error == nil) {
605         ASSERT(newRequest != nil);
606         result = [NSURLConnection sendSynchronousRequest:newRequest returningResponse:&response error:&error];
607     }
608     
609     if (error == nil) {
610         *finalURL = [response URL];
611         if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
612             NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; 
613             *responseHeaderDict = [httpResponse allHeaderFields];
614             *statusCode = [httpResponse statusCode];
615         } else {
616             *responseHeaderDict = [NSDictionary dictionary];
617             *statusCode = 200;
618         }
619     } else {
620         *finalURL = URL;
621         *responseHeaderDict = [NSDictionary dictionary];
622         if ([error domain] == NSURLErrorDomain) {
623             *statusCode = [error code];
624         } else {
625             *statusCode = 404;
626         }
627     }
628     
629     [_frame _sendRemainingDelegateMessagesWithIdentifier:identifier response:response length:[result length] error:error];
630     [request release];
631     
632     return result;
633 }
634
635 - (BOOL)isReloading
636 {
637     return [[[self dataSource] request] cachePolicy] == NSURLRequestReloadIgnoringCacheData;
638 }
639
640 // We would like a better value for a maximum time_t,
641 // but there is no way to do that in C with any certainty.
642 // INT_MAX should work well enough for our purposes.
643 #define MAX_TIME_T ((time_t)INT_MAX)    
644
645 - (time_t)expiresTimeForResponse:(NSURLResponse *)response
646 {
647     // This check can be removed when the new Foundation method
648     // has been around long enough for everyone to have it.
649     ASSERT([response respondsToSelector:@selector(_calculatedExpiration)]);
650
651     NSTimeInterval expiration = [response _calculatedExpiration];
652     expiration += kCFAbsoluteTimeIntervalSince1970;
653     
654     return expiration > MAX_TIME_T ? MAX_TIME_T : (time_t)expiration;
655 }
656
657 - (void)reportClientRedirectToURL:(NSURL *)URL delay:(NSTimeInterval)seconds fireDate:(NSDate *)date lockHistory:(BOOL)lockHistory isJavaScriptFormAction:(BOOL)isJavaScriptFormAction
658 {
659     [_loader clientRedirectedTo:URL delay:seconds fireDate:date lockHistory:lockHistory isJavaScriptFormAction:(BOOL)isJavaScriptFormAction];
660 }
661
662 - (void)reportClientRedirectCancelled:(BOOL)cancelWithLoadInProgress
663 {
664     [_loader clientRedirectCancelledOrFinished:cancelWithLoadInProgress];
665 }
666
667 - (void)close
668 {
669     [super close];
670     [_frame release];
671     _frame = nil;
672 }
673
674 - (void)activateWindow
675 {
676     [[[self webView] _UIDelegateForwarder] webViewFocus:[self webView]];
677 }
678
679 - (void)deactivateWindow
680 {
681    [[[self webView] _UIDelegateForwarder] webViewUnfocus:[self webView]];
682 }
683
684 - (void)formControlIsBecomingFirstResponder:(NSView *)formControl
685 {
686     // When a form element becomes first responder, its enclosing WebHTMLView might need to
687     // change its focus-displaying state, but isn't otherwise notified.
688     [(WebHTMLView *)[[_frame frameView] documentView] _formControlIsBecomingFirstResponder:formControl];
689 }
690
691 - (void)formControlIsResigningFirstResponder:(NSView *)formControl
692 {
693     // When a form element resigns first responder, its enclosing WebHTMLView might need to
694     // change its focus-displaying state, but isn't otherwise notified.
695     [(WebHTMLView *)[[_frame frameView] documentView] _formControlIsResigningFirstResponder:formControl];
696 }
697
698 - (void)loadURL:(NSURL *)URL referrer:(NSString *)referrer reload:(BOOL)reload userGesture:(BOOL)forUser target:(NSString *)target triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values
699 {
700     BOOL hideReferrer;
701     if (![self canLoadURL:URL fromReferrer:referrer hideReferrer:&hideReferrer])
702         return;
703
704     if ([target length] == 0) {
705         target = nil;
706     }
707
708     WebFrame *targetFrame = [_frame findFrameNamed:target];
709     if (![self canTargetLoadInFrame:[targetFrame _bridge]]) {
710         return;
711     }
712     
713     WebFrameLoadType loadType;
714     
715     if (reload)
716         loadType = WebFrameLoadTypeReload;
717     else if (!forUser)
718         loadType = WebFrameLoadTypeInternal;
719     else
720         loadType = WebFrameLoadTypeStandard;
721     [_loader loadURL:URL referrer:(hideReferrer ? nil : referrer) loadType:loadType target:target triggeringEvent:event form:form formValues:values];
722
723     if (targetFrame != nil && _frame != targetFrame) {
724         [[targetFrame _bridge] activateWindow];
725     }
726 }
727
728 - (void)postWithURL:(NSURL *)URL referrer:(NSString *)referrer target:(NSString *)target data:(NSArray *)postData contentType:(NSString *)contentType triggeringEvent:(NSEvent *)event form:(DOMElement *)form formValues:(NSDictionary *)values
729 {
730     BOOL hideReferrer;
731     if (![self canLoadURL:URL fromReferrer:referrer hideReferrer:&hideReferrer])
732         return;
733
734     if ([target length] == 0) {
735         target = nil;
736     }
737
738     WebFrame *targetFrame = [_frame findFrameNamed:target];
739     if (![self canTargetLoadInFrame:[targetFrame _bridge]]) {
740         return;
741     }
742
743     [_frame _postWithURL:URL referrer:(hideReferrer ? nil : referrer) target:target data:postData contentType:contentType triggeringEvent:event form:form formValues:values];
744
745     if (targetFrame != nil && _frame != targetFrame) {
746         [[targetFrame _bridge] activateWindow];
747     }
748 }
749
750 - (WebCoreFrameBridge *)createChildFrameNamed:(NSString *)frameName 
751                                       withURL:(NSURL *)URL
752                                      referrer:(NSString *)referrer
753                                    ownerElement:(WebCoreElement *)ownerElement
754                               allowsScrolling:(BOOL)allowsScrolling 
755                                   marginWidth:(int)width
756                                  marginHeight:(int)height
757 {
758     BOOL hideReferrer;
759     if (![self canLoadURL:URL fromReferrer:referrer hideReferrer:&hideReferrer])
760         return nil;
761
762     ASSERT(_frame);
763     
764     WebFrameView *childView = [[WebFrameView alloc] initWithFrame:NSMakeRect(0,0,0,0)];
765     [childView setAllowsScrolling:allowsScrolling];
766     WebFrameBridge *newBridge = [[WebFrameBridge alloc] initSubframeWithOwnerElement:ownerElement frameName:frameName view:childView];
767     [_frame _addChild:[newBridge webFrame]];
768     [childView release];
769
770     [childView _setMarginWidth:width];
771     [childView _setMarginHeight:height];
772
773     [newBridge release];
774
775     if (!newBridge)
776         return nil;
777
778     [_frame _loadURL:URL referrer:(hideReferrer ? nil : referrer) intoChild:[newBridge webFrame]];
779
780     return newBridge;
781 }
782
783 - (void)saveDocumentState:(NSArray *)documentState
784 {
785     WebHistoryItem *item = [_frame _itemForSavingDocState];
786     LOG(Loading, "%@: saving form state from to 0x%x", [_frame name], item);
787     if (item) {
788         [item setDocumentState:documentState];
789         // You might think we could save the scroll state here too, but unfortunately this
790         // often gets called after WebFrame::_transitionToCommitted has restored the scroll
791         // position of the next document.
792     }
793 }
794
795 - (NSArray *)documentState
796 {
797     LOG(Loading, "%@: restoring form state from item 0x%x", [_frame name], [_frame _itemForRestoringDocState]);
798     return [[_frame _itemForRestoringDocState] documentState];
799 }
800
801 - (BOOL)saveDocumentToPageCache:(id)documentInfo
802 {
803     WebHistoryItem *item = [_frame _itemForSavingDocState];
804     if (![item hasPageCache]) {
805         return NO;
806     }
807     [[item pageCache] setObject:documentInfo forKey:WebCorePageCacheStateKey];
808     return YES;
809 }
810
811 - (NSString *)userAgentForURL:(NSURL *)URL
812 {
813     return [[self webView] userAgentForURL:URL];
814 }
815
816 - (BOOL)inNextKeyViewOutsideWebFrameViews
817 {
818     return _inNextKeyViewOutsideWebFrameViews;
819 }
820
821 - (NSView *)_nextKeyViewOutsideWebFrameViewsWithValidityCheck:(BOOL)mustBeValid
822 {
823     // We can get here in unusual situations such as the one listed in 4451831, so we
824     // return nil to avoid an infinite recursion.
825     if (_inNextKeyViewOutsideWebFrameViews)
826         return nil;
827     
828     _inNextKeyViewOutsideWebFrameViews = YES;
829     WebView *webView = [self webView];
830     // Do not ask webView for its next key view, but rather, ask it for 
831     // the next key view of the last view in its key view loop.
832     // Doing so gives us the correct answer as calculated by AppKit, 
833     // and makes HTML views behave like other views.
834     NSView *lastViewInLoop = [webView _findLastViewInKeyViewLoop];
835     NSView *nextKeyView = mustBeValid ? [lastViewInLoop nextValidKeyView] : [lastViewInLoop nextKeyView];
836     _inNextKeyViewOutsideWebFrameViews = NO;
837     return nextKeyView;
838 }
839
840 - (NSView *)nextKeyViewOutsideWebFrameViews
841 {
842     return [self _nextKeyViewOutsideWebFrameViewsWithValidityCheck:NO];
843 }
844
845 - (NSView *)nextValidKeyViewOutsideWebFrameViews
846 {
847     return [self _nextKeyViewOutsideWebFrameViewsWithValidityCheck:YES];
848 }
849
850 - (NSView *)previousKeyViewOutsideWebFrameViews
851 {
852     WebView *webView = [self webView];
853     NSView *previousKeyView = [webView previousKeyView];
854     return previousKeyView;
855 }
856
857 - (BOOL)defersLoading
858 {
859     return [[self webView] defersCallbacks];
860 }
861
862 - (void)setDefersLoading:(BOOL)defers
863 {
864     [[self webView] setDefersCallbacks:defers];
865 }
866
867 - (void)setNeedsReapplyStyles
868 {
869     NSView <WebDocumentView> *view = [[_frame frameView] documentView];
870     if ([view isKindOfClass:[WebHTMLView class]]) {
871         [(WebHTMLView *)view setNeedsToApplyStyles:YES];
872         [view setNeedsLayout:YES];
873         [view setNeedsDisplay:YES];
874     }
875 }
876
877 - (void)tokenizerProcessedData
878 {
879     [_frame _checkLoadComplete];
880 }
881
882 - (NSString *)incomingReferrer
883 {
884     return [[[self dataSource] request] _web_HTTPReferrer];
885 }
886
887 - (NSView *)pluginViewWithPackage:(WebPluginPackage *)pluginPackage
888                    attributeNames:(NSArray *)attributeNames
889                   attributeValues:(NSArray *)attributeValues
890                           baseURL:(NSURL *)baseURL
891                        DOMElement:(DOMElement *)element
892                      loadManually:(BOOL)loadManually
893 {
894     WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
895     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
896         
897     WebPluginController *pluginController = [docView _pluginController];
898     
899     // Store attributes in a dictionary so they can be passed to WebPlugins.
900     NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
901     
902     [pluginPackage load];
903     Class viewFactory = [pluginPackage viewFactory];
904     
905     NSView *view = nil;
906     NSDictionary *arguments = nil;
907     
908     if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
909         arguments = [NSDictionary dictionaryWithObjectsAndKeys:
910             baseURL, WebPlugInBaseURLKey,
911             attributes, WebPlugInAttributesKey,
912             pluginController, WebPlugInContainerKey,
913             [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
914             [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
915             element, WebPlugInContainingElementKey,
916             nil];
917         LOG(Plugins, "arguments:\n%@", arguments);
918     } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
919         arguments = [NSDictionary dictionaryWithObjectsAndKeys:
920             baseURL, WebPluginBaseURLKey,
921             attributes, WebPluginAttributesKey,
922             pluginController, WebPluginContainerKey,
923             element, WebPlugInContainingElementKey,
924             nil];
925         LOG(Plugins, "arguments:\n%@", arguments);
926     }
927
928     view = [WebPluginController plugInViewWithArguments:arguments fromPluginPackage:pluginPackage];
929     
930     [attributes release];
931     return view;
932 }
933
934 - (NSString *)valueForKey:(NSString *)key keys:(NSArray *)keys values:(NSArray *)values
935 {
936     unsigned count = [keys count];
937     unsigned i;
938     for (i = 0; i < count; i++) {
939         if ([[keys objectAtIndex:i] _webkit_isCaseInsensitiveEqualToString:key])
940             return [values objectAtIndex:i];
941     }
942     return nil;
943 }
944
945 - (NSView *)viewForPluginWithURL:(NSURL *)URL
946                   attributeNames:(NSArray *)attributeNames
947                  attributeValues:(NSArray *)attributeValues
948                         MIMEType:(NSString *)MIMEType
949                       DOMElement:(DOMElement *)element
950                     loadManually:(BOOL)loadManually
951 {
952     BOOL hideReferrer;
953     if (![self canLoadURL:URL fromReferrer:[self referrer] hideReferrer:&hideReferrer])
954         return nil;
955
956     ASSERT([attributeNames count] == [attributeValues count]);
957
958     WebBasePluginPackage *pluginPackage = nil;
959     NSView *view = nil;
960     int errorCode = 0;
961
962     WebView *wv = [self webView];
963     id wd = [wv UIDelegate];
964
965     if ([wd respondsToSelector:@selector(webView:plugInViewWithArguments:)]) {
966         NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
967         NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:
968             attributes, WebPlugInAttributesKey,
969             [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
970             URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
971             [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
972             element, WebPlugInContainingElementKey,
973             nil];
974         [attributes release];
975         view = [wd webView:wv plugInViewWithArguments:arguments];
976         if (view)
977             return view;
978     }
979
980     if ([MIMEType length] != 0)
981         pluginPackage = [[self webView] _pluginForMIMEType:MIMEType];
982     else
983         MIMEType = nil;
984     
985     NSString *extension = [[URL path] pathExtension];
986     if (!pluginPackage && [extension length] != 0) {
987         pluginPackage = [[self webView] _pluginForExtension:extension];
988         if (pluginPackage) {
989             NSString *newMIMEType = [pluginPackage MIMETypeForExtension:extension];
990             if ([newMIMEType length] != 0)
991                 MIMEType = newMIMEType;
992         }
993     }
994
995     NSURL *baseURL = [self baseURL];
996     if (pluginPackage) {
997         if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
998             view = [self pluginViewWithPackage:(WebPluginPackage *)pluginPackage
999                                 attributeNames:attributeNames
1000                                attributeValues:attributeValues
1001                                        baseURL:baseURL
1002                                     DOMElement:element
1003                                   loadManually:loadManually];
1004         } else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
1005             WebNetscapePluginEmbeddedView *embeddedView = [[[WebNetscapePluginEmbeddedView alloc] initWithFrame:NSZeroRect
1006                                                                   plugin:(WebNetscapePluginPackage *)pluginPackage
1007                                                                      URL:URL
1008                                                                  baseURL:baseURL
1009                                                                 MIMEType:MIMEType
1010                                                            attributeKeys:attributeNames
1011                                                          attributeValues:attributeValues
1012                                                             loadManually:loadManually
1013                                                               DOMElement:element] autorelease];
1014             view = embeddedView;
1015             [_frame _addPlugInView:embeddedView];
1016         } else
1017             ASSERT_NOT_REACHED();
1018     } else
1019         errorCode = WebKitErrorCannotFindPlugIn;
1020
1021     if (!errorCode && !view)
1022         errorCode = WebKitErrorCannotLoadPlugIn;
1023
1024     if (errorCode) {
1025         NSString *pluginPage = [self valueForKey:@"pluginspage" keys:attributeNames values:attributeValues];
1026         NSURL *pluginPageURL = pluginPage != nil ? [self URLWithAttributeString:pluginPage] : nil;
1027         NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
1028                                                         contentURL:URL
1029                                                      pluginPageURL:pluginPageURL
1030                                                         pluginName:[pluginPackage name]
1031                                                           MIMEType:MIMEType];
1032         WebNullPluginView *nullView = [[[WebNullPluginView alloc] initWithFrame:NSZeroRect error:error] autorelease];
1033         [_frame _addPlugInView:nullView];
1034         view = nullView;
1035         [error release];
1036     }
1037     
1038     ASSERT(view);
1039     return view;
1040 }
1041
1042 - (void)redirectDataToPlugin:(NSView *)pluginView
1043 {
1044     WebHTMLRepresentation *representation = (WebHTMLRepresentation *)[[_frame dataSource] representation];
1045
1046     if ([pluginView isKindOfClass:[WebNetscapePluginEmbeddedView class]])
1047         [representation _redirectDataToManualLoader:(WebNetscapePluginEmbeddedView *)pluginView forPluginView:pluginView];
1048     else {
1049         WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
1050         ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1051         
1052         WebPluginController *pluginController = [docView _pluginController];
1053         [representation _redirectDataToManualLoader:pluginController forPluginView:pluginView];
1054     }
1055 }
1056
1057 - (NSView *)viewForJavaAppletWithFrame:(NSRect)theFrame
1058                         attributeNames:(NSArray *)attributeNames
1059                        attributeValues:(NSArray *)attributeValues
1060                                baseURL:(NSURL *)baseURL
1061                             DOMElement:(DOMElement *)element
1062 {
1063     NSString *MIMEType = @"application/x-java-applet";
1064     WebBasePluginPackage *pluginPackage;
1065     NSView *view = nil;
1066     
1067     pluginPackage = [[self webView] _pluginForMIMEType:MIMEType];
1068
1069     if (pluginPackage) {
1070         if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
1071             // For some reason, the Java plug-in requires that we pass the dimension of the plug-in as attributes.
1072             NSMutableArray *names = [attributeNames mutableCopy];
1073             NSMutableArray *values = [attributeValues mutableCopy];
1074             if ([self valueForKey:@"width" keys:attributeNames values:attributeValues] == nil) {
1075                 [names addObject:@"width"];
1076                 [values addObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.width]];
1077             }
1078             if ([self valueForKey:@"height" keys:attributeNames values:attributeValues] == nil) {
1079                 [names addObject:@"height"];
1080                 [values addObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.height]];
1081             }
1082             view = [self pluginViewWithPackage:(WebPluginPackage *)pluginPackage
1083                                 attributeNames:names
1084                                attributeValues:values
1085                                        baseURL:baseURL
1086                                     DOMElement:element
1087                                   loadManually:NO];
1088             [names release];
1089             [values release];
1090         } else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
1091             view = [[[WebNetscapePluginEmbeddedView alloc] initWithFrame:theFrame
1092                                                                   plugin:(WebNetscapePluginPackage *)pluginPackage
1093                                                                      URL:nil
1094                                                                  baseURL:baseURL
1095                                                                 MIMEType:MIMEType
1096                                                            attributeKeys:attributeNames
1097                                                          attributeValues:attributeValues
1098                                                             loadManually:NO
1099                                                               DOMElement:element] autorelease];
1100         } else {
1101             ASSERT_NOT_REACHED();
1102         }
1103     }
1104
1105     if (!view) {
1106         NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorJavaUnavailable
1107                                                         contentURL:nil
1108                                                      pluginPageURL:nil
1109                                                         pluginName:[pluginPackage name]
1110                                                           MIMEType:MIMEType];
1111         view = [[[WebNullPluginView alloc] initWithFrame:theFrame error:error] autorelease];
1112         [error release];
1113     }
1114
1115     ASSERT(view);
1116
1117     return view;
1118 }
1119
1120 #ifndef NDEBUG
1121 static BOOL loggedObjectCacheSize = NO;
1122 #endif
1123
1124 -(int)getObjectCacheSize
1125 {
1126     vm_size_t memSize = WebSystemMainMemory();
1127     int cacheSize = [[self _preferences] _objectCacheSize];
1128     int multiplier = 1;
1129     if (memSize >= 1024 * 1024 * 1024)
1130         multiplier = 4;
1131     else if (memSize >= 512 * 1024 * 1024)
1132         multiplier = 2;
1133
1134 #ifndef NDEBUG
1135     if (!loggedObjectCacheSize){
1136         LOG (CacheSizes, "Object cache size set to %d bytes.", cacheSize * multiplier);
1137         loggedObjectCacheSize = YES;
1138     }
1139 #endif
1140
1141     return cacheSize * multiplier;
1142 }
1143
1144 - (ObjectElementType)determineObjectFromMIMEType:(NSString*)MIMEType URL:(NSURL*)URL
1145 {
1146     if ([MIMEType length] == 0) {
1147         // Try to guess the MIME type based off the extension.
1148         NSString *extension = [[URL path] pathExtension];
1149         if ([extension length] > 0) {
1150             MIMEType = WKGetMIMETypeForExtension(extension);
1151             if ([MIMEType length] == 0 && [[self webView] _pluginForExtension:extension])
1152                 // If no MIME type is specified, use a plug-in if we have one that can handle the extension.
1153                 return ObjectElementPlugin;
1154         }
1155     }
1156
1157     if ([MIMEType length] == 0)
1158         return ObjectElementFrame; // Go ahead and hope that we can display the content.
1159
1160     if ([[self webView] _isMIMETypeRegisteredAsPlugin:MIMEType])
1161         return ObjectElementPlugin;
1162
1163     if ([WebFrameView _viewClassForMIMEType:MIMEType])
1164         return ObjectElementFrame;
1165     
1166     return ObjectElementNone;
1167 }
1168
1169 - (void)loadEmptyDocumentSynchronously
1170 {
1171     NSURL *url = [[NSURL alloc] initWithString:@""];
1172     NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
1173     [_frame loadRequest:request];
1174     [request release];
1175     [url release];
1176 }
1177
1178 - (NSString *)MIMETypeForPath:(NSString *)path
1179 {
1180     ASSERT(path);
1181     NSString *extension = [path pathExtension];
1182     NSString *type = WKGetMIMETypeForExtension(extension);
1183     return [type length] == 0 ? (NSString *)@"application/octet-stream" : type;
1184 }
1185
1186 - (void)allowDHTMLDrag:(BOOL *)flagDHTML UADrag:(BOOL *)flagUA
1187 {
1188     WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
1189     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1190     unsigned int mask = [docView _delegateDragSourceActionMask];
1191     *flagDHTML = (mask & WebDragSourceActionDHTML) != 0;
1192     *flagUA = ((mask & WebDragSourceActionImage) || (mask & WebDragSourceActionLink) || (mask & WebDragSourceActionSelection));
1193 }
1194
1195 - (BOOL)startDraggingImage:(NSImage *)dragImage at:(NSPoint)dragLoc operation:(NSDragOperation)op event:(NSEvent *)event sourceIsDHTML:(BOOL)flag DHTMLWroteData:(BOOL)dhtmlWroteData
1196 {
1197     WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
1198     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1199     [docView _setInitiatedDrag:YES];
1200     return [docView _startDraggingImage:dragImage at:dragLoc operation:op event:event sourceIsDHTML:flag DHTMLWroteData:dhtmlWroteData];
1201 }
1202
1203 - (void)handleAutoscrollForMouseDragged:(NSEvent *)event;
1204 {
1205     WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
1206
1207     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1208
1209     [docView _handleAutoscrollForMouseDragged:event];
1210 }
1211
1212 - (BOOL)mayStartDragAtEventLocation:(NSPoint)location
1213 {
1214     WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
1215
1216     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1217
1218     return [docView _mayStartDragAtEventLocation:location];
1219 }
1220
1221 - (BOOL)selectWordBeforeMenuEvent
1222 {
1223     return [[self webView] _selectWordBeforeMenuEvent];
1224 }
1225
1226 - (int)historyLength
1227 {
1228     return [[[self webView] backForwardList] backListCount] + 1;
1229 }
1230
1231 - (BOOL)canGoBackOrForward:(int)distance
1232 {
1233     if (distance == 0)
1234         return YES;
1235
1236     if (distance > 0 && distance <= [[[self webView] backForwardList] forwardListCount])
1237         return YES;
1238
1239     if (distance < 0 && -distance <= [[[self webView] backForwardList] backListCount])
1240         return YES;
1241     
1242     return NO;
1243 }
1244
1245 - (void)goBackOrForward:(int)distance
1246 {
1247     if (distance == 0) {
1248         return;
1249     }
1250     WebView *webView = [self webView];
1251     WebBackForwardList *list = [webView backForwardList];
1252     WebHistoryItem *item = [list itemAtIndex:distance];
1253     if (!item) {
1254         if (distance > 0) {
1255             int forwardListCount = [list forwardListCount];
1256             if (forwardListCount > 0) {
1257                 item = [list itemAtIndex:forwardListCount];
1258             }
1259         } else {
1260             int backListCount = [list forwardListCount];
1261             if (backListCount > 0) {
1262                 item = [list itemAtIndex:-backListCount];
1263             }
1264         }
1265     }
1266     if (item) {
1267         [webView goToBackForwardItem:item];
1268     }
1269 }
1270
1271 - (NSURL*)historyURL:(int)distance
1272 {
1273     WebView *webView = [self webView];
1274     WebBackForwardList *list = [webView backForwardList];
1275     WebHistoryItem *item = [list itemAtIndex:distance];
1276     if (!item) {
1277         if (distance > 0) {
1278             int forwardListCount = [list forwardListCount];
1279             if (forwardListCount > 0)
1280                 item = [list itemAtIndex:forwardListCount];
1281         } else {
1282             int backListCount = [list forwardListCount];
1283             if (backListCount > 0)
1284                 item = [list itemAtIndex:-backListCount];
1285         }
1286     }
1287     if (item)
1288         return [item URL];
1289     
1290     return nil;
1291 }
1292
1293 static id <WebFormDelegate> formDelegate(WebFrameBridge *self)
1294 {
1295     ASSERT(self->_frame != nil);
1296     return [[self->_frame webView] _formDelegate];
1297 }
1298
1299 #define FormDelegateLog(ctrl)  LOG(FormDelegate, "control=%@", ctrl)
1300
1301 - (void)textFieldDidBeginEditing:(DOMHTMLInputElement *)element
1302 {
1303     FormDelegateLog(element);
1304     [formDelegate(self) textFieldDidBeginEditing:element inFrame:_frame];
1305 }
1306
1307 - (void)textFieldDidEndEditing:(DOMHTMLInputElement *)element
1308 {
1309     FormDelegateLog(element);
1310     [formDelegate(self) textFieldDidEndEditing:element inFrame:_frame];
1311 }
1312
1313 - (void)textDidChangeInTextField:(DOMHTMLInputElement *)element
1314 {
1315     FormDelegateLog(element);
1316     [formDelegate(self) textDidChangeInTextField:(DOMHTMLInputElement *)element inFrame:_frame];
1317 }
1318
1319 - (void)textDidChangeInTextArea:(DOMHTMLTextAreaElement *)element
1320 {
1321     FormDelegateLog(element);
1322     [formDelegate(self) textDidChangeInTextArea:element inFrame:_frame];
1323 }
1324
1325 - (BOOL)textField:(DOMHTMLInputElement *)element doCommandBySelector:(SEL)commandSelector
1326 {
1327     FormDelegateLog(element);
1328     return [formDelegate(self) textField:element doCommandBySelector:commandSelector inFrame:_frame];
1329 }
1330
1331 - (BOOL)textField:(DOMHTMLInputElement *)element shouldHandleEvent:(NSEvent *)event
1332 {
1333     FormDelegateLog(element);
1334     return [formDelegate(self) textField:element shouldHandleEvent:event inFrame:_frame];
1335 }
1336
1337 - (void)frameDetached
1338 {
1339     [_frame stopLoading];
1340     [_frame _detachFromParent];
1341 }
1342
1343 - (void)setHasBorder:(BOOL)hasBorder
1344 {
1345     [[_frame frameView] _setHasBorder:hasBorder];
1346 }
1347
1348 - (NSFileWrapper *)fileWrapperForURL:(NSURL *)URL
1349 {
1350     return [[_frame dataSource] _fileWrapperForURL:URL];
1351 }
1352
1353 - (void)print
1354 {
1355     id wd = [[self webView] UIDelegate];
1356     
1357     if ([wd respondsToSelector:@selector(webView:printFrameView:)]) {
1358         [wd webView:[self webView] printFrameView:[_frame frameView]];
1359     } else {
1360         [[WebDefaultUIDelegate sharedUIDelegate] webView:[self webView] printFrameView:[_frame frameView]];
1361     }
1362 }
1363
1364 - (jobject)getAppletInView:(NSView *)view
1365 {
1366     jobject applet;
1367
1368     if ([view respondsToSelector:@selector(webPlugInGetApplet)])
1369         applet = [view webPlugInGetApplet];
1370     else
1371         applet = [self pollForAppletInView:view];
1372         
1373     return applet;
1374 }
1375
1376 // NOTE: pollForAppletInView: will block until the block is ready to use, or
1377 // until a timeout is exceeded.  It will return nil if the timeour is
1378 // exceeded.
1379 // Deprecated, use getAppletInView:.
1380 - (jobject)pollForAppletInView:(NSView *)view
1381 {
1382     jobject applet = 0;
1383     
1384     if ([view respondsToSelector:@selector(pollForAppletInWindow:)]) {
1385         // The Java VM needs the containing window of the view to
1386         // initialize.  The view may not yet be in the window's view 
1387         // hierarchy, so we have to pass the window when requesting
1388         // the applet.
1389         applet = [view pollForAppletInWindow:[[self webView] window]];
1390     }
1391     
1392     return applet;
1393 }
1394
1395 - (void)respondToChangedContents
1396 {
1397     NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1398     if ([view isKindOfClass:[WebHTMLView class]]) {
1399         [(WebHTMLView *)view _updateFontPanel];
1400     }
1401     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidChangeNotification object:[self webView]];
1402 }
1403
1404 - (void)respondToChangedSelection
1405 {
1406     NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1407     if ([view isKindOfClass:[WebHTMLView class]]) {
1408         [(WebHTMLView *)view _selectionChanged];
1409     }
1410     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidChangeSelectionNotification object:[self webView]];
1411 }
1412
1413 - (NSUndoManager *)undoManager
1414 {
1415     return [[self webView] undoManager];
1416 }
1417
1418 - (void)issueCutCommand
1419 {
1420     NSView* documentView = [[_frame frameView] documentView];
1421     if ([documentView isKindOfClass:[WebHTMLView class]])
1422         [(WebHTMLView*)documentView cut:nil];
1423 }
1424
1425 - (void)issueCopyCommand
1426 {
1427     NSView* documentView = [[_frame frameView] documentView];
1428     if ([documentView isKindOfClass:[WebHTMLView class]])
1429         [(WebHTMLView*)documentView copy:nil];
1430 }
1431
1432 - (void)issuePasteCommand
1433 {
1434     NSView* documentView = [[_frame frameView] documentView];
1435     if ([documentView isKindOfClass:[WebHTMLView class]])
1436         [(WebHTMLView*)documentView paste:nil];
1437 }
1438
1439 - (void)issuePasteAndMatchStyleCommand
1440 {
1441     NSView <WebDocumentView> *documentView = [[_frame frameView] documentView];
1442     if ([documentView isKindOfClass:[WebHTMLView class]])
1443         [(WebHTMLView*)documentView pasteAsPlainText:nil];
1444 }
1445
1446 - (void)issueTransposeCommand
1447 {
1448     NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1449     if ([view isKindOfClass:[WebHTMLView class]])
1450         [(WebHTMLView *)view transpose:nil];
1451 }
1452
1453 - (BOOL)canPaste
1454 {
1455     NSView* documentView = [[_frame frameView] documentView];
1456     return [documentView isKindOfClass:[WebHTMLView class]] && [(WebHTMLView*)documentView _canPaste];
1457 }
1458
1459 - (void)setIsSelected:(BOOL)isSelected forView:(NSView *)view
1460 {
1461     if ([view respondsToSelector:@selector(webPlugInSetIsSelected:)]) {
1462         [view webPlugInSetIsSelected:isSelected];
1463     }
1464     else if ([view respondsToSelector:@selector(setIsSelected:)]) {
1465         [view setIsSelected:isSelected];
1466     }
1467 }
1468
1469 - (NSString *)overrideMediaType
1470 {
1471     return [[self webView] mediaStyle];
1472 }
1473
1474 - (BOOL)isEditable
1475 {
1476     return [[self webView] isEditable];
1477 }
1478
1479 - (BOOL)shouldChangeSelectedDOMRange:(DOMRange *)currentRange toDOMRange:(DOMRange *)proposedRange affinity:(NSSelectionAffinity)selectionAffinity stillSelecting:(BOOL)flag
1480 {
1481     return [[self webView] _shouldChangeSelectedDOMRange:currentRange toDOMRange:proposedRange affinity:selectionAffinity stillSelecting:flag];
1482 }
1483
1484 - (BOOL)shouldDeleteSelectedDOMRange:(DOMRange *)range
1485 {
1486     WebView *webView = [self webView];
1487     return [[webView _editingDelegateForwarder] webView:webView shouldDeleteDOMRange:range];
1488 }
1489
1490 - (BOOL)shouldBeginEditing:(DOMRange *)range
1491 {
1492     return [[self webView] _shouldBeginEditingInDOMRange:range];
1493 }
1494
1495 - (BOOL)shouldEndEditing:(DOMRange *)range
1496 {
1497     return [[self webView] _shouldEndEditingInDOMRange:range];
1498 }
1499
1500 - (void)didBeginEditing
1501 {
1502     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidBeginEditingNotification object:[_frame webView]];
1503 }
1504
1505 - (void)didEndEditing
1506 {
1507     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidEndEditingNotification object:[_frame webView]];
1508 }
1509
1510 - (void)windowObjectCleared
1511 {
1512     WebView *wv = [self webView];
1513     [[wv _frameLoadDelegateForwarder] webView:wv windowScriptObjectAvailable:[self windowScriptObject]];
1514     if ([wv scriptDebugDelegate] || [WebScriptDebugServer listenerCount]) {
1515         [_frame _detachScriptDebugger]; // FIXME: remove this once <rdar://problem/4608404> is fixed
1516         [_frame _attachScriptDebugger];
1517     }
1518 }
1519
1520 - (int)spellCheckerDocumentTag
1521 {
1522     return [[self webView] spellCheckerDocumentTag];
1523 }
1524
1525 - (BOOL)isContinuousSpellCheckingEnabled
1526 {
1527     return [[self webView] isContinuousSpellCheckingEnabled];
1528 }
1529
1530 - (void)didFirstLayout
1531 {
1532     [_loader didFirstLayout];
1533 }
1534
1535 - (BOOL)_compareDashboardRegions:(NSDictionary *)regions
1536 {
1537     return [lastDashboardRegions isEqualToDictionary:regions];
1538 }
1539
1540 - (void)dashboardRegionsChanged:(NSMutableDictionary *)regions
1541 {
1542     WebView *wv = [self webView];
1543     id wd = [wv UIDelegate];
1544     
1545     [wv _addScrollerDashboardRegions:regions];
1546     
1547     if (![self _compareDashboardRegions:regions]) {
1548         if ([wd respondsToSelector:@selector(webView:dashboardRegionsChanged:)]) {
1549             [wd webView:wv dashboardRegionsChanged:regions];
1550             [lastDashboardRegions release];
1551             lastDashboardRegions = [regions retain];
1552         }
1553     }
1554 }
1555
1556 - (NSRect)customHighlightRect:(NSString*)type forLine:(NSRect)lineRect
1557 {
1558     ASSERT(_frame != nil);
1559     NSView *documentView = [[_frame frameView] documentView];
1560     if (![documentView isKindOfClass:[WebHTMLView class]])
1561         return NSZeroRect;
1562
1563     WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
1564     id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
1565     return [highlighter highlightRectForLine:lineRect];
1566 }
1567
1568 - (void)paintCustomHighlight:(NSString*)type forBox:(NSRect)boxRect onLine:(NSRect)lineRect behindText:(BOOL)text
1569                   entireLine:(BOOL)line
1570 {
1571     ASSERT(_frame != nil);
1572     NSView *documentView = [[_frame frameView] documentView];
1573     if (![documentView isKindOfClass:[WebHTMLView class]])
1574         return;
1575
1576     WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
1577     id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
1578     [highlighter paintHighlightForBox:boxRect onLine:lineRect behindText:text entireLine:line];
1579 }
1580
1581 - (NSString *)nameForUndoAction:(WebUndoAction)undoAction
1582 {
1583     switch (undoAction) {
1584         case WebUndoActionUnspecified: return nil;
1585         case WebUndoActionSetColor: return UI_STRING_KEY("Set Color", "Set Color (Undo action name)", "Undo action name");
1586         case WebUndoActionSetBackgroundColor: return UI_STRING_KEY("Set Background Color", "Set Background Color (Undo action name)", "Undo action name");
1587         case WebUndoActionTurnOffKerning: return UI_STRING_KEY("Turn Off Kerning", "Turn Off Kerning (Undo action name)", "Undo action name");
1588         case WebUndoActionTightenKerning: return UI_STRING_KEY("Tighten Kerning", "Tighten Kerning (Undo action name)", "Undo action name");
1589         case WebUndoActionLoosenKerning: return UI_STRING_KEY("Loosen Kerning", "Loosen Kerning (Undo action name)", "Undo action name");
1590         case WebUndoActionUseStandardKerning: return UI_STRING_KEY("Use Standard Kerning", "Use Standard Kerning (Undo action name)", "Undo action name");
1591         case WebUndoActionTurnOffLigatures: return UI_STRING_KEY("Turn Off Ligatures", "Turn Off Ligatures (Undo action name)", "Undo action name");
1592         case WebUndoActionUseStandardLigatures: return UI_STRING_KEY("Use Standard Ligatures", "Use Standard Ligatures (Undo action name)", "Undo action name");
1593         case WebUndoActionUseAllLigatures: return UI_STRING_KEY("Use All Ligatures", "Use All Ligatures (Undo action name)", "Undo action name");
1594         case WebUndoActionRaiseBaseline: return UI_STRING_KEY("Raise Baseline", "Raise Baseline (Undo action name)", "Undo action name");
1595         case WebUndoActionLowerBaseline: return UI_STRING_KEY("Lower Baseline", "Lower Baseline (Undo action name)", "Undo action name");
1596         case WebUndoActionSetTraditionalCharacterShape: return UI_STRING_KEY("Set Traditional Character Shape", "Set Traditional Character Shape (Undo action name)", "Undo action name");
1597         case WebUndoActionSetFont: return UI_STRING_KEY("Set Font", "Set Font (Undo action name)", "Undo action name");
1598         case WebUndoActionChangeAttributes: return UI_STRING_KEY("Change Attributes", "Change Attributes (Undo action name)", "Undo action name");
1599         case WebUndoActionAlignLeft: return UI_STRING_KEY("Align Left", "Align Left (Undo action name)", "Undo action name");
1600         case WebUndoActionAlignRight: return UI_STRING_KEY("Align Right", "Align Right (Undo action name)", "Undo action name");
1601         case WebUndoActionCenter: return UI_STRING_KEY("Center", "Center (Undo action name)", "Undo action name");
1602         case WebUndoActionJustify: return UI_STRING_KEY("Justify", "Justify (Undo action name)", "Undo action name");
1603         case WebUndoActionSetWritingDirection: return UI_STRING_KEY("Set Writing Direction", "Set Writing Direction (Undo action name)", "Undo action name");
1604         case WebUndoActionSubscript: return UI_STRING_KEY("Subscript", "Subscript (Undo action name)", "Undo action name");
1605         case WebUndoActionSuperscript: return UI_STRING_KEY("Superscript", "Superscript (Undo action name)", "Undo action name");
1606         case WebUndoActionUnderline: return UI_STRING_KEY("Underline", "Underline (Undo action name)", "Undo action name");
1607         case WebUndoActionOutline: return UI_STRING_KEY("Outline", "Outline (Undo action name)", "Undo action name");
1608         case WebUndoActionUnscript: return UI_STRING_KEY("Unscript", "Unscript (Undo action name)", "Undo action name");
1609         case WebUndoActionDrag: return UI_STRING_KEY("Drag", "Drag (Undo action name)", "Undo action name");
1610         case WebUndoActionCut: return UI_STRING_KEY("Cut", "Cut (Undo action name)", "Undo action name");
1611         case WebUndoActionPaste: return UI_STRING_KEY("Paste", "Paste (Undo action name)", "Undo action name");
1612         case WebUndoActionPasteFont: return UI_STRING_KEY("Paste Font", "Paste Font (Undo action name)", "Undo action name");
1613         case WebUndoActionPasteRuler: return UI_STRING_KEY("Paste Ruler", "Paste Ruler (Undo action name)", "Undo action name");
1614         case WebUndoActionTyping: return UI_STRING_KEY("Typing", "Typing (Undo action name)", "Undo action name");
1615         case WebUndoActionCreateLink: return UI_STRING_KEY("Create Link", "Create Link (Undo action name)", "Undo action name");
1616         case WebUndoActionUnlink: return UI_STRING_KEY("Unlink", "Unlink (Undo action name)", "Undo action name");
1617         case WebUndoActionInsertList: return UI_STRING_KEY("Insert List", "Insert List (Undo action name)", "Undo action name");
1618         case WebUndoActionFormatBlock: return UI_STRING_KEY("Formatting", "Format Block (Undo action name)", "Undo action name");
1619         case WebUndoActionIndent: return UI_STRING_KEY("Indent", "Indent (Undo action name)", "Undo action name");
1620         case WebUndoActionOutdent: return UI_STRING_KEY("Outdent", "Outdent (Undo action name)", "Undo action name");
1621     }
1622     return nil;
1623 }
1624
1625 - (WebCorePageBridge *)createModalDialogWithURL:(NSURL *)URL
1626 {
1627     ASSERT(_frame != nil);
1628
1629     NSMutableURLRequest *request = nil;
1630
1631     if (URL != nil && ![URL _web_isEmpty]) {
1632         request = [NSMutableURLRequest requestWithURL:URL];
1633         [request _web_setHTTPReferrer:[self referrer]];
1634     }
1635
1636     WebView *currentWebView = [self webView];
1637     id UIDelegate = [currentWebView UIDelegate];
1638
1639     WebView *newWebView = nil;
1640     if ([UIDelegate respondsToSelector:@selector(webView:createWebViewModalDialogWithRequest:)])
1641         newWebView = [UIDelegate webView:currentWebView createWebViewModalDialogWithRequest:request];
1642     else if ([UIDelegate respondsToSelector:@selector(webView:createWebViewWithRequest:)])
1643         newWebView = [UIDelegate webView:currentWebView createWebViewWithRequest:request];
1644     else
1645         newWebView = [[WebDefaultUIDelegate sharedUIDelegate] webView:currentWebView createWebViewWithRequest:request];
1646
1647     return [newWebView _pageBridge];
1648 }
1649
1650 - (BOOL)canRunModal
1651 {
1652     WebView *webView = [self webView];
1653     id UIDelegate = [webView UIDelegate];
1654     return [UIDelegate respondsToSelector:@selector(webViewRunModal:)];
1655 }
1656
1657 - (BOOL)canRunModalNow
1658 {
1659     return [self canRunModal] && ![WebLoader inConnectionCallback];
1660 }
1661
1662 - (void)runModal
1663 {
1664     if (![self canRunModal])
1665         return;
1666
1667     WebView *webView = [self webView];
1668     if ([webView defersCallbacks]) {
1669         LOG_ERROR("tried to run modal in a view when it was deferring callbacks -- should never happen");
1670         return;
1671     }
1672
1673     // Defer callbacks in all the other views in this group, so we don't try to run JavaScript
1674     // in a way that could interact with this view.
1675     NSMutableArray *deferredWebViews = [NSMutableArray array];
1676     NSString *namespace = [webView groupName];
1677     if (namespace) {
1678         NSEnumerator *enumerator = [WebCoreFrameNamespaces framesInNamespace:namespace];
1679         WebView *otherWebView;
1680         while ((otherWebView = [[enumerator nextObject] webView]) != nil) {
1681             if (otherWebView != webView && ![otherWebView defersCallbacks]) {
1682                 [otherWebView setDefersCallbacks:YES];
1683                 [deferredWebViews addObject:otherWebView];
1684             }
1685         }
1686     }
1687
1688     // Go run the modal event loop.
1689     [[webView UIDelegate] webViewRunModal:webView];
1690
1691     // Restore the callbacks for any views that we deferred them for.
1692     unsigned count = [deferredWebViews count];
1693     unsigned i;
1694     for (i = 0; i < count; ++i) {
1695         WebView *otherWebView = [deferredWebViews objectAtIndex:i];
1696         [otherWebView setDefersCallbacks:NO];
1697     }
1698 }
1699
1700 - (void)handledOnloadEvents
1701 {
1702     [_frame _handledOnloadEvents];
1703 }
1704
1705 - (void)closeURL
1706 {
1707     [_frame _willCloseURL];
1708     [super closeURL];
1709 }
1710
1711 - (NSURLResponse*)mainResourceURLResponse
1712 {
1713     return [[_frame dataSource] response];
1714 }
1715
1716 - (NSString*)imageTitleForFilename:(NSString*)filename size:(NSSize)size
1717 {
1718     return [NSString stringWithFormat:UI_STRING("%@ %.0f√ó%.0f pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filename, size.width, size.height];
1719 }
1720
1721 - (void)notifyIconChanged:(NSURL*)iconURL
1722 {
1723     [_loader _notifyIconChanged:iconURL];
1724 }
1725
1726 - (NSURL*)originalRequestURL
1727 {
1728     return [[[_loader activeDataSource] initialRequest] URL];
1729 }
1730
1731 - (BOOL)isLoadTypeReload
1732 {
1733     return [_loader loadType] == WebFrameLoadTypeReload;
1734 }
1735
1736 @end