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