WebCore:
[WebKit-https.git] / WebKit / WebCoreSupport / WebFrameBridge.m
1 /*
2  * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #import "WebFrameBridge.h"
30
31 #import <JavaScriptCore/Assertions.h>
32 #import "WebBackForwardList.h"
33 #import "WebBaseNetscapePluginView.h"
34 #import "WebBasePluginPackage.h"
35 #import "WebDataSourceInternal.h"
36 #import "WebDefaultUIDelegate.h"
37 #import "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     [[self dataSource] _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 = [[self dataSource] _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     return [docView _startDraggingImage:dragImage at:dragLoc operation:op event:event sourceIsDHTML:flag DHTMLWroteData:dhtmlWroteData];
1192 }
1193
1194 - (void)handleAutoscrollForMouseDragged:(NSEvent *)event;
1195 {
1196     WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
1197
1198     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1199
1200     [docView _handleAutoscrollForMouseDragged:event];
1201 }
1202
1203 - (BOOL)mayStartDragAtEventLocation:(NSPoint)location
1204 {
1205     WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
1206
1207     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
1208
1209     return [docView _mayStartDragAtEventLocation:location];
1210 }
1211
1212 - (BOOL)selectWordBeforeMenuEvent
1213 {
1214     return [[self webView] _selectWordBeforeMenuEvent];
1215 }
1216
1217 - (int)historyLength
1218 {
1219     return [[[self webView] backForwardList] backListCount] + 1;
1220 }
1221
1222 - (BOOL)canGoBackOrForward:(int)distance
1223 {
1224     if (distance == 0)
1225         return YES;
1226
1227     if (distance > 0 && distance <= [[[self webView] backForwardList] forwardListCount])
1228         return YES;
1229
1230     if (distance < 0 && -distance <= [[[self webView] backForwardList] backListCount])
1231         return YES;
1232     
1233     return NO;
1234 }
1235
1236 - (void)goBackOrForward:(int)distance
1237 {
1238     if (distance == 0) {
1239         return;
1240     }
1241     WebView *webView = [self webView];
1242     WebBackForwardList *list = [webView backForwardList];
1243     WebHistoryItem *item = [list itemAtIndex:distance];
1244     if (!item) {
1245         if (distance > 0) {
1246             int forwardListCount = [list forwardListCount];
1247             if (forwardListCount > 0) {
1248                 item = [list itemAtIndex:forwardListCount];
1249             }
1250         } else {
1251             int backListCount = [list forwardListCount];
1252             if (backListCount > 0) {
1253                 item = [list itemAtIndex:-backListCount];
1254             }
1255         }
1256     }
1257     if (item) {
1258         [webView goToBackForwardItem:item];
1259     }
1260 }
1261
1262 - (NSURL*)historyURL:(int)distance
1263 {
1264     WebView *webView = [self webView];
1265     WebBackForwardList *list = [webView backForwardList];
1266     WebHistoryItem *item = [list itemAtIndex:distance];
1267     if (!item) {
1268         if (distance > 0) {
1269             int forwardListCount = [list forwardListCount];
1270             if (forwardListCount > 0)
1271                 item = [list itemAtIndex:forwardListCount];
1272         } else {
1273             int backListCount = [list forwardListCount];
1274             if (backListCount > 0)
1275                 item = [list itemAtIndex:-backListCount];
1276         }
1277     }
1278     if (item)
1279         return [item URL];
1280     
1281     return nil;
1282 }
1283
1284 static id <WebFormDelegate> formDelegate(WebFrameBridge *self)
1285 {
1286     ASSERT(self->_frame != nil);
1287     return [[self->_frame webView] _formDelegate];
1288 }
1289
1290 #define FormDelegateLog(ctrl)  LOG(FormDelegate, "control=%@", ctrl)
1291
1292 - (void)textFieldDidBeginEditing:(DOMHTMLInputElement *)element
1293 {
1294     FormDelegateLog(element);
1295     [formDelegate(self) textFieldDidBeginEditing:element inFrame:_frame];
1296 }
1297
1298 - (void)textFieldDidEndEditing:(DOMHTMLInputElement *)element
1299 {
1300     FormDelegateLog(element);
1301     [formDelegate(self) textFieldDidEndEditing:element inFrame:_frame];
1302 }
1303
1304 - (void)textDidChangeInTextField:(DOMHTMLInputElement *)element
1305 {
1306     FormDelegateLog(element);
1307     [formDelegate(self) textDidChangeInTextField:(DOMHTMLInputElement *)element inFrame:_frame];
1308 }
1309
1310 - (void)textDidChangeInTextArea:(DOMHTMLTextAreaElement *)element
1311 {
1312     FormDelegateLog(element);
1313     [formDelegate(self) textDidChangeInTextArea:element inFrame:_frame];
1314 }
1315
1316 - (BOOL)textField:(DOMHTMLInputElement *)element doCommandBySelector:(SEL)commandSelector
1317 {
1318     FormDelegateLog(element);
1319     return [formDelegate(self) textField:element doCommandBySelector:commandSelector inFrame:_frame];
1320 }
1321
1322 - (BOOL)textField:(DOMHTMLInputElement *)element shouldHandleEvent:(NSEvent *)event
1323 {
1324     FormDelegateLog(element);
1325     return [formDelegate(self) textField:element shouldHandleEvent:event inFrame:_frame];
1326 }
1327
1328 - (void)frameDetached
1329 {
1330     [_frame stopLoading];
1331     [_frame _detachFromParent];
1332 }
1333
1334 - (void)setHasBorder:(BOOL)hasBorder
1335 {
1336     [[_frame frameView] _setHasBorder:hasBorder];
1337 }
1338
1339 - (NSFileWrapper *)fileWrapperForURL:(NSURL *)URL
1340 {
1341     return [[_frame dataSource] _fileWrapperForURL:URL];
1342 }
1343
1344 - (void)print
1345 {
1346     id wd = [[self webView] UIDelegate];
1347     
1348     if ([wd respondsToSelector:@selector(webView:printFrameView:)]) {
1349         [wd webView:[self webView] printFrameView:[_frame frameView]];
1350     } else {
1351         [[WebDefaultUIDelegate sharedUIDelegate] webView:[self webView] printFrameView:[_frame frameView]];
1352     }
1353 }
1354
1355 - (jobject)getAppletInView:(NSView *)view
1356 {
1357     jobject applet;
1358
1359     if ([view respondsToSelector:@selector(webPlugInGetApplet)])
1360         applet = [view webPlugInGetApplet];
1361     else
1362         applet = [self pollForAppletInView:view];
1363         
1364     return applet;
1365 }
1366
1367 // NOTE: pollForAppletInView: will block until the block is ready to use, or
1368 // until a timeout is exceeded.  It will return nil if the timeour is
1369 // exceeded.
1370 // Deprecated, use getAppletInView:.
1371 - (jobject)pollForAppletInView:(NSView *)view
1372 {
1373     jobject applet = 0;
1374     
1375     if ([view respondsToSelector:@selector(pollForAppletInWindow:)]) {
1376         // The Java VM needs the containing window of the view to
1377         // initialize.  The view may not yet be in the window's view 
1378         // hierarchy, so we have to pass the window when requesting
1379         // the applet.
1380         applet = [view pollForAppletInWindow:[[self webView] window]];
1381     }
1382     
1383     return applet;
1384 }
1385
1386 - (void)respondToChangedContents
1387 {
1388     NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1389     if ([view isKindOfClass:[WebHTMLView class]]) {
1390         [(WebHTMLView *)view _updateFontPanel];
1391     }
1392     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidChangeNotification object:[self webView]];
1393 }
1394
1395 - (void)respondToChangedSelection
1396 {
1397     NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1398     if ([view isKindOfClass:[WebHTMLView class]]) {
1399         [(WebHTMLView *)view _selectionChanged];
1400     }
1401     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidChangeSelectionNotification object:[self webView]];
1402 }
1403
1404 - (NSUndoManager *)undoManager
1405 {
1406     return [[self webView] undoManager];
1407 }
1408
1409 - (void)issueCutCommand
1410 {
1411     [[self webView] cut:nil];
1412 }
1413
1414 - (void)issueCopyCommand
1415 {
1416     [[self webView] copy:nil];
1417 }
1418
1419 - (void)issuePasteCommand
1420 {
1421     [[self webView] paste:nil];
1422 }
1423
1424 - (void)issuePasteAndMatchStyleCommand
1425 {
1426     [[self webView] pasteAsPlainText:nil];
1427 }
1428
1429 - (void)issueTransposeCommand
1430 {
1431     NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1432     if ([view isKindOfClass:[WebHTMLView class]]) {
1433         [(WebHTMLView *)view transpose:nil];
1434     }
1435 }
1436
1437 - (BOOL)canPaste
1438 {
1439     return [[self webView] _canPaste];
1440 }
1441
1442 - (void)setIsSelected:(BOOL)isSelected forView:(NSView *)view
1443 {
1444     if ([view respondsToSelector:@selector(webPlugInSetIsSelected:)]) {
1445         [view webPlugInSetIsSelected:isSelected];
1446     }
1447     else if ([view respondsToSelector:@selector(setIsSelected:)]) {
1448         [view setIsSelected:isSelected];
1449     }
1450 }
1451
1452 - (NSString *)overrideMediaType
1453 {
1454     return [[self webView] mediaStyle];
1455 }
1456
1457 - (BOOL)isEditable
1458 {
1459     return [[self webView] isEditable];
1460 }
1461
1462 - (BOOL)shouldChangeSelectedDOMRange:(DOMRange *)currentRange toDOMRange:(DOMRange *)proposedRange affinity:(NSSelectionAffinity)selectionAffinity stillSelecting:(BOOL)flag
1463 {
1464     return [[self webView] _shouldChangeSelectedDOMRange:currentRange toDOMRange:proposedRange affinity:selectionAffinity stillSelecting:flag];
1465 }
1466
1467 - (BOOL)shouldDeleteSelectedDOMRange:(DOMRange *)range
1468 {
1469     WebView *webView = [self webView];
1470     return [[webView _editingDelegateForwarder] webView:webView shouldDeleteDOMRange:range];
1471 }
1472
1473 - (BOOL)shouldBeginEditing:(DOMRange *)range
1474 {
1475     return [[self webView] _shouldBeginEditingInDOMRange:range];
1476 }
1477
1478 - (BOOL)shouldEndEditing:(DOMRange *)range
1479 {
1480     return [[self webView] _shouldEndEditingInDOMRange:range];
1481 }
1482
1483 - (void)didBeginEditing
1484 {
1485     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidBeginEditingNotification object:[_frame webView]];
1486 }
1487
1488 - (void)didEndEditing
1489 {
1490     [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidEndEditingNotification object:[_frame webView]];
1491 }
1492
1493 - (void)windowObjectCleared
1494 {
1495     WebView *wv = [self webView];
1496     [[wv _frameLoadDelegateForwarder] webView:wv windowScriptObjectAvailable:[self windowScriptObject]];
1497     if ([wv scriptDebugDelegate] || [WebScriptDebugServer listenerCount]) {
1498         [_frame _detachScriptDebugger]; // FIXME: remove this once <rdar://problem/4608404> is fixed
1499         [_frame _attachScriptDebugger];
1500     }
1501 }
1502
1503 - (int)spellCheckerDocumentTag
1504 {
1505     return [[self webView] spellCheckerDocumentTag];
1506 }
1507
1508 - (BOOL)isContinuousSpellCheckingEnabled
1509 {
1510     return [[self webView] isContinuousSpellCheckingEnabled];
1511 }
1512
1513 - (void)didFirstLayout
1514 {
1515     [_frame _didFirstLayout];
1516     WebView *wv = [self webView];
1517     [[wv _frameLoadDelegateForwarder] webView:wv didFirstLayoutInFrame:_frame];
1518 }
1519
1520 - (BOOL)_compareDashboardRegions:(NSDictionary *)regions
1521 {
1522     return [lastDashboardRegions isEqualToDictionary:regions];
1523 }
1524
1525 - (void)dashboardRegionsChanged:(NSMutableDictionary *)regions
1526 {
1527     WebView *wv = [self webView];
1528     id wd = [wv UIDelegate];
1529     
1530     [wv _addScrollerDashboardRegions:regions];
1531     
1532     if (![self _compareDashboardRegions:regions]) {
1533         if ([wd respondsToSelector:@selector(webView:dashboardRegionsChanged:)]) {
1534             [wd webView:wv dashboardRegionsChanged:regions];
1535             [lastDashboardRegions release];
1536             lastDashboardRegions = [regions retain];
1537         }
1538     }
1539 }
1540
1541 - (NSRect)customHighlightRect:(NSString*)type forLine:(NSRect)lineRect
1542 {
1543     ASSERT(_frame != nil);
1544     NSView *documentView = [[_frame frameView] documentView];
1545     if (![documentView isKindOfClass:[WebHTMLView class]])
1546         return NSZeroRect;
1547
1548     WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
1549     id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
1550     return [highlighter highlightRectForLine:lineRect];
1551 }
1552
1553 - (void)paintCustomHighlight:(NSString*)type forBox:(NSRect)boxRect onLine:(NSRect)lineRect behindText:(BOOL)text
1554                   entireLine:(BOOL)line
1555 {
1556     ASSERT(_frame != nil);
1557     NSView *documentView = [[_frame frameView] documentView];
1558     if (![documentView isKindOfClass:[WebHTMLView class]])
1559         return;
1560
1561     WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
1562     id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
1563     [highlighter paintHighlightForBox:boxRect onLine:lineRect behindText:text entireLine:line];
1564 }
1565
1566 - (NSString *)nameForUndoAction:(WebUndoAction)undoAction
1567 {
1568     switch (undoAction) {
1569         case WebUndoActionUnspecified: return nil;
1570         case WebUndoActionSetColor: return UI_STRING_KEY("Set Color", "Set Color (Undo action name)", "Undo action name");
1571         case WebUndoActionSetBackgroundColor: return UI_STRING_KEY("Set Background Color", "Set Background Color (Undo action name)", "Undo action name");
1572         case WebUndoActionTurnOffKerning: return UI_STRING_KEY("Turn Off Kerning", "Turn Off Kerning (Undo action name)", "Undo action name");
1573         case WebUndoActionTightenKerning: return UI_STRING_KEY("Tighten Kerning", "Tighten Kerning (Undo action name)", "Undo action name");
1574         case WebUndoActionLoosenKerning: return UI_STRING_KEY("Loosen Kerning", "Loosen Kerning (Undo action name)", "Undo action name");
1575         case WebUndoActionUseStandardKerning: return UI_STRING_KEY("Use Standard Kerning", "Use Standard Kerning (Undo action name)", "Undo action name");
1576         case WebUndoActionTurnOffLigatures: return UI_STRING_KEY("Turn Off Ligatures", "Turn Off Ligatures (Undo action name)", "Undo action name");
1577         case WebUndoActionUseStandardLigatures: return UI_STRING_KEY("Use Standard Ligatures", "Use Standard Ligatures (Undo action name)", "Undo action name");
1578         case WebUndoActionUseAllLigatures: return UI_STRING_KEY("Use All Ligatures", "Use All Ligatures (Undo action name)", "Undo action name");
1579         case WebUndoActionRaiseBaseline: return UI_STRING_KEY("Raise Baseline", "Raise Baseline (Undo action name)", "Undo action name");
1580         case WebUndoActionLowerBaseline: return UI_STRING_KEY("Lower Baseline", "Lower Baseline (Undo action name)", "Undo action name");
1581         case WebUndoActionSetTraditionalCharacterShape: return UI_STRING_KEY("Set Traditional Character Shape", "Set Traditional Character Shape (Undo action name)", "Undo action name");
1582         case WebUndoActionSetFont: return UI_STRING_KEY("Set Font", "Set Font (Undo action name)", "Undo action name");
1583         case WebUndoActionChangeAttributes: return UI_STRING_KEY("Change Attributes", "Change Attributes (Undo action name)", "Undo action name");
1584         case WebUndoActionAlignLeft: return UI_STRING_KEY("Align Left", "Align Left (Undo action name)", "Undo action name");
1585         case WebUndoActionAlignRight: return UI_STRING_KEY("Align Right", "Align Right (Undo action name)", "Undo action name");
1586         case WebUndoActionCenter: return UI_STRING_KEY("Center", "Center (Undo action name)", "Undo action name");
1587         case WebUndoActionJustify: return UI_STRING_KEY("Justify", "Justify (Undo action name)", "Undo action name");
1588         case WebUndoActionSetWritingDirection: return UI_STRING_KEY("Set Writing Direction", "Set Writing Direction (Undo action name)", "Undo action name");
1589         case WebUndoActionSubscript: return UI_STRING_KEY("Subscript", "Subscript (Undo action name)", "Undo action name");
1590         case WebUndoActionSuperscript: return UI_STRING_KEY("Superscript", "Superscript (Undo action name)", "Undo action name");
1591         case WebUndoActionUnderline: return UI_STRING_KEY("Underline", "Underline (Undo action name)", "Undo action name");
1592         case WebUndoActionOutline: return UI_STRING_KEY("Outline", "Outline (Undo action name)", "Undo action name");
1593         case WebUndoActionUnscript: return UI_STRING_KEY("Unscript", "Unscript (Undo action name)", "Undo action name");
1594         case WebUndoActionDrag: return UI_STRING_KEY("Drag", "Drag (Undo action name)", "Undo action name");
1595         case WebUndoActionCut: return UI_STRING_KEY("Cut", "Cut (Undo action name)", "Undo action name");
1596         case WebUndoActionPaste: return UI_STRING_KEY("Paste", "Paste (Undo action name)", "Undo action name");
1597         case WebUndoActionPasteFont: return UI_STRING_KEY("Paste Font", "Paste Font (Undo action name)", "Undo action name");
1598         case WebUndoActionPasteRuler: return UI_STRING_KEY("Paste Ruler", "Paste Ruler (Undo action name)", "Undo action name");
1599         case WebUndoActionTyping: return UI_STRING_KEY("Typing", "Typing (Undo action name)", "Undo action name");
1600         case WebUndoActionCreateLink: return UI_STRING_KEY("Create Link", "Create Link (Undo action name)", "Undo action name");
1601         case WebUndoActionUnlink: return UI_STRING_KEY("Unlink", "Unlink (Undo action name)", "Undo action name");
1602         case WebUndoActionInsertList: return UI_STRING_KEY("Insert List", "Insert List (Undo action name)", "Undo action name");
1603         case WebUndoActionFormatBlock: return UI_STRING_KEY("Formatting", "Format Block (Undo action name)", "Undo action name");
1604         case WebUndoActionIndent: return UI_STRING_KEY("Indent", "Indent (Undo action name)", "Undo action name");
1605         case WebUndoActionOutdent: return UI_STRING_KEY("Outdent", "Outdent (Undo action name)", "Undo action name");
1606     }
1607     return nil;
1608 }
1609
1610 - (WebCorePageBridge *)createModalDialogWithURL:(NSURL *)URL
1611 {
1612     ASSERT(_frame != nil);
1613
1614     NSMutableURLRequest *request = nil;
1615
1616     if (URL != nil && ![URL _web_isEmpty]) {
1617         request = [NSMutableURLRequest requestWithURL:URL];
1618         [request _web_setHTTPReferrer:[self referrer]];
1619     }
1620
1621     WebView *currentWebView = [self webView];
1622     id UIDelegate = [currentWebView UIDelegate];
1623
1624     WebView *newWebView = nil;
1625     if ([UIDelegate respondsToSelector:@selector(webView:createWebViewModalDialogWithRequest:)])
1626         newWebView = [UIDelegate webView:currentWebView createWebViewModalDialogWithRequest:request];
1627     else if ([UIDelegate respondsToSelector:@selector(webView:createWebViewWithRequest:)])
1628         newWebView = [UIDelegate webView:currentWebView createWebViewWithRequest:request];
1629     else
1630         newWebView = [[WebDefaultUIDelegate sharedUIDelegate] webView:currentWebView createWebViewWithRequest:request];
1631
1632     return [newWebView _pageBridge];
1633 }
1634
1635 - (BOOL)canRunModal
1636 {
1637     WebView *webView = [self webView];
1638     id UIDelegate = [webView UIDelegate];
1639     return [UIDelegate respondsToSelector:@selector(webViewRunModal:)];
1640 }
1641
1642 - (BOOL)canRunModalNow
1643 {
1644     return [self canRunModal] && ![WebLoader inConnectionCallback];
1645 }
1646
1647 - (void)runModal
1648 {
1649     if (![self canRunModal])
1650         return;
1651
1652     WebView *webView = [self webView];
1653     if ([webView defersCallbacks]) {
1654         LOG_ERROR("tried to run modal in a view when it was deferring callbacks -- should never happen");
1655         return;
1656     }
1657
1658     // Defer callbacks in all the other views in this group, so we don't try to run JavaScript
1659     // in a way that could interact with this view.
1660     NSMutableArray *deferredWebViews = [NSMutableArray array];
1661     NSString *namespace = [webView groupName];
1662     if (namespace) {
1663         NSEnumerator *enumerator = [WebCoreFrameNamespaces framesInNamespace:namespace];
1664         WebView *otherWebView;
1665         while ((otherWebView = [[enumerator nextObject] webView]) != nil) {
1666             if (otherWebView != webView && ![otherWebView defersCallbacks]) {
1667                 [otherWebView setDefersCallbacks:YES];
1668                 [deferredWebViews addObject:otherWebView];
1669             }
1670         }
1671     }
1672
1673     // Go run the modal event loop.
1674     [[webView UIDelegate] webViewRunModal:webView];
1675
1676     // Restore the callbacks for any views that we deferred them for.
1677     unsigned count = [deferredWebViews count];
1678     unsigned i;
1679     for (i = 0; i < count; ++i) {
1680         WebView *otherWebView = [deferredWebViews objectAtIndex:i];
1681         [otherWebView setDefersCallbacks:NO];
1682     }
1683 }
1684
1685 - (void)handledOnloadEvents
1686 {
1687     [_frame _handledOnloadEvents];
1688 }
1689
1690 - (void)closeURL
1691 {
1692     [_frame _willCloseURL];
1693     [super closeURL];
1694 }
1695
1696 - (NSURLResponse*)mainResourceURLResponse
1697 {
1698     return [[_frame dataSource] response];
1699 }
1700
1701 - (NSString*)imageTitleForFilename:(NSString*)filename size:(NSSize)size
1702 {
1703     return [NSString stringWithFormat:UI_STRING("%@ %.0f×%.0f pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filename, size.width, size.height];
1704 }
1705
1706 - (void)notifyIconChanged:(NSURL*)iconURL
1707 {
1708     [[_frame _frameLoader] _notifyIconChanged:iconURL];
1709 }
1710
1711 - (NSURL*)originalRequestURL
1712 {
1713     return [[[[_frame _frameLoader] activeDataSource] initialRequest] URL];
1714 }
1715
1716 - (BOOL)isLoadTypeReload
1717 {
1718     return [_frame _loadType] == WebFrameLoadTypeReload;
1719 }
1720
1721
1722
1723 @end