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