2 * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #import "WebFrameBridge.h"
31 #import "WebBackForwardList.h"
32 #import "WebBaseNetscapePluginView.h"
33 #import "WebBasePluginPackage.h"
34 #import "WebDataSourceInternal.h"
35 #import "WebDefaultUIDelegate.h"
36 #import "WebEditingDelegate.h"
37 #import "WebEditorClient.h"
38 #import "WebFormDelegate.h"
39 #import "WebFrameInternal.h"
40 #import "WebFrameLoadDelegate.h"
41 #import "WebFrameViewInternal.h"
42 #import "WebHTMLRepresentationPrivate.h"
43 #import "WebHTMLViewInternal.h"
44 #import "WebHistoryItemPrivate.h"
45 #import "WebIconDatabase.h"
46 #import "WebIconDatabasePrivate.h"
47 #import "WebJavaPlugIn.h"
48 #import "WebJavaScriptTextInputPanel.h"
49 #import "WebKitErrorsPrivate.h"
50 #import "WebKitLogging.h"
51 #import "WebKitNSStringExtras.h"
52 #import "WebKitStatisticsPrivate.h"
53 #import "WebKitSystemBits.h"
54 #import "WebLocalizableStrings.h"
55 #import "WebNSObjectExtras.h"
56 #import "WebNSURLExtras.h"
57 #import "WebNSURLRequestExtras.h"
58 #import "WebNSViewExtras.h"
59 #import "WebNetscapePluginEmbeddedView.h"
60 #import "WebNetscapePluginPackage.h"
61 #import "WebNullPluginView.h"
62 #import "WebPageBridge.h"
64 #import "WebPluginController.h"
65 #import "WebPluginDatabase.h"
66 #import "WebPluginPackage.h"
67 #import "WebPluginViewFactoryPrivate.h"
68 #import "WebPreferencesPrivate.h"
69 #import "WebResourcePrivate.h"
70 #import "WebScriptDebugServerPrivate.h"
71 #import "WebUIDelegatePrivate.h"
72 #import "WebViewInternal.h"
73 #import <Foundation/NSURLConnection.h>
74 #import <Foundation/NSURLRequest.h>
75 #import <Foundation/NSURLResponse.h>
76 #import <JavaScriptCore/Assertions.h>
77 #import <JavaVM/jni.h>
78 #import <WebCore/DocumentLoader.h>
79 #import <WebCore/FormDataStream.h>
80 #import <WebCore/FrameLoader.h>
81 #import <WebCore/FrameLoaderClient.h>
82 #import <WebCore/FrameMac.h>
83 #import <WebCore/FrameTree.h>
84 #import <WebCore/Page.h>
85 #import <WebCore/ResourceLoader.h>
86 #import <WebCore/SubresourceLoader.h>
87 #import <WebCore/WebCoreFrameNamespaces.h>
88 #import <WebCore/WebCoreSettings.h>
89 #import <WebKitSystemInterface.h>
90 #import <wtf/RefPtr.h>
92 // For compatibility with old SPI.
93 @interface NSView (OldWebPlugin)
94 - (void)setIsSelected:(BOOL)f;
97 @interface NSView (AppKitSecretsWebBridgeKnowsAbout)
98 - (NSView *)_findLastViewInKeyViewLoop;
101 @interface NSView (JavaPluginSecrets)
102 - (jobject)pollForAppletInWindow:(NSWindow *)window;
105 using namespace WebCore;
107 NSString *WebPluginBaseURLKey = @"WebPluginBaseURL";
108 NSString *WebPluginAttributesKey = @"WebPluginAttributes";
109 NSString *WebPluginContainerKey = @"WebPluginContainer";
111 #define KeyboardUIModeDidChangeNotification @"com.apple.KeyboardUIModeDidChange"
112 #define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode")
113 #define UniversalAccessDomain CFSTR("com.apple.universalaccess")
115 @implementation WebFrameBridge
119 ASSERT([[self _frame]->page()->bridge() isKindOfClass:[WebPageBridge class]]);
120 return [(WebPageBridge *)[self _frame]->page()->bridge() webView];
123 - (void)finishInitializingWithFrameName:(NSString *)name view:(WebFrameView *)view
125 WebView *webView = [self webView];
127 _frame = [[WebFrame alloc] _initWithWebFrameView:view webView:webView coreFrame:m_frame];
130 [self _frame]->tree()->setName(name);
131 [self _frame]->setSettings([[webView _settings] settings]);
132 [self setTextSizeMultiplier:[webView textSizeMultiplier]];
135 - (id)initMainFrameWithPage:(WebPageBridge *)page frameName:(NSString *)name view:(WebFrameView *)view
137 // FIXME: Need to clear the WebView pointer in WebEditorClient when the WebView is deallocated.
138 self = [super initMainFrameWithPage:page withEditorClient:new WebEditorClient([page webView])];
139 [self finishInitializingWithFrameName:name view:view];
143 - (id)initSubframeWithOwnerElement:(WebCoreElement *)ownerElement frameName:(NSString *)name view:(WebFrameView *)view
145 RefPtr<WebEditorClient> editorClient = new WebEditorClient;
146 self = [super initSubframeWithOwnerElement:ownerElement withEditorClient:editorClient.get()];
147 // FIXME: Need to clear the WebView pointer in WebEditorClient when the WebView is deallocated.
148 editorClient->setWebView([self webView]);
149 [self finishInitializingWithFrameName:name view:view];
155 if (_keyboardUIModeAccessed) {
156 [[NSDistributedNotificationCenter defaultCenter]
157 removeObserver:self name:KeyboardUIModeDidChangeNotification object:nil];
158 [[NSNotificationCenter defaultCenter]
159 removeObserver:self name:WebPreferencesChangedNotification object:nil];
161 ASSERT(_frame == nil);
167 [lastDashboardRegions release];
180 - (WebPreferences *)_preferences
182 return [[self webView] preferences];
185 - (void)_retrieveKeyboardUIModeFromPreferences:(NSNotification *)notification
187 CFPreferencesAppSynchronize(UniversalAccessDomain);
189 Boolean keyExistsAndHasValidFormat;
190 int mode = CFPreferencesGetAppIntegerValue(AppleKeyboardUIMode, UniversalAccessDomain, &keyExistsAndHasValidFormat);
192 // The keyboard access mode is reported by two bits:
193 // Bit 0 is set if feature is on
194 // Bit 1 is set if full keyboard access works for any control, not just text boxes and lists
195 // We require both bits to be on.
196 // I do not know that we would ever get one bit on and the other off since
197 // checking the checkbox in system preferences which is marked as "Turn on full keyboard access"
198 // turns on both bits.
199 _keyboardUIMode = (mode & 0x2) ? WebCoreKeyboardAccessFull : WebCoreKeyboardAccessDefault;
201 // check for tabbing to links
202 if ([[self _preferences] tabsToLinks])
203 _keyboardUIMode = (WebCoreKeyboardUIMode)(_keyboardUIMode | WebCoreKeyboardAccessTabsToLinks);
206 - (WebCoreKeyboardUIMode)keyboardUIMode
208 if (!_keyboardUIModeAccessed) {
209 _keyboardUIModeAccessed = YES;
210 [self _retrieveKeyboardUIModeFromPreferences:nil];
212 [[NSDistributedNotificationCenter defaultCenter]
213 addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:)
214 name:KeyboardUIModeDidChangeNotification object:nil];
216 [[NSNotificationCenter defaultCenter]
217 addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:)
218 name:WebPreferencesChangedNotification object:nil];
220 return _keyboardUIMode;
223 - (WebFrame *)webFrame
228 - (WebCoreFrameBridge *)mainFrame
230 ASSERT(_frame != nil);
231 return [[[self webView] mainFrame] _bridge];
234 - (NSView *)documentView
236 ASSERT(_frame != nil);
237 return [[_frame frameView] documentView];
240 - (WebCorePageBridge *)createWindowWithURL:(NSURL *)URL
242 ASSERT(_frame != nil);
244 NSMutableURLRequest *request = nil;
245 if (URL != nil && ![URL _web_isEmpty]) {
246 request = [NSMutableURLRequest requestWithURL:URL];
247 [request _web_setHTTPReferrer:m_frame->referrer()];
250 WebView *currentWebView = [self webView];
251 id wd = [currentWebView UIDelegate];
253 if ([wd respondsToSelector:@selector(webView:createWebViewWithRequest:)])
254 newWebView = [wd webView:currentWebView createWebViewWithRequest:request];
256 newWebView = [[WebDefaultUIDelegate sharedUIDelegate] webView:currentWebView createWebViewWithRequest:request];
257 return [newWebView _pageBridge];
262 WebView *wv = [self webView];
263 [[wv _UIDelegateForwarder] webViewShow:wv];
266 - (BOOL)areToolbarsVisible
268 ASSERT(_frame != nil);
269 WebView *wv = [self webView];
270 id wd = [wv UIDelegate];
271 if ([wd respondsToSelector:@selector(webViewAreToolbarsVisible:)])
272 return [wd webViewAreToolbarsVisible:wv];
273 return [[WebDefaultUIDelegate sharedUIDelegate] webViewAreToolbarsVisible:wv];
276 - (void)setToolbarsVisible:(BOOL)visible
278 ASSERT(_frame != nil);
279 WebView *wv = [self webView];
280 [[wv _UIDelegateForwarder] webView:wv setToolbarsVisible:visible];
283 - (void)setScrollbarsVisible:(BOOL)visible
285 ASSERT(_frame != nil);
286 [[_frame frameView] setAllowsScrolling:visible];
289 - (BOOL)isStatusbarVisible
291 ASSERT(_frame != nil);
292 WebView *wv = [self webView];
293 id wd = [wv UIDelegate];
294 if ([wd respondsToSelector:@selector(webViewIsStatusBarVisible:)])
295 return [wd webViewIsStatusBarVisible:wv];
296 return [[WebDefaultUIDelegate sharedUIDelegate] webViewIsStatusBarVisible:wv];
299 - (void)setStatusbarVisible:(BOOL)visible
301 ASSERT(_frame != nil);
302 WebView *wv = [self webView];
303 [[wv _UIDelegateForwarder] webView:wv setStatusBarVisible:visible];
306 - (void)setWindowIsResizable:(BOOL)resizable
308 ASSERT(_frame != nil);
309 WebView *webView = [self webView];
310 [[webView _UIDelegateForwarder] webView:webView setResizable:resizable];
313 - (NSResponder *)firstResponder
315 ASSERT(_frame != nil);
316 WebView *webView = [self webView];
317 return [[webView _UIDelegateForwarder] webViewFirstResponder:webView];
320 - (void)makeFirstResponder:(NSResponder *)view
322 ASSERT(_frame != nil);
323 WebView *webView = [self webView];
324 [webView _pushPerformingProgrammaticFocus];
325 [[webView _UIDelegateForwarder] webView:webView makeFirstResponder:view];
326 [webView _popPerformingProgrammaticFocus];
329 - (void)willMakeFirstResponderForNodeFocus
331 ASSERT([[[_frame frameView] documentView] isKindOfClass:[WebHTMLView class]]);
332 [(WebHTMLView *)[[_frame frameView] documentView] _willMakeFirstResponderForNodeFocus];
335 - (BOOL)textViewWasFirstResponderAtMouseDownTime:(NSTextView *)textView;
337 ASSERT(_frame != nil);
338 NSView *documentView = [[_frame frameView] documentView];
339 if (![documentView isKindOfClass:[WebHTMLView class]])
341 WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
342 return [webHTMLView _textViewWasFirstResponderAtMouseDownTime:textView];
345 - (void)closeWindowSoon
347 WebView *parentWebView = [self webView];
349 // We need to remove the parent WebView from WebViewSets here, before it actually
350 // closes, to make sure that JavaScript code that executes before it closes
351 // can't find it. Otherwise, window.open will select a closed WebView instead of
352 // opening a new one <rdar://problem/3572585>.
354 // We also need to stop the load to prevent further parsing or JavaScript execution
355 // after the window has torn down <rdar://problem/4161660>.
357 // FIXME: This code assumes that the UI delegate will respond to a webViewClose
358 // message by actually closing the WebView. Safari guarantees this behavior, but other apps might not.
359 // This approach is an inherent limitation of not making a close execute immediately
360 // after a call to window.close.
362 [parentWebView setGroupName:nil];
363 [parentWebView stopLoading:self];
364 [parentWebView performSelector:@selector(_closeWindow) withObject:nil afterDelay:0.0];
369 ASSERT(_frame != nil);
370 return [[_frame frameView] window];
373 - (void)runJavaScriptAlertPanelWithMessage:(NSString *)message
375 WebView *wv = [self webView];
376 id wd = [wv UIDelegate];
377 // Check whether delegate implements new version, then whether delegate implements old version. If neither,
378 // fall back to shared delegate's implementation of new version.
379 if ([wd respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:)])
380 [wd webView:wv runJavaScriptAlertPanelWithMessage:message initiatedByFrame:_frame];
381 else if ([wd respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:)])
382 [wd webView:wv runJavaScriptAlertPanelWithMessage:message];
384 [[WebDefaultUIDelegate sharedUIDelegate] webView:wv runJavaScriptAlertPanelWithMessage:message initiatedByFrame:_frame];
387 - (BOOL)runJavaScriptConfirmPanelWithMessage:(NSString *)message
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:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:)])
394 return [wd webView:wv runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:_frame];
395 if ([wd respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:)])
396 return [wd webView:wv runJavaScriptConfirmPanelWithMessage:message];
397 return [[WebDefaultUIDelegate sharedUIDelegate] webView:wv runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:_frame];
400 - (BOOL)shouldInterruptJavaScript
402 WebView *wv = [self webView];
403 id wd = [wv UIDelegate];
404 if ([wd respondsToSelector:@selector(webViewShouldInterruptJavaScript:)])
405 return [wd webViewShouldInterruptJavaScript:wv];
409 - (BOOL)canRunBeforeUnloadConfirmPanel
411 WebView *wv = [self webView];
412 id wd = [wv UIDelegate];
413 return [wd respondsToSelector:@selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:)];
416 - (BOOL)runBeforeUnloadConfirmPanelWithMessage:(NSString *)message
418 WebView *wv = [self webView];
419 id wd = [wv UIDelegate];
420 if ([wd respondsToSelector:@selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:)])
421 return [wd webView:wv runBeforeUnloadConfirmPanelWithMessage:message initiatedByFrame:_frame];
425 - (BOOL)runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText returningText:(NSString **)result
427 WebView *wv = [self webView];
428 id wd = [wv UIDelegate];
429 // Check whether delegate implements new version, then whether delegate implements old version. If neither,
430 // fall back to shared delegate's implementation of new version.
431 if ([wd respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:)])
432 *result = [wd webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:_frame];
433 else if ([wd respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:)])
434 *result = [wd webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText];
436 *result = [[WebDefaultUIDelegate sharedUIDelegate] webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:_frame];
437 return *result != nil;
440 - (void)addMessageToConsole:(NSDictionary *)message
442 WebView *wv = [self webView];
443 id wd = [wv UIDelegate];
444 if ([wd respondsToSelector:@selector(webView:addMessageToConsole:)])
445 [wd webView:wv addMessageToConsole:message];
448 - (void)runOpenPanelForFileButtonWithResultListener:(id<WebCoreOpenPanelResultListener>)resultListener
450 WebView *wv = [self webView];
451 [[wv _UIDelegateForwarder] webView:wv runOpenPanelForFileButtonWithResultListener:(id<WebOpenPanelResultListener>)resultListener];
454 - (WebDataSource *)dataSource
456 ASSERT(_frame != nil);
457 WebDataSource *dataSource = [_frame dataSource];
459 ASSERT(dataSource != nil);
464 - (void)setStatusText:(NSString *)status
466 ASSERT(_frame != nil);
467 WebView *wv = [self webView];
468 [[wv _UIDelegateForwarder] webView:wv setStatusText:status];
478 - (void)activateWindow
480 [[[self webView] _UIDelegateForwarder] webViewFocus:[self webView]];
483 - (void)deactivateWindow
485 [[[self webView] _UIDelegateForwarder] webViewUnfocus:[self webView]];
488 - (void)formControlIsBecomingFirstResponder:(NSView *)formControl
490 // When a form element becomes first responder, its enclosing WebHTMLView might need to
491 // change its focus-displaying state, but isn't otherwise notified.
492 [(WebHTMLView *)[[_frame frameView] documentView] _formControlIsBecomingFirstResponder:formControl];
495 - (void)formControlIsResigningFirstResponder:(NSView *)formControl
497 // When a form element resigns first responder, its enclosing WebHTMLView might need to
498 // change its focus-displaying state, but isn't otherwise notified.
499 [(WebHTMLView *)[[_frame frameView] documentView] _formControlIsResigningFirstResponder:formControl];
502 - (WebCoreFrameBridge *)createChildFrameNamed:(NSString *)frameName
504 referrer:(const String&)referrer
505 ownerElement:(WebCoreElement *)ownerElement
506 allowsScrolling:(BOOL)allowsScrolling
507 marginWidth:(int)width
508 marginHeight:(int)height
511 if (!m_frame->loader()->canLoad(URL, referrer, hideReferrer))
516 WebFrameView *childView = [[WebFrameView alloc] initWithFrame:NSMakeRect(0,0,0,0)];
517 [childView setAllowsScrolling:allowsScrolling];
518 WebFrameBridge *newBridge = [[WebFrameBridge alloc] initSubframeWithOwnerElement:ownerElement frameName:frameName view:childView];
519 [_frame _addChild:[newBridge webFrame]];
522 [childView _setMarginWidth:width];
523 [childView _setMarginHeight:height];
530 [_frame _loadURL:URL referrer:(hideReferrer ? String() : referrer) intoChild:[newBridge webFrame]];
535 - (void)saveDocumentState:(NSArray *)documentState
537 WebHistoryItem *item = [_frame _itemForSavingDocState];
538 LOG(Loading, "%@: saving form state from to 0x%x", [_frame name], item);
540 [item setDocumentState:documentState];
541 // You might think we could save the scroll state here too, but unfortunately this
542 // often gets called after WebFrame::_transitionToCommitted has restored the scroll
543 // position of the next document.
546 - (NSArray *)documentState
548 LOG(Loading, "%@: restoring form state from item 0x%x", [_frame name], [_frame _itemForRestoringDocState]);
549 return [[_frame _itemForRestoringDocState] documentState];
552 - (NSString *)userAgentForURL:(NSURL *)URL
554 return [[self webView] userAgentForURL:URL];
557 - (BOOL)inNextKeyViewOutsideWebFrameViews
559 return _inNextKeyViewOutsideWebFrameViews;
562 - (NSView *)_nextKeyViewOutsideWebFrameViewsWithValidityCheck:(BOOL)mustBeValid
564 // We can get here in unusual situations such as the one listed in 4451831, so we
565 // return nil to avoid an infinite recursion.
566 if (_inNextKeyViewOutsideWebFrameViews)
569 _inNextKeyViewOutsideWebFrameViews = YES;
570 WebView *webView = [self webView];
571 // Do not ask webView for its next key view, but rather, ask it for
572 // the next key view of the last view in its key view loop.
573 // Doing so gives us the correct answer as calculated by AppKit,
574 // and makes HTML views behave like other views.
575 NSView *lastViewInLoop = [webView _findLastViewInKeyViewLoop];
576 NSView *nextKeyView = mustBeValid ? [lastViewInLoop nextValidKeyView] : [lastViewInLoop nextKeyView];
577 _inNextKeyViewOutsideWebFrameViews = NO;
581 - (NSView *)nextKeyViewOutsideWebFrameViews
583 return [self _nextKeyViewOutsideWebFrameViewsWithValidityCheck:NO];
586 - (NSView *)nextValidKeyViewOutsideWebFrameViews
588 return [self _nextKeyViewOutsideWebFrameViewsWithValidityCheck:YES];
591 - (NSView *)previousKeyViewOutsideWebFrameViews
593 return [[self webView] previousKeyView];
596 - (void)setNeedsReapplyStyles
598 NSView <WebDocumentView> *view = [[_frame frameView] documentView];
599 if ([view isKindOfClass:[WebHTMLView class]]) {
600 [(WebHTMLView *)view setNeedsToApplyStyles:YES];
601 [view setNeedsLayout:YES];
602 [view setNeedsDisplay:YES];
606 - (NSView *)pluginViewWithPackage:(WebPluginPackage *)pluginPackage
607 attributeNames:(NSArray *)attributeNames
608 attributeValues:(NSArray *)attributeValues
609 baseURL:(NSURL *)baseURL
610 DOMElement:(DOMElement *)element
611 loadManually:(BOOL)loadManually
613 WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
614 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
616 WebPluginController *pluginController = [docView _pluginController];
618 // Store attributes in a dictionary so they can be passed to WebPlugins.
619 NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
621 [pluginPackage load];
622 Class viewFactory = [pluginPackage viewFactory];
625 NSDictionary *arguments = nil;
627 if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
628 arguments = [NSDictionary dictionaryWithObjectsAndKeys:
629 baseURL, WebPlugInBaseURLKey,
630 attributes, WebPlugInAttributesKey,
631 pluginController, WebPlugInContainerKey,
632 [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
633 [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
634 element, WebPlugInContainingElementKey,
636 LOG(Plugins, "arguments:\n%@", arguments);
637 } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
638 arguments = [NSDictionary dictionaryWithObjectsAndKeys:
639 baseURL, WebPluginBaseURLKey,
640 attributes, WebPluginAttributesKey,
641 pluginController, WebPluginContainerKey,
642 element, WebPlugInContainingElementKey,
644 LOG(Plugins, "arguments:\n%@", arguments);
647 view = [WebPluginController plugInViewWithArguments:arguments fromPluginPackage:pluginPackage];
649 [attributes release];
653 - (NSString *)valueForKey:(NSString *)key keys:(NSArray *)keys values:(NSArray *)values
655 unsigned count = [keys count];
657 for (i = 0; i < count; i++)
658 if ([[keys objectAtIndex:i] _webkit_isCaseInsensitiveEqualToString:key])
659 return [values objectAtIndex:i];
663 - (NSView *)viewForPluginWithURL:(NSURL *)URL
664 attributeNames:(NSArray *)attributeNames
665 attributeValues:(NSArray *)attributeValues
666 MIMEType:(NSString *)MIMEType
667 DOMElement:(DOMElement *)element
668 loadManually:(BOOL)loadManually
671 if (!m_frame->loader()->canLoad(URL, m_frame->referrer(), hideReferrer))
674 ASSERT([attributeNames count] == [attributeValues count]);
676 WebBasePluginPackage *pluginPackage = nil;
680 WebView *wv = [self webView];
681 id wd = [wv UIDelegate];
683 if ([wd respondsToSelector:@selector(webView:plugInViewWithArguments:)]) {
684 NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
685 NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:
686 attributes, WebPlugInAttributesKey,
687 [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
688 URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
689 [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
690 element, WebPlugInContainingElementKey,
692 [attributes release];
693 view = [wd webView:wv plugInViewWithArguments:arguments];
698 if ([MIMEType length] != 0)
699 pluginPackage = [[self webView] _pluginForMIMEType:MIMEType];
703 NSString *extension = [[URL path] pathExtension];
704 if (!pluginPackage && [extension length] != 0) {
705 pluginPackage = [[self webView] _pluginForExtension:extension];
707 NSString *newMIMEType = [pluginPackage MIMETypeForExtension:extension];
708 if ([newMIMEType length] != 0)
709 MIMEType = newMIMEType;
713 NSURL *baseURL = [self baseURL];
715 if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
716 view = [self pluginViewWithPackage:(WebPluginPackage *)pluginPackage
717 attributeNames:attributeNames
718 attributeValues:attributeValues
721 loadManually:loadManually];
722 } else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
723 WebNetscapePluginEmbeddedView *embeddedView = [[[WebNetscapePluginEmbeddedView alloc] initWithFrame:NSZeroRect
724 plugin:(WebNetscapePluginPackage *)pluginPackage
728 attributeKeys:attributeNames
729 attributeValues:attributeValues
730 loadManually:loadManually
731 DOMElement:element] autorelease];
733 [_frame _addPlugInView:embeddedView];
735 ASSERT_NOT_REACHED();
737 errorCode = WebKitErrorCannotFindPlugIn;
739 if (!errorCode && !view)
740 errorCode = WebKitErrorCannotLoadPlugIn;
743 NSString *pluginPage = [self valueForKey:@"pluginspage" keys:attributeNames values:attributeValues];
744 NSURL *pluginPageURL = pluginPage != nil ? [self URLWithAttributeString:pluginPage] : nil;
745 NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
747 pluginPageURL:pluginPageURL
748 pluginName:[pluginPackage name]
750 WebNullPluginView *nullView = [[[WebNullPluginView alloc] initWithFrame:NSZeroRect error:error] autorelease];
751 [_frame _addPlugInView:nullView];
760 - (void)redirectDataToPlugin:(NSView *)pluginView
762 WebHTMLRepresentation *representation = (WebHTMLRepresentation *)[[_frame dataSource] representation];
764 if ([pluginView isKindOfClass:[WebNetscapePluginEmbeddedView class]])
765 [representation _redirectDataToManualLoader:(WebNetscapePluginEmbeddedView *)pluginView forPluginView:pluginView];
767 WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
768 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
770 WebPluginController *pluginController = [docView _pluginController];
771 [representation _redirectDataToManualLoader:pluginController forPluginView:pluginView];
775 - (NSView *)viewForJavaAppletWithFrame:(NSRect)theFrame
776 attributeNames:(NSArray *)attributeNames
777 attributeValues:(NSArray *)attributeValues
778 baseURL:(NSURL *)baseURL
779 DOMElement:(DOMElement *)element
781 NSString *MIMEType = @"application/x-java-applet";
782 WebBasePluginPackage *pluginPackage;
785 pluginPackage = [[self webView] _pluginForMIMEType:MIMEType];
788 if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
789 // For some reason, the Java plug-in requires that we pass the dimension of the plug-in as attributes.
790 NSMutableArray *names = [attributeNames mutableCopy];
791 NSMutableArray *values = [attributeValues mutableCopy];
792 if ([self valueForKey:@"width" keys:attributeNames values:attributeValues] == nil) {
793 [names addObject:@"width"];
794 [values addObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.width]];
796 if ([self valueForKey:@"height" keys:attributeNames values:attributeValues] == nil) {
797 [names addObject:@"height"];
798 [values addObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.height]];
800 view = [self pluginViewWithPackage:(WebPluginPackage *)pluginPackage
802 attributeValues:values
808 } else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
809 view = [[[WebNetscapePluginEmbeddedView alloc] initWithFrame:theFrame
810 plugin:(WebNetscapePluginPackage *)pluginPackage
814 attributeKeys:attributeNames
815 attributeValues:attributeValues
817 DOMElement:element] autorelease];
819 ASSERT_NOT_REACHED();
824 NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorJavaUnavailable
827 pluginName:[pluginPackage name]
829 view = [[[WebNullPluginView alloc] initWithFrame:theFrame error:error] autorelease];
839 static BOOL loggedObjectCacheSize = NO;
842 -(int)getObjectCacheSize
844 vm_size_t memSize = WebSystemMainMemory();
845 int cacheSize = [[self _preferences] _objectCacheSize];
848 // 2GB and greater will be 128mb. 1gb and greater will be 64mb.
849 // Otherwise just use 32mb.
850 if (memSize >= (unsigned)(2048 * 1024 * 1024))
852 else if (memSize >= 1024 * 1024 * 1024)
856 if (!loggedObjectCacheSize){
857 LOG(CacheSizes, "Object cache size set to %d bytes.", cacheSize * multiplier);
858 loggedObjectCacheSize = YES;
862 return cacheSize * multiplier;
865 - (ObjectElementType)determineObjectFromMIMEType:(NSString*)MIMEType URL:(NSURL*)URL
867 if ([MIMEType length] == 0) {
868 // Try to guess the MIME type based off the extension.
869 NSString *extension = [[URL path] pathExtension];
870 if ([extension length] > 0) {
871 MIMEType = WKGetMIMETypeForExtension(extension);
872 if ([MIMEType length] == 0 && [[self webView] _pluginForExtension:extension])
873 // If no MIME type is specified, use a plug-in if we have one that can handle the extension.
874 return ObjectElementPlugin;
878 if ([MIMEType length] == 0)
879 return ObjectElementFrame; // Go ahead and hope that we can display the content.
881 if ([[WebCoreFrameBridge supportedImageMIMETypes] containsObject:MIMEType])
882 return ObjectElementFrame;
884 if ([[self webView] _isMIMETypeRegisteredAsPlugin:MIMEType])
885 return ObjectElementPlugin;
887 if ([WebFrameView _viewClassForMIMEType:MIMEType])
888 return ObjectElementFrame;
890 return ObjectElementNone;
893 - (NSString *)MIMETypeForPath:(NSString *)path
896 NSString *extension = [path pathExtension];
897 NSString *type = WKGetMIMETypeForExtension(extension);
898 return [type length] == 0 ? (NSString *)@"application/octet-stream" : type;
901 - (void)allowDHTMLDrag:(BOOL *)flagDHTML UADrag:(BOOL *)flagUA
903 WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
904 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
905 unsigned int mask = [docView _delegateDragSourceActionMask];
906 *flagDHTML = (mask & WebDragSourceActionDHTML) != 0;
907 *flagUA = ((mask & WebDragSourceActionImage) || (mask & WebDragSourceActionLink) || (mask & WebDragSourceActionSelection));
910 - (BOOL)startDraggingImage:(NSImage *)dragImage at:(NSPoint)dragLoc operation:(NSDragOperation)op
911 event:(NSEvent *)event sourceIsDHTML:(BOOL)flag DHTMLWroteData:(BOOL)dhtmlWroteData
913 WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
914 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
915 [docView _setInitiatedDrag:YES];
916 return [docView _startDraggingImage:dragImage at:dragLoc operation:op event:event
917 sourceIsDHTML:flag DHTMLWroteData:dhtmlWroteData];
920 - (BOOL)mayStartDragAtEventLocation:(NSPoint)location
922 WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
923 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
924 return [docView _mayStartDragAtEventLocation:location];
927 - (BOOL)selectWordBeforeMenuEvent
929 return [[self webView] _selectWordBeforeMenuEvent];
934 return [[[self webView] backForwardList] backListCount] + 1;
937 - (BOOL)canGoBackOrForward:(int)distance
941 if (distance > 0 && distance <= [[[self webView] backForwardList] forwardListCount])
943 if (distance < 0 && -distance <= [[[self webView] backForwardList] backListCount])
948 - (void)goBackOrForward:(int)distance
952 WebView *webView = [self webView];
953 WebBackForwardList *list = [webView backForwardList];
954 WebHistoryItem *item = [list itemAtIndex:distance];
957 int forwardListCount = [list forwardListCount];
958 if (forwardListCount > 0) {
959 item = [list itemAtIndex:forwardListCount];
962 int backListCount = [list forwardListCount];
963 if (backListCount > 0) {
964 item = [list itemAtIndex:-backListCount];
969 [webView goToBackForwardItem:item];
973 - (NSURL*)historyURL:(int)distance
975 WebView *webView = [self webView];
976 WebBackForwardList *list = [webView backForwardList];
977 WebHistoryItem *item = [list itemAtIndex:distance];
980 int forwardListCount = [list forwardListCount];
981 if (forwardListCount > 0)
982 item = [list itemAtIndex:forwardListCount];
984 int backListCount = [list forwardListCount];
985 if (backListCount > 0)
986 item = [list itemAtIndex:-backListCount];
995 static id <WebFormDelegate> formDelegate(WebFrameBridge *self)
997 ASSERT(self->_frame != nil);
998 return [[self->_frame webView] _formDelegate];
1001 #define FormDelegateLog(ctrl) LOG(FormDelegate, "control=%@", ctrl)
1003 - (void)textFieldDidBeginEditing:(DOMHTMLInputElement *)element
1005 FormDelegateLog(element);
1006 [formDelegate(self) textFieldDidBeginEditing:element inFrame:_frame];
1009 - (void)textFieldDidEndEditing:(DOMHTMLInputElement *)element
1011 FormDelegateLog(element);
1012 [formDelegate(self) textFieldDidEndEditing:element inFrame:_frame];
1015 - (void)textDidChangeInTextField:(DOMHTMLInputElement *)element
1017 FormDelegateLog(element);
1018 [formDelegate(self) textDidChangeInTextField:(DOMHTMLInputElement *)element inFrame:_frame];
1021 - (void)textDidChangeInTextArea:(DOMHTMLTextAreaElement *)element
1023 FormDelegateLog(element);
1024 [formDelegate(self) textDidChangeInTextArea:element inFrame:_frame];
1027 - (BOOL)textField:(DOMHTMLInputElement *)element doCommandBySelector:(SEL)commandSelector
1029 FormDelegateLog(element);
1030 return [formDelegate(self) textField:element doCommandBySelector:commandSelector inFrame:_frame];
1033 - (BOOL)textField:(DOMHTMLInputElement *)element shouldHandleEvent:(NSEvent *)event
1035 FormDelegateLog(element);
1036 return [formDelegate(self) textField:element shouldHandleEvent:event inFrame:_frame];
1039 - (void)setHasBorder:(BOOL)hasBorder
1041 [[_frame frameView] _setHasBorder:hasBorder];
1046 id wd = [[self webView] UIDelegate];
1047 if ([wd respondsToSelector:@selector(webView:printFrameView:)])
1048 [wd webView:[self webView] printFrameView:[_frame frameView]];
1050 [[WebDefaultUIDelegate sharedUIDelegate] webView:[self webView] printFrameView:[_frame frameView]];
1053 - (jobject)getAppletInView:(NSView *)view
1055 if ([view respondsToSelector:@selector(webPlugInGetApplet)])
1056 return [view webPlugInGetApplet];
1057 return [self pollForAppletInView:view];
1060 // NOTE: pollForAppletInView: will block until the block is ready to use, or
1061 // until a timeout is exceeded. It will return nil if the timeout is
1063 // Deprecated, use getAppletInView:.
1064 - (jobject)pollForAppletInView:(NSView *)view
1066 if ([view respondsToSelector:@selector(pollForAppletInWindow:)])
1067 // The Java VM needs the containing window of the view to
1068 // initialize. The view may not yet be in the window's view
1069 // hierarchy, so we have to pass the window when requesting
1071 return [view pollForAppletInWindow:[[self webView] window]];
1075 - (void)respondToChangedContents
1077 NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1078 if ([view isKindOfClass:[WebHTMLView class]])
1079 [(WebHTMLView *)view _updateFontPanel];
1080 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidChangeNotification object:[self webView]];
1083 - (void)respondToChangedSelection
1085 NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1086 if ([view isKindOfClass:[WebHTMLView class]])
1087 [(WebHTMLView *)view _selectionChanged];
1088 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidChangeSelectionNotification object:[self webView]];
1091 - (NSUndoManager *)undoManager
1093 return [[self webView] undoManager];
1096 - (void)issueCutCommand
1098 NSView* documentView = [[_frame frameView] documentView];
1099 if ([documentView isKindOfClass:[WebHTMLView class]])
1100 [(WebHTMLView*)documentView cut:nil];
1103 - (void)issueCopyCommand
1105 NSView* documentView = [[_frame frameView] documentView];
1106 if ([documentView isKindOfClass:[WebHTMLView class]])
1107 [(WebHTMLView*)documentView copy:nil];
1110 - (void)issuePasteCommand
1112 NSView* documentView = [[_frame frameView] documentView];
1113 if ([documentView isKindOfClass:[WebHTMLView class]])
1114 [(WebHTMLView*)documentView paste:nil];
1117 - (void)issuePasteAndMatchStyleCommand
1119 NSView <WebDocumentView> *documentView = [[_frame frameView] documentView];
1120 if ([documentView isKindOfClass:[WebHTMLView class]])
1121 [(WebHTMLView*)documentView pasteAsPlainText:nil];
1124 - (void)issueTransposeCommand
1126 NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1127 if ([view isKindOfClass:[WebHTMLView class]])
1128 [(WebHTMLView *)view transpose:nil];
1131 - (void)setIsSelected:(BOOL)isSelected forView:(NSView *)view
1133 if ([view respondsToSelector:@selector(webPlugInSetIsSelected:)])
1134 [view webPlugInSetIsSelected:isSelected];
1135 else if ([view respondsToSelector:@selector(setIsSelected:)])
1136 [view setIsSelected:isSelected];
1139 - (NSString *)overrideMediaType
1141 return [[self webView] mediaStyle];
1146 return [[self webView] isEditable];
1149 - (BOOL)shouldChangeSelectedDOMRange:(DOMRange *)currentRange toDOMRange:(DOMRange *)proposedRange affinity:(WebCore::EAffinity)selectionAffinity stillSelecting:(BOOL)flag
1151 return [[self webView] _shouldChangeSelectedDOMRange:currentRange toDOMRange:proposedRange affinity:kit(selectionAffinity) stillSelecting:flag];
1154 - (BOOL)shouldDeleteSelectedDOMRange:(DOMRange *)range
1156 WebView *webView = [self webView];
1157 return [[webView _editingDelegateForwarder] webView:webView shouldDeleteDOMRange:range];
1160 - (BOOL)shouldBeginEditing:(DOMRange *)range
1162 return [[self webView] _shouldBeginEditingInDOMRange:range];
1165 - (BOOL)shouldEndEditing:(DOMRange *)range
1167 return [[self webView] _shouldEndEditingInDOMRange:range];
1170 - (void)didBeginEditing
1172 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidBeginEditingNotification object:[_frame webView]];
1175 - (void)didEndEditing
1177 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidEndEditingNotification object:[_frame webView]];
1180 - (void)windowObjectCleared
1182 WebView *wv = [self webView];
1183 [[wv _frameLoadDelegateForwarder] webView:wv windowScriptObjectAvailable:m_frame->windowScriptObject()];
1184 if ([wv scriptDebugDelegate] || [WebScriptDebugServer listenerCount]) {
1185 [_frame _detachScriptDebugger]; // FIXME: remove this once <rdar://problem/4608404> is fixed
1186 [_frame _attachScriptDebugger];
1190 - (BOOL)_compareDashboardRegions:(NSDictionary *)regions
1192 return [lastDashboardRegions isEqualToDictionary:regions];
1195 - (void)dashboardRegionsChanged:(NSMutableDictionary *)regions
1197 WebView *wv = [self webView];
1198 id wd = [wv UIDelegate];
1200 [wv _addScrollerDashboardRegions:regions];
1202 if (![self _compareDashboardRegions:regions]) {
1203 if ([wd respondsToSelector:@selector(webView:dashboardRegionsChanged:)]) {
1204 [wd webView:wv dashboardRegionsChanged:regions];
1205 [lastDashboardRegions release];
1206 lastDashboardRegions = [regions retain];
1211 - (void)willPopupMenu:(NSMenu *)menu
1213 WebView *wv = [self webView];
1214 id wd = [wv UIDelegate];
1216 if ([wd respondsToSelector:@selector(webView:willPopupMenu:)])
1217 [wd webView:wv willPopupMenu:menu];
1220 - (NSRect)customHighlightRect:(NSString*)type forLine:(NSRect)lineRect
1222 ASSERT(_frame != nil);
1223 NSView *documentView = [[_frame frameView] documentView];
1224 if (![documentView isKindOfClass:[WebHTMLView class]])
1227 WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
1228 id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
1229 return [highlighter highlightRectForLine:lineRect];
1232 - (void)paintCustomHighlight:(NSString*)type forBox:(NSRect)boxRect onLine:(NSRect)lineRect behindText:(BOOL)text
1233 entireLine:(BOOL)line
1235 ASSERT(_frame != nil);
1236 NSView *documentView = [[_frame frameView] documentView];
1237 if (![documentView isKindOfClass:[WebHTMLView class]])
1240 WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
1241 id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
1242 [highlighter paintHighlightForBox:boxRect onLine:lineRect behindText:text entireLine:line];
1245 - (NSString *)nameForUndoAction:(WebUndoAction)undoAction
1247 switch (undoAction) {
1248 case WebUndoActionUnspecified: return nil;
1249 case WebUndoActionSetColor: return UI_STRING_KEY("Set Color", "Set Color (Undo action name)", "Undo action name");
1250 case WebUndoActionSetBackgroundColor: return UI_STRING_KEY("Set Background Color", "Set Background Color (Undo action name)", "Undo action name");
1251 case WebUndoActionTurnOffKerning: return UI_STRING_KEY("Turn Off Kerning", "Turn Off Kerning (Undo action name)", "Undo action name");
1252 case WebUndoActionTightenKerning: return UI_STRING_KEY("Tighten Kerning", "Tighten Kerning (Undo action name)", "Undo action name");
1253 case WebUndoActionLoosenKerning: return UI_STRING_KEY("Loosen Kerning", "Loosen Kerning (Undo action name)", "Undo action name");
1254 case WebUndoActionUseStandardKerning: return UI_STRING_KEY("Use Standard Kerning", "Use Standard Kerning (Undo action name)", "Undo action name");
1255 case WebUndoActionTurnOffLigatures: return UI_STRING_KEY("Turn Off Ligatures", "Turn Off Ligatures (Undo action name)", "Undo action name");
1256 case WebUndoActionUseStandardLigatures: return UI_STRING_KEY("Use Standard Ligatures", "Use Standard Ligatures (Undo action name)", "Undo action name");
1257 case WebUndoActionUseAllLigatures: return UI_STRING_KEY("Use All Ligatures", "Use All Ligatures (Undo action name)", "Undo action name");
1258 case WebUndoActionRaiseBaseline: return UI_STRING_KEY("Raise Baseline", "Raise Baseline (Undo action name)", "Undo action name");
1259 case WebUndoActionLowerBaseline: return UI_STRING_KEY("Lower Baseline", "Lower Baseline (Undo action name)", "Undo action name");
1260 case WebUndoActionSetTraditionalCharacterShape: return UI_STRING_KEY("Set Traditional Character Shape", "Set Traditional Character Shape (Undo action name)", "Undo action name");
1261 case WebUndoActionSetFont: return UI_STRING_KEY("Set Font", "Set Font (Undo action name)", "Undo action name");
1262 case WebUndoActionChangeAttributes: return UI_STRING_KEY("Change Attributes", "Change Attributes (Undo action name)", "Undo action name");
1263 case WebUndoActionAlignLeft: return UI_STRING_KEY("Align Left", "Align Left (Undo action name)", "Undo action name");
1264 case WebUndoActionAlignRight: return UI_STRING_KEY("Align Right", "Align Right (Undo action name)", "Undo action name");
1265 case WebUndoActionCenter: return UI_STRING_KEY("Center", "Center (Undo action name)", "Undo action name");
1266 case WebUndoActionJustify: return UI_STRING_KEY("Justify", "Justify (Undo action name)", "Undo action name");
1267 case WebUndoActionSetWritingDirection: return UI_STRING_KEY("Set Writing Direction", "Set Writing Direction (Undo action name)", "Undo action name");
1268 case WebUndoActionSubscript: return UI_STRING_KEY("Subscript", "Subscript (Undo action name)", "Undo action name");
1269 case WebUndoActionSuperscript: return UI_STRING_KEY("Superscript", "Superscript (Undo action name)", "Undo action name");
1270 case WebUndoActionUnderline: return UI_STRING_KEY("Underline", "Underline (Undo action name)", "Undo action name");
1271 case WebUndoActionOutline: return UI_STRING_KEY("Outline", "Outline (Undo action name)", "Undo action name");
1272 case WebUndoActionUnscript: return UI_STRING_KEY("Unscript", "Unscript (Undo action name)", "Undo action name");
1273 case WebUndoActionDrag: return UI_STRING_KEY("Drag", "Drag (Undo action name)", "Undo action name");
1274 case WebUndoActionCut: return UI_STRING_KEY("Cut", "Cut (Undo action name)", "Undo action name");
1275 case WebUndoActionPaste: return UI_STRING_KEY("Paste", "Paste (Undo action name)", "Undo action name");
1276 case WebUndoActionPasteFont: return UI_STRING_KEY("Paste Font", "Paste Font (Undo action name)", "Undo action name");
1277 case WebUndoActionPasteRuler: return UI_STRING_KEY("Paste Ruler", "Paste Ruler (Undo action name)", "Undo action name");
1278 case WebUndoActionTyping: return UI_STRING_KEY("Typing", "Typing (Undo action name)", "Undo action name");
1279 case WebUndoActionCreateLink: return UI_STRING_KEY("Create Link", "Create Link (Undo action name)", "Undo action name");
1280 case WebUndoActionUnlink: return UI_STRING_KEY("Unlink", "Unlink (Undo action name)", "Undo action name");
1281 case WebUndoActionInsertList: return UI_STRING_KEY("Insert List", "Insert List (Undo action name)", "Undo action name");
1282 case WebUndoActionFormatBlock: return UI_STRING_KEY("Formatting", "Format Block (Undo action name)", "Undo action name");
1283 case WebUndoActionIndent: return UI_STRING_KEY("Indent", "Indent (Undo action name)", "Undo action name");
1284 case WebUndoActionOutdent: return UI_STRING_KEY("Outdent", "Outdent (Undo action name)", "Undo action name");
1289 - (NSString*)imageTitleForFilename:(NSString*)filename size:(NSSize)size
1291 return [NSString stringWithFormat:UI_STRING("%@ %.0f×%.0f pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filename, size.width, size.height];