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/FrameLoader.h>
80 #import <WebCore/FrameLoaderClient.h>
81 #import <WebCore/FrameMac.h>
82 #import <WebCore/FrameTree.h>
83 #import <WebCore/Page.h>
84 #import <WebCore/ResourceLoader.h>
85 #import <WebCore/SubresourceLoader.h>
86 #import <WebCore/WebCoreFrameNamespaces.h>
87 #import <WebCore/WebCoreSettings.h>
88 #import <WebKitSystemInterface.h>
89 #import <wtf/RefPtr.h>
91 // For compatibility with old SPI.
92 @interface NSView (OldWebPlugin)
93 - (void)setIsSelected:(BOOL)f;
96 @interface NSView (AppKitSecretsWebBridgeKnowsAbout)
97 - (NSView *)_findLastViewInKeyViewLoop;
100 @interface NSView (JavaPluginSecrets)
101 - (jobject)pollForAppletInWindow:(NSWindow *)window;
104 using namespace WebCore;
106 NSString *WebPluginBaseURLKey = @"WebPluginBaseURL";
107 NSString *WebPluginAttributesKey = @"WebPluginAttributes";
108 NSString *WebPluginContainerKey = @"WebPluginContainer";
110 #define KeyboardUIModeDidChangeNotification @"com.apple.KeyboardUIModeDidChange"
111 #define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode")
112 #define UniversalAccessDomain CFSTR("com.apple.universalaccess")
114 @implementation WebFrameBridge
118 ASSERT([[self _frame]->page()->bridge() isKindOfClass:[WebPageBridge class]]);
119 return [(WebPageBridge *)[self _frame]->page()->bridge() webView];
122 - (void)finishInitializingWithFrameName:(NSString *)name view:(WebFrameView *)view
124 WebView *webView = [self webView];
126 _frame = [[WebFrame alloc] _initWithWebFrameView:view webView:webView coreFrame:m_frame];
129 [self _frame]->tree()->setName(name);
130 [self _frame]->setSettings([[webView _settings] settings]);
131 [self setTextSizeMultiplier:[webView textSizeMultiplier]];
134 - (id)initMainFrameWithPage:(WebPageBridge *)page frameName:(NSString *)name view:(WebFrameView *)view
136 // FIXME: Need to clear the WebView pointer in WebEditorClient when the WebView is deallocated.
137 self = [super initMainFrameWithPage:page withEditorClient:new WebEditorClient([page webView])];
138 [self finishInitializingWithFrameName:name view:view];
142 - (id)initSubframeWithOwnerElement:(WebCoreElement *)ownerElement frameName:(NSString *)name view:(WebFrameView *)view
144 RefPtr<WebEditorClient> editorClient = new WebEditorClient;
145 self = [super initSubframeWithOwnerElement:ownerElement withEditorClient:editorClient.get()];
146 // FIXME: Need to clear the WebView pointer in WebEditorClient when the WebView is deallocated.
147 editorClient->setWebView([self webView]);
148 [self finishInitializingWithFrameName:name view:view];
154 if (_keyboardUIModeAccessed) {
155 [[NSDistributedNotificationCenter defaultCenter]
156 removeObserver:self name:KeyboardUIModeDidChangeNotification object:nil];
157 [[NSNotificationCenter defaultCenter]
158 removeObserver:self name:WebPreferencesChangedNotification object:nil];
160 ASSERT(_frame == nil);
166 [lastDashboardRegions release];
179 - (WebPreferences *)_preferences
181 return [[self webView] preferences];
184 - (void)_retrieveKeyboardUIModeFromPreferences:(NSNotification *)notification
186 CFPreferencesAppSynchronize(UniversalAccessDomain);
188 Boolean keyExistsAndHasValidFormat;
189 int mode = CFPreferencesGetAppIntegerValue(AppleKeyboardUIMode, UniversalAccessDomain, &keyExistsAndHasValidFormat);
191 // The keyboard access mode is reported by two bits:
192 // Bit 0 is set if feature is on
193 // Bit 1 is set if full keyboard access works for any control, not just text boxes and lists
194 // We require both bits to be on.
195 // I do not know that we would ever get one bit on and the other off since
196 // checking the checkbox in system preferences which is marked as "Turn on full keyboard access"
197 // turns on both bits.
198 _keyboardUIMode = (mode & 0x2) ? WebCoreKeyboardAccessFull : WebCoreKeyboardAccessDefault;
200 // check for tabbing to links
201 if ([[self _preferences] tabsToLinks])
202 _keyboardUIMode = (WebCoreKeyboardUIMode)(_keyboardUIMode | WebCoreKeyboardAccessTabsToLinks);
205 - (WebCoreKeyboardUIMode)keyboardUIMode
207 if (!_keyboardUIModeAccessed) {
208 _keyboardUIModeAccessed = YES;
209 [self _retrieveKeyboardUIModeFromPreferences:nil];
211 [[NSDistributedNotificationCenter defaultCenter]
212 addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:)
213 name:KeyboardUIModeDidChangeNotification object:nil];
215 [[NSNotificationCenter defaultCenter]
216 addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:)
217 name:WebPreferencesChangedNotification object:nil];
219 return _keyboardUIMode;
222 - (WebFrame *)webFrame
227 - (WebCoreFrameBridge *)mainFrame
229 ASSERT(_frame != nil);
230 return [[[self webView] mainFrame] _bridge];
233 - (NSView *)documentView
235 ASSERT(_frame != nil);
236 return [[_frame frameView] documentView];
239 - (WebCorePageBridge *)createWindowWithURL:(NSURL *)URL
241 ASSERT(_frame != nil);
243 NSMutableURLRequest *request = nil;
244 if (URL != nil && ![URL _web_isEmpty]) {
245 request = [NSMutableURLRequest requestWithURL:URL];
246 [request _web_setHTTPReferrer:m_frame->referrer()];
249 WebView *currentWebView = [self webView];
250 id wd = [currentWebView UIDelegate];
252 if ([wd respondsToSelector:@selector(webView:createWebViewWithRequest:)])
253 newWebView = [wd webView:currentWebView createWebViewWithRequest:request];
255 newWebView = [[WebDefaultUIDelegate sharedUIDelegate] webView:currentWebView createWebViewWithRequest:request];
256 return [newWebView _pageBridge];
261 WebView *wv = [self webView];
262 [[wv _UIDelegateForwarder] webViewShow:wv];
265 - (BOOL)areToolbarsVisible
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];
275 - (void)setToolbarsVisible:(BOOL)visible
277 ASSERT(_frame != nil);
278 WebView *wv = [self webView];
279 [[wv _UIDelegateForwarder] webView:wv setToolbarsVisible:visible];
282 - (void)setScrollbarsVisible:(BOOL)visible
284 ASSERT(_frame != nil);
285 [[_frame frameView] setAllowsScrolling:visible];
288 - (BOOL)isStatusbarVisible
290 ASSERT(_frame != nil);
291 WebView *wv = [self webView];
292 id wd = [wv UIDelegate];
293 if ([wd respondsToSelector:@selector(webViewIsStatusBarVisible:)])
294 return [wd webViewIsStatusBarVisible:wv];
295 return [[WebDefaultUIDelegate sharedUIDelegate] webViewIsStatusBarVisible:wv];
298 - (void)setStatusbarVisible:(BOOL)visible
300 ASSERT(_frame != nil);
301 WebView *wv = [self webView];
302 [[wv _UIDelegateForwarder] webView:wv setStatusBarVisible:visible];
305 - (void)setWindowIsResizable:(BOOL)resizable
307 ASSERT(_frame != nil);
308 WebView *webView = [self webView];
309 [[webView _UIDelegateForwarder] webView:webView setResizable:resizable];
312 - (NSResponder *)firstResponder
314 ASSERT(_frame != nil);
315 WebView *webView = [self webView];
316 return [[webView _UIDelegateForwarder] webViewFirstResponder:webView];
319 - (void)makeFirstResponder:(NSResponder *)view
321 ASSERT(_frame != nil);
322 WebView *webView = [self webView];
323 [webView _pushPerformingProgrammaticFocus];
324 [[webView _UIDelegateForwarder] webView:webView makeFirstResponder:view];
325 [webView _popPerformingProgrammaticFocus];
328 - (void)willMakeFirstResponderForNodeFocus
330 ASSERT([[[_frame frameView] documentView] isKindOfClass:[WebHTMLView class]]);
331 [(WebHTMLView *)[[_frame frameView] documentView] _willMakeFirstResponderForNodeFocus];
334 - (BOOL)textViewWasFirstResponderAtMouseDownTime:(NSTextView *)textView;
336 ASSERT(_frame != nil);
337 NSView *documentView = [[_frame frameView] documentView];
338 if (![documentView isKindOfClass:[WebHTMLView class]])
340 WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
341 return [webHTMLView _textViewWasFirstResponderAtMouseDownTime:textView];
344 - (void)closeWindowSoon
346 WebView *parentWebView = [self webView];
348 // We need to remove the parent WebView from WebViewSets here, before it actually
349 // closes, to make sure that JavaScript code that executes before it closes
350 // can't find it. Otherwise, window.open will select a closed WebView instead of
351 // opening a new one <rdar://problem/3572585>.
353 // We also need to stop the load to prevent further parsing or JavaScript execution
354 // after the window has torn down <rdar://problem/4161660>.
356 // FIXME: This code assumes that the UI delegate will respond to a webViewClose
357 // message by actually closing the WebView. Safari guarantees this behavior, but other apps might not.
358 // This approach is an inherent limitation of not making a close execute immediately
359 // after a call to window.close.
361 [parentWebView setGroupName:nil];
362 [parentWebView stopLoading:self];
363 [parentWebView performSelector:@selector(_closeWindow) withObject:nil afterDelay:0.0];
368 ASSERT(_frame != nil);
369 return [[_frame frameView] window];
372 - (void)runJavaScriptAlertPanelWithMessage:(NSString *)message
374 WebView *wv = [self webView];
375 id wd = [wv UIDelegate];
376 // Check whether delegate implements new version, then whether delegate implements old version. If neither,
377 // fall back to shared delegate's implementation of new version.
378 if ([wd respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:)])
379 [wd webView:wv runJavaScriptAlertPanelWithMessage:message initiatedByFrame:_frame];
380 else if ([wd respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:)])
381 [wd webView:wv runJavaScriptAlertPanelWithMessage:message];
383 [[WebDefaultUIDelegate sharedUIDelegate] webView:wv runJavaScriptAlertPanelWithMessage:message initiatedByFrame:_frame];
386 - (BOOL)runJavaScriptConfirmPanelWithMessage:(NSString *)message
388 WebView *wv = [self webView];
389 id wd = [wv UIDelegate];
390 // Check whether delegate implements new version, then whether delegate implements old version. If neither,
391 // fall back to shared delegate's implementation of new version.
392 if ([wd respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:)])
393 return [wd webView:wv runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:_frame];
394 if ([wd respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:)])
395 return [wd webView:wv runJavaScriptConfirmPanelWithMessage:message];
396 return [[WebDefaultUIDelegate sharedUIDelegate] webView:wv runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:_frame];
399 - (BOOL)shouldInterruptJavaScript
401 WebView *wv = [self webView];
402 id wd = [wv UIDelegate];
403 if ([wd respondsToSelector:@selector(webViewShouldInterruptJavaScript:)])
404 return [wd webViewShouldInterruptJavaScript:wv];
408 - (BOOL)canRunBeforeUnloadConfirmPanel
410 WebView *wv = [self webView];
411 id wd = [wv UIDelegate];
412 return [wd respondsToSelector:@selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:)];
415 - (BOOL)runBeforeUnloadConfirmPanelWithMessage:(NSString *)message
417 WebView *wv = [self webView];
418 id wd = [wv UIDelegate];
419 if ([wd respondsToSelector:@selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:)])
420 return [wd webView:wv runBeforeUnloadConfirmPanelWithMessage:message initiatedByFrame:_frame];
424 - (BOOL)runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText returningText:(NSString **)result
426 WebView *wv = [self webView];
427 id wd = [wv UIDelegate];
428 // Check whether delegate implements new version, then whether delegate implements old version. If neither,
429 // fall back to shared delegate's implementation of new version.
430 if ([wd respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:)])
431 *result = [wd webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:_frame];
432 else if ([wd respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:)])
433 *result = [wd webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText];
435 *result = [[WebDefaultUIDelegate sharedUIDelegate] webView:wv runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultText initiatedByFrame:_frame];
436 return *result != nil;
439 - (void)addMessageToConsole:(NSDictionary *)message
441 WebView *wv = [self webView];
442 id wd = [wv UIDelegate];
443 if ([wd respondsToSelector:@selector(webView:addMessageToConsole:)])
444 [wd webView:wv addMessageToConsole:message];
447 - (void)runOpenPanelForFileButtonWithResultListener:(id<WebCoreOpenPanelResultListener>)resultListener
449 WebView *wv = [self webView];
450 [[wv _UIDelegateForwarder] webView:wv runOpenPanelForFileButtonWithResultListener:(id<WebOpenPanelResultListener>)resultListener];
453 - (WebDataSource *)dataSource
455 ASSERT(_frame != nil);
456 WebDataSource *dataSource = [_frame dataSource];
458 ASSERT(dataSource != nil);
463 - (void)setStatusText:(NSString *)status
465 ASSERT(_frame != nil);
466 WebView *wv = [self webView];
467 [[wv _UIDelegateForwarder] webView:wv setStatusText:status];
477 - (void)activateWindow
479 [[[self webView] _UIDelegateForwarder] webViewFocus:[self webView]];
482 - (void)deactivateWindow
484 [[[self webView] _UIDelegateForwarder] webViewUnfocus:[self webView]];
487 - (void)formControlIsBecomingFirstResponder:(NSView *)formControl
489 // When a form element becomes first responder, its enclosing WebHTMLView might need to
490 // change its focus-displaying state, but isn't otherwise notified.
491 [(WebHTMLView *)[[_frame frameView] documentView] _formControlIsBecomingFirstResponder:formControl];
494 - (void)formControlIsResigningFirstResponder:(NSView *)formControl
496 // When a form element resigns first responder, its enclosing WebHTMLView might need to
497 // change its focus-displaying state, but isn't otherwise notified.
498 [(WebHTMLView *)[[_frame frameView] documentView] _formControlIsResigningFirstResponder:formControl];
501 - (WebCoreFrameBridge *)createChildFrameNamed:(NSString *)frameName
503 referrer:(const String&)referrer
504 ownerElement:(WebCoreElement *)ownerElement
505 allowsScrolling:(BOOL)allowsScrolling
506 marginWidth:(int)width
507 marginHeight:(int)height
510 if (!m_frame->loader()->canLoad(URL, referrer, hideReferrer))
515 WebFrameView *childView = [[WebFrameView alloc] initWithFrame:NSMakeRect(0,0,0,0)];
516 [childView setAllowsScrolling:allowsScrolling];
517 WebFrameBridge *newBridge = [[WebFrameBridge alloc] initSubframeWithOwnerElement:ownerElement frameName:frameName view:childView];
518 [_frame _addChild:[newBridge webFrame]];
521 [childView _setMarginWidth:width];
522 [childView _setMarginHeight:height];
529 [_frame _loadURL:URL referrer:(hideReferrer ? String() : referrer) intoChild:[newBridge webFrame]];
534 - (void)saveDocumentState:(NSArray *)documentState
536 WebHistoryItem *item = [_frame _itemForSavingDocState];
537 LOG(Loading, "%@: saving form state from to 0x%x", [_frame name], item);
539 [item setDocumentState:documentState];
540 // You might think we could save the scroll state here too, but unfortunately this
541 // often gets called after WebFrame::_transitionToCommitted has restored the scroll
542 // position of the next document.
545 - (NSArray *)documentState
547 LOG(Loading, "%@: restoring form state from item 0x%x", [_frame name], [_frame _itemForRestoringDocState]);
548 return [[_frame _itemForRestoringDocState] documentState];
551 - (NSString *)userAgentForURL:(NSURL *)URL
553 return [[self webView] userAgentForURL:URL];
556 - (BOOL)inNextKeyViewOutsideWebFrameViews
558 return _inNextKeyViewOutsideWebFrameViews;
561 - (NSView *)_nextKeyViewOutsideWebFrameViewsWithValidityCheck:(BOOL)mustBeValid
563 // We can get here in unusual situations such as the one listed in 4451831, so we
564 // return nil to avoid an infinite recursion.
565 if (_inNextKeyViewOutsideWebFrameViews)
568 _inNextKeyViewOutsideWebFrameViews = YES;
569 WebView *webView = [self webView];
570 // Do not ask webView for its next key view, but rather, ask it for
571 // the next key view of the last view in its key view loop.
572 // Doing so gives us the correct answer as calculated by AppKit,
573 // and makes HTML views behave like other views.
574 NSView *lastViewInLoop = [webView _findLastViewInKeyViewLoop];
575 NSView *nextKeyView = mustBeValid ? [lastViewInLoop nextValidKeyView] : [lastViewInLoop nextKeyView];
576 _inNextKeyViewOutsideWebFrameViews = NO;
580 - (NSView *)nextKeyViewOutsideWebFrameViews
582 return [self _nextKeyViewOutsideWebFrameViewsWithValidityCheck:NO];
585 - (NSView *)nextValidKeyViewOutsideWebFrameViews
587 return [self _nextKeyViewOutsideWebFrameViewsWithValidityCheck:YES];
590 - (NSView *)previousKeyViewOutsideWebFrameViews
592 return [[self webView] previousKeyView];
595 - (void)setNeedsReapplyStyles
597 NSView <WebDocumentView> *view = [[_frame frameView] documentView];
598 if ([view isKindOfClass:[WebHTMLView class]]) {
599 [(WebHTMLView *)view setNeedsToApplyStyles:YES];
600 [view setNeedsLayout:YES];
601 [view setNeedsDisplay:YES];
605 - (NSView *)pluginViewWithPackage:(WebPluginPackage *)pluginPackage
606 attributeNames:(NSArray *)attributeNames
607 attributeValues:(NSArray *)attributeValues
608 baseURL:(NSURL *)baseURL
609 DOMElement:(DOMElement *)element
610 loadManually:(BOOL)loadManually
612 WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
613 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
615 WebPluginController *pluginController = [docView _pluginController];
617 // Store attributes in a dictionary so they can be passed to WebPlugins.
618 NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
620 [pluginPackage load];
621 Class viewFactory = [pluginPackage viewFactory];
624 NSDictionary *arguments = nil;
626 if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
627 arguments = [NSDictionary dictionaryWithObjectsAndKeys:
628 baseURL, WebPlugInBaseURLKey,
629 attributes, WebPlugInAttributesKey,
630 pluginController, WebPlugInContainerKey,
631 [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
632 [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
633 element, WebPlugInContainingElementKey,
635 LOG(Plugins, "arguments:\n%@", arguments);
636 } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
637 arguments = [NSDictionary dictionaryWithObjectsAndKeys:
638 baseURL, WebPluginBaseURLKey,
639 attributes, WebPluginAttributesKey,
640 pluginController, WebPluginContainerKey,
641 element, WebPlugInContainingElementKey,
643 LOG(Plugins, "arguments:\n%@", arguments);
646 view = [WebPluginController plugInViewWithArguments:arguments fromPluginPackage:pluginPackage];
648 [attributes release];
652 - (NSString *)valueForKey:(NSString *)key keys:(NSArray *)keys values:(NSArray *)values
654 unsigned count = [keys count];
656 for (i = 0; i < count; i++)
657 if ([[keys objectAtIndex:i] _webkit_isCaseInsensitiveEqualToString:key])
658 return [values objectAtIndex:i];
662 - (NSView *)viewForPluginWithURL:(NSURL *)URL
663 attributeNames:(NSArray *)attributeNames
664 attributeValues:(NSArray *)attributeValues
665 MIMEType:(NSString *)MIMEType
666 DOMElement:(DOMElement *)element
667 loadManually:(BOOL)loadManually
670 if (!m_frame->loader()->canLoad(URL, m_frame->referrer(), hideReferrer))
673 ASSERT([attributeNames count] == [attributeValues count]);
675 WebBasePluginPackage *pluginPackage = nil;
679 WebView *wv = [self webView];
680 id wd = [wv UIDelegate];
682 if ([wd respondsToSelector:@selector(webView:plugInViewWithArguments:)]) {
683 NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
684 NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:
685 attributes, WebPlugInAttributesKey,
686 [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
687 URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
688 [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
689 element, WebPlugInContainingElementKey,
691 [attributes release];
692 view = [wd webView:wv plugInViewWithArguments:arguments];
697 if ([MIMEType length] != 0)
698 pluginPackage = [[self webView] _pluginForMIMEType:MIMEType];
702 NSString *extension = [[URL path] pathExtension];
703 if (!pluginPackage && [extension length] != 0) {
704 pluginPackage = [[self webView] _pluginForExtension:extension];
706 NSString *newMIMEType = [pluginPackage MIMETypeForExtension:extension];
707 if ([newMIMEType length] != 0)
708 MIMEType = newMIMEType;
712 NSURL *baseURL = [self baseURL];
714 if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
715 view = [self pluginViewWithPackage:(WebPluginPackage *)pluginPackage
716 attributeNames:attributeNames
717 attributeValues:attributeValues
720 loadManually:loadManually];
721 } else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
722 WebNetscapePluginEmbeddedView *embeddedView = [[[WebNetscapePluginEmbeddedView alloc] initWithFrame:NSZeroRect
723 plugin:(WebNetscapePluginPackage *)pluginPackage
727 attributeKeys:attributeNames
728 attributeValues:attributeValues
729 loadManually:loadManually
730 DOMElement:element] autorelease];
732 [_frame _addPlugInView:embeddedView];
734 ASSERT_NOT_REACHED();
736 errorCode = WebKitErrorCannotFindPlugIn;
738 if (!errorCode && !view)
739 errorCode = WebKitErrorCannotLoadPlugIn;
742 NSString *pluginPage = [self valueForKey:@"pluginspage" keys:attributeNames values:attributeValues];
743 NSURL *pluginPageURL = pluginPage != nil ? [self URLWithAttributeString:pluginPage] : nil;
744 NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
746 pluginPageURL:pluginPageURL
747 pluginName:[pluginPackage name]
749 WebNullPluginView *nullView = [[[WebNullPluginView alloc] initWithFrame:NSZeroRect error:error] autorelease];
750 [_frame _addPlugInView:nullView];
759 - (void)redirectDataToPlugin:(NSView *)pluginView
761 WebHTMLRepresentation *representation = (WebHTMLRepresentation *)[[_frame dataSource] representation];
763 if ([pluginView isKindOfClass:[WebNetscapePluginEmbeddedView class]])
764 [representation _redirectDataToManualLoader:(WebNetscapePluginEmbeddedView *)pluginView forPluginView:pluginView];
766 WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
767 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
769 WebPluginController *pluginController = [docView _pluginController];
770 [representation _redirectDataToManualLoader:pluginController forPluginView:pluginView];
774 - (NSView *)viewForJavaAppletWithFrame:(NSRect)theFrame
775 attributeNames:(NSArray *)attributeNames
776 attributeValues:(NSArray *)attributeValues
777 baseURL:(NSURL *)baseURL
778 DOMElement:(DOMElement *)element
780 NSString *MIMEType = @"application/x-java-applet";
781 WebBasePluginPackage *pluginPackage;
784 pluginPackage = [[self webView] _pluginForMIMEType:MIMEType];
787 if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
788 // For some reason, the Java plug-in requires that we pass the dimension of the plug-in as attributes.
789 NSMutableArray *names = [attributeNames mutableCopy];
790 NSMutableArray *values = [attributeValues mutableCopy];
791 if ([self valueForKey:@"width" keys:attributeNames values:attributeValues] == nil) {
792 [names addObject:@"width"];
793 [values addObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.width]];
795 if ([self valueForKey:@"height" keys:attributeNames values:attributeValues] == nil) {
796 [names addObject:@"height"];
797 [values addObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.height]];
799 view = [self pluginViewWithPackage:(WebPluginPackage *)pluginPackage
801 attributeValues:values
807 } else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
808 view = [[[WebNetscapePluginEmbeddedView alloc] initWithFrame:theFrame
809 plugin:(WebNetscapePluginPackage *)pluginPackage
813 attributeKeys:attributeNames
814 attributeValues:attributeValues
816 DOMElement:element] autorelease];
818 ASSERT_NOT_REACHED();
823 NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorJavaUnavailable
826 pluginName:[pluginPackage name]
828 view = [[[WebNullPluginView alloc] initWithFrame:theFrame error:error] autorelease];
838 static BOOL loggedObjectCacheSize = NO;
841 -(int)getObjectCacheSize
843 vm_size_t memSize = WebSystemMainMemory();
844 int cacheSize = [[self _preferences] _objectCacheSize];
847 // 2GB and greater will be 128mb. 1gb and greater will be 64mb.
848 // Otherwise just use 32mb.
849 if (memSize >= (unsigned)(2048 * 1024 * 1024))
851 else if (memSize >= 1024 * 1024 * 1024)
855 if (!loggedObjectCacheSize){
856 LOG(CacheSizes, "Object cache size set to %d bytes.", cacheSize * multiplier);
857 loggedObjectCacheSize = YES;
861 return cacheSize * multiplier;
864 - (ObjectElementType)determineObjectFromMIMEType:(NSString*)MIMEType URL:(NSURL*)URL
866 if ([MIMEType length] == 0) {
867 // Try to guess the MIME type based off the extension.
868 NSString *extension = [[URL path] pathExtension];
869 if ([extension length] > 0) {
870 MIMEType = WKGetMIMETypeForExtension(extension);
871 if ([MIMEType length] == 0 && [[self webView] _pluginForExtension:extension])
872 // If no MIME type is specified, use a plug-in if we have one that can handle the extension.
873 return ObjectElementPlugin;
877 if ([MIMEType length] == 0)
878 return ObjectElementFrame; // Go ahead and hope that we can display the content.
880 if ([[WebCoreFrameBridge supportedImageMIMETypes] containsObject:MIMEType])
881 return ObjectElementFrame;
883 if ([[self webView] _isMIMETypeRegisteredAsPlugin:MIMEType])
884 return ObjectElementPlugin;
886 if ([WebFrameView _viewClassForMIMEType:MIMEType])
887 return ObjectElementFrame;
889 return ObjectElementNone;
892 - (NSString *)MIMETypeForPath:(NSString *)path
895 NSString *extension = [path pathExtension];
896 NSString *type = WKGetMIMETypeForExtension(extension);
897 return [type length] == 0 ? (NSString *)@"application/octet-stream" : type;
900 - (void)allowDHTMLDrag:(BOOL *)flagDHTML UADrag:(BOOL *)flagUA
902 WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
903 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
904 unsigned int mask = [docView _delegateDragSourceActionMask];
905 *flagDHTML = (mask & WebDragSourceActionDHTML) != 0;
906 *flagUA = ((mask & WebDragSourceActionImage) || (mask & WebDragSourceActionLink) || (mask & WebDragSourceActionSelection));
909 - (BOOL)startDraggingImage:(NSImage *)dragImage at:(NSPoint)dragLoc operation:(NSDragOperation)op
910 event:(NSEvent *)event sourceIsDHTML:(BOOL)flag DHTMLWroteData:(BOOL)dhtmlWroteData
912 WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
913 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
914 [docView _setInitiatedDrag:YES];
915 return [docView _startDraggingImage:dragImage at:dragLoc operation:op event:event
916 sourceIsDHTML:flag DHTMLWroteData:dhtmlWroteData];
919 - (BOOL)mayStartDragAtEventLocation:(NSPoint)location
921 WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
922 ASSERT([docView isKindOfClass:[WebHTMLView class]]);
923 return [docView _mayStartDragAtEventLocation:location];
926 - (BOOL)selectWordBeforeMenuEvent
928 return [[self webView] _selectWordBeforeMenuEvent];
933 return [[[self webView] backForwardList] backListCount] + 1;
936 - (BOOL)canGoBackOrForward:(int)distance
940 if (distance > 0 && distance <= [[[self webView] backForwardList] forwardListCount])
942 if (distance < 0 && -distance <= [[[self webView] backForwardList] backListCount])
947 - (void)goBackOrForward:(int)distance
951 WebView *webView = [self webView];
952 WebBackForwardList *list = [webView backForwardList];
953 WebHistoryItem *item = [list itemAtIndex:distance];
956 int forwardListCount = [list forwardListCount];
957 if (forwardListCount > 0) {
958 item = [list itemAtIndex:forwardListCount];
961 int backListCount = [list forwardListCount];
962 if (backListCount > 0) {
963 item = [list itemAtIndex:-backListCount];
968 [webView goToBackForwardItem:item];
972 - (NSURL*)historyURL:(int)distance
974 WebView *webView = [self webView];
975 WebBackForwardList *list = [webView backForwardList];
976 WebHistoryItem *item = [list itemAtIndex:distance];
979 int forwardListCount = [list forwardListCount];
980 if (forwardListCount > 0)
981 item = [list itemAtIndex:forwardListCount];
983 int backListCount = [list forwardListCount];
984 if (backListCount > 0)
985 item = [list itemAtIndex:-backListCount];
994 static id <WebFormDelegate> formDelegate(WebFrameBridge *self)
996 ASSERT(self->_frame != nil);
997 return [[self->_frame webView] _formDelegate];
1000 #define FormDelegateLog(ctrl) LOG(FormDelegate, "control=%@", ctrl)
1002 - (void)textFieldDidBeginEditing:(DOMHTMLInputElement *)element
1004 FormDelegateLog(element);
1005 [formDelegate(self) textFieldDidBeginEditing:element inFrame:_frame];
1008 - (void)textFieldDidEndEditing:(DOMHTMLInputElement *)element
1010 FormDelegateLog(element);
1011 [formDelegate(self) textFieldDidEndEditing:element inFrame:_frame];
1014 - (void)textDidChangeInTextField:(DOMHTMLInputElement *)element
1016 FormDelegateLog(element);
1017 [formDelegate(self) textDidChangeInTextField:(DOMHTMLInputElement *)element inFrame:_frame];
1020 - (void)textDidChangeInTextArea:(DOMHTMLTextAreaElement *)element
1022 FormDelegateLog(element);
1023 [formDelegate(self) textDidChangeInTextArea:element inFrame:_frame];
1026 - (BOOL)textField:(DOMHTMLInputElement *)element doCommandBySelector:(SEL)commandSelector
1028 FormDelegateLog(element);
1029 return [formDelegate(self) textField:element doCommandBySelector:commandSelector inFrame:_frame];
1032 - (BOOL)textField:(DOMHTMLInputElement *)element shouldHandleEvent:(NSEvent *)event
1034 FormDelegateLog(element);
1035 return [formDelegate(self) textField:element shouldHandleEvent:event inFrame:_frame];
1038 - (void)setHasBorder:(BOOL)hasBorder
1040 [[_frame frameView] _setHasBorder:hasBorder];
1045 id wd = [[self webView] UIDelegate];
1046 if ([wd respondsToSelector:@selector(webView:printFrameView:)])
1047 [wd webView:[self webView] printFrameView:[_frame frameView]];
1049 [[WebDefaultUIDelegate sharedUIDelegate] webView:[self webView] printFrameView:[_frame frameView]];
1052 - (jobject)getAppletInView:(NSView *)view
1054 if ([view respondsToSelector:@selector(webPlugInGetApplet)])
1055 return [view webPlugInGetApplet];
1056 return [self pollForAppletInView:view];
1059 // NOTE: pollForAppletInView: will block until the block is ready to use, or
1060 // until a timeout is exceeded. It will return nil if the timeout is
1062 // Deprecated, use getAppletInView:.
1063 - (jobject)pollForAppletInView:(NSView *)view
1065 if ([view respondsToSelector:@selector(pollForAppletInWindow:)])
1066 // The Java VM needs the containing window of the view to
1067 // initialize. The view may not yet be in the window's view
1068 // hierarchy, so we have to pass the window when requesting
1070 return [view pollForAppletInWindow:[[self webView] window]];
1074 - (void)respondToChangedContents
1076 NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1077 if ([view isKindOfClass:[WebHTMLView class]])
1078 [(WebHTMLView *)view _updateFontPanel];
1079 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidChangeNotification object:[self webView]];
1082 - (void)respondToChangedSelection
1084 NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1085 if ([view isKindOfClass:[WebHTMLView class]])
1086 [(WebHTMLView *)view _selectionChanged];
1087 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidChangeSelectionNotification object:[self webView]];
1090 - (NSUndoManager *)undoManager
1092 return [[self webView] undoManager];
1095 - (void)issueCutCommand
1097 NSView* documentView = [[_frame frameView] documentView];
1098 if ([documentView isKindOfClass:[WebHTMLView class]])
1099 [(WebHTMLView*)documentView cut:nil];
1102 - (void)issueCopyCommand
1104 NSView* documentView = [[_frame frameView] documentView];
1105 if ([documentView isKindOfClass:[WebHTMLView class]])
1106 [(WebHTMLView*)documentView copy:nil];
1109 - (void)issuePasteCommand
1111 NSView* documentView = [[_frame frameView] documentView];
1112 if ([documentView isKindOfClass:[WebHTMLView class]])
1113 [(WebHTMLView*)documentView paste:nil];
1116 - (void)issuePasteAndMatchStyleCommand
1118 NSView <WebDocumentView> *documentView = [[_frame frameView] documentView];
1119 if ([documentView isKindOfClass:[WebHTMLView class]])
1120 [(WebHTMLView*)documentView pasteAsPlainText:nil];
1123 - (void)issueTransposeCommand
1125 NSView <WebDocumentView> *view = [[_frame frameView] documentView];
1126 if ([view isKindOfClass:[WebHTMLView class]])
1127 [(WebHTMLView *)view transpose:nil];
1130 - (void)setIsSelected:(BOOL)isSelected forView:(NSView *)view
1132 if ([view respondsToSelector:@selector(webPlugInSetIsSelected:)])
1133 [view webPlugInSetIsSelected:isSelected];
1134 else if ([view respondsToSelector:@selector(setIsSelected:)])
1135 [view setIsSelected:isSelected];
1138 - (NSString *)overrideMediaType
1140 return [[self webView] mediaStyle];
1145 return [[self webView] isEditable];
1148 - (BOOL)shouldChangeSelectedDOMRange:(DOMRange *)currentRange toDOMRange:(DOMRange *)proposedRange affinity:(WebCore::EAffinity)selectionAffinity stillSelecting:(BOOL)flag
1150 return [[self webView] _shouldChangeSelectedDOMRange:currentRange toDOMRange:proposedRange affinity:kit(selectionAffinity) stillSelecting:flag];
1153 - (BOOL)shouldDeleteSelectedDOMRange:(DOMRange *)range
1155 WebView *webView = [self webView];
1156 return [[webView _editingDelegateForwarder] webView:webView shouldDeleteDOMRange:range];
1159 - (BOOL)shouldBeginEditing:(DOMRange *)range
1161 return [[self webView] _shouldBeginEditingInDOMRange:range];
1164 - (BOOL)shouldEndEditing:(DOMRange *)range
1166 return [[self webView] _shouldEndEditingInDOMRange:range];
1169 - (void)didBeginEditing
1171 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidBeginEditingNotification object:[_frame webView]];
1174 - (void)didEndEditing
1176 [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidEndEditingNotification object:[_frame webView]];
1179 - (void)windowObjectCleared
1181 WebView *wv = [self webView];
1182 [[wv _frameLoadDelegateForwarder] webView:wv windowScriptObjectAvailable:m_frame->windowScriptObject()];
1183 if ([wv scriptDebugDelegate] || [WebScriptDebugServer listenerCount]) {
1184 [_frame _detachScriptDebugger]; // FIXME: remove this once <rdar://problem/4608404> is fixed
1185 [_frame _attachScriptDebugger];
1189 - (BOOL)_compareDashboardRegions:(NSDictionary *)regions
1191 return [lastDashboardRegions isEqualToDictionary:regions];
1194 - (void)dashboardRegionsChanged:(NSMutableDictionary *)regions
1196 WebView *wv = [self webView];
1197 id wd = [wv UIDelegate];
1199 [wv _addScrollerDashboardRegions:regions];
1201 if (![self _compareDashboardRegions:regions]) {
1202 if ([wd respondsToSelector:@selector(webView:dashboardRegionsChanged:)]) {
1203 [wd webView:wv dashboardRegionsChanged:regions];
1204 [lastDashboardRegions release];
1205 lastDashboardRegions = [regions retain];
1210 - (void)willPopupMenu:(NSMenu *)menu
1212 WebView *wv = [self webView];
1213 id wd = [wv UIDelegate];
1215 if ([wd respondsToSelector:@selector(webView:willPopupMenu:)])
1216 [wd webView:wv willPopupMenu:menu];
1219 - (NSRect)customHighlightRect:(NSString*)type forLine:(NSRect)lineRect
1221 ASSERT(_frame != nil);
1222 NSView *documentView = [[_frame frameView] documentView];
1223 if (![documentView isKindOfClass:[WebHTMLView class]])
1226 WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
1227 id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
1228 return [highlighter highlightRectForLine:lineRect];
1231 - (void)paintCustomHighlight:(NSString*)type forBox:(NSRect)boxRect onLine:(NSRect)lineRect behindText:(BOOL)text
1232 entireLine:(BOOL)line
1234 ASSERT(_frame != nil);
1235 NSView *documentView = [[_frame frameView] documentView];
1236 if (![documentView isKindOfClass:[WebHTMLView class]])
1239 WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
1240 id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
1241 [highlighter paintHighlightForBox:boxRect onLine:lineRect behindText:text entireLine:line];
1244 - (NSString *)nameForUndoAction:(WebUndoAction)undoAction
1246 switch (undoAction) {
1247 case WebUndoActionUnspecified: return nil;
1248 case WebUndoActionSetColor: return UI_STRING_KEY("Set Color", "Set Color (Undo action name)", "Undo action name");
1249 case WebUndoActionSetBackgroundColor: return UI_STRING_KEY("Set Background Color", "Set Background Color (Undo action name)", "Undo action name");
1250 case WebUndoActionTurnOffKerning: return UI_STRING_KEY("Turn Off Kerning", "Turn Off Kerning (Undo action name)", "Undo action name");
1251 case WebUndoActionTightenKerning: return UI_STRING_KEY("Tighten Kerning", "Tighten Kerning (Undo action name)", "Undo action name");
1252 case WebUndoActionLoosenKerning: return UI_STRING_KEY("Loosen Kerning", "Loosen Kerning (Undo action name)", "Undo action name");
1253 case WebUndoActionUseStandardKerning: return UI_STRING_KEY("Use Standard Kerning", "Use Standard Kerning (Undo action name)", "Undo action name");
1254 case WebUndoActionTurnOffLigatures: return UI_STRING_KEY("Turn Off Ligatures", "Turn Off Ligatures (Undo action name)", "Undo action name");
1255 case WebUndoActionUseStandardLigatures: return UI_STRING_KEY("Use Standard Ligatures", "Use Standard Ligatures (Undo action name)", "Undo action name");
1256 case WebUndoActionUseAllLigatures: return UI_STRING_KEY("Use All Ligatures", "Use All Ligatures (Undo action name)", "Undo action name");
1257 case WebUndoActionRaiseBaseline: return UI_STRING_KEY("Raise Baseline", "Raise Baseline (Undo action name)", "Undo action name");
1258 case WebUndoActionLowerBaseline: return UI_STRING_KEY("Lower Baseline", "Lower Baseline (Undo action name)", "Undo action name");
1259 case WebUndoActionSetTraditionalCharacterShape: return UI_STRING_KEY("Set Traditional Character Shape", "Set Traditional Character Shape (Undo action name)", "Undo action name");
1260 case WebUndoActionSetFont: return UI_STRING_KEY("Set Font", "Set Font (Undo action name)", "Undo action name");
1261 case WebUndoActionChangeAttributes: return UI_STRING_KEY("Change Attributes", "Change Attributes (Undo action name)", "Undo action name");
1262 case WebUndoActionAlignLeft: return UI_STRING_KEY("Align Left", "Align Left (Undo action name)", "Undo action name");
1263 case WebUndoActionAlignRight: return UI_STRING_KEY("Align Right", "Align Right (Undo action name)", "Undo action name");
1264 case WebUndoActionCenter: return UI_STRING_KEY("Center", "Center (Undo action name)", "Undo action name");
1265 case WebUndoActionJustify: return UI_STRING_KEY("Justify", "Justify (Undo action name)", "Undo action name");
1266 case WebUndoActionSetWritingDirection: return UI_STRING_KEY("Set Writing Direction", "Set Writing Direction (Undo action name)", "Undo action name");
1267 case WebUndoActionSubscript: return UI_STRING_KEY("Subscript", "Subscript (Undo action name)", "Undo action name");
1268 case WebUndoActionSuperscript: return UI_STRING_KEY("Superscript", "Superscript (Undo action name)", "Undo action name");
1269 case WebUndoActionUnderline: return UI_STRING_KEY("Underline", "Underline (Undo action name)", "Undo action name");
1270 case WebUndoActionOutline: return UI_STRING_KEY("Outline", "Outline (Undo action name)", "Undo action name");
1271 case WebUndoActionUnscript: return UI_STRING_KEY("Unscript", "Unscript (Undo action name)", "Undo action name");
1272 case WebUndoActionDrag: return UI_STRING_KEY("Drag", "Drag (Undo action name)", "Undo action name");
1273 case WebUndoActionCut: return UI_STRING_KEY("Cut", "Cut (Undo action name)", "Undo action name");
1274 case WebUndoActionPaste: return UI_STRING_KEY("Paste", "Paste (Undo action name)", "Undo action name");
1275 case WebUndoActionPasteFont: return UI_STRING_KEY("Paste Font", "Paste Font (Undo action name)", "Undo action name");
1276 case WebUndoActionPasteRuler: return UI_STRING_KEY("Paste Ruler", "Paste Ruler (Undo action name)", "Undo action name");
1277 case WebUndoActionTyping: return UI_STRING_KEY("Typing", "Typing (Undo action name)", "Undo action name");
1278 case WebUndoActionCreateLink: return UI_STRING_KEY("Create Link", "Create Link (Undo action name)", "Undo action name");
1279 case WebUndoActionUnlink: return UI_STRING_KEY("Unlink", "Unlink (Undo action name)", "Undo action name");
1280 case WebUndoActionInsertList: return UI_STRING_KEY("Insert List", "Insert List (Undo action name)", "Undo action name");
1281 case WebUndoActionFormatBlock: return UI_STRING_KEY("Formatting", "Format Block (Undo action name)", "Undo action name");
1282 case WebUndoActionIndent: return UI_STRING_KEY("Indent", "Indent (Undo action name)", "Undo action name");
1283 case WebUndoActionOutdent: return UI_STRING_KEY("Outdent", "Outdent (Undo action name)", "Undo action name");
1288 - (NSString*)imageTitleForFilename:(NSString*)filename size:(NSSize)size
1290 return [NSString stringWithFormat:UI_STRING("%@ %.0f×%.0f pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filename, size.width, size.height];