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