WebFrameBridge.mm 28.8 KB
Newer Older
1
/*
darin@apple.com's avatar
darin@apple.com committed
2
 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
darin's avatar
darin committed
28

darin's avatar
darin committed
29 30 31 32 33
#import "WebFrameBridge.h"

#import "WebBackForwardList.h"
#import "WebBaseNetscapePluginView.h"
#import "WebBasePluginPackage.h"
mjs's avatar
mjs committed
34
#import "WebDataSourceInternal.h"
darin's avatar
darin committed
35 36 37 38
#import "WebDefaultUIDelegate.h"
#import "WebEditingDelegate.h"
#import "WebFormDelegate.h"
#import "WebFrameInternal.h"
darin's avatar
darin committed
39
#import "WebFrameLoadDelegate.h"
ggaren's avatar
ggaren committed
40
#import "WebFrameLoaderClient.h"
darin's avatar
darin committed
41 42 43
#import "WebFrameViewInternal.h"
#import "WebHTMLRepresentationPrivate.h"
#import "WebHTMLViewInternal.h"
beidson's avatar
beidson committed
44
#import "WebHistoryItemInternal.h"
darin's avatar
darin committed
45 46 47 48 49 50
#import "WebHistoryItemPrivate.h"
#import "WebJavaPlugIn.h"
#import "WebJavaScriptTextInputPanel.h"
#import "WebKitErrorsPrivate.h"
#import "WebKitLogging.h"
#import "WebKitNSStringExtras.h"
51
#import "WebKitPluginContainerView.h"
darin's avatar
darin committed
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
#import "WebKitStatisticsPrivate.h"
#import "WebKitSystemBits.h"
#import "WebLocalizableStrings.h"
#import "WebNSObjectExtras.h"
#import "WebNSURLExtras.h"
#import "WebNSURLRequestExtras.h"
#import "WebNSViewExtras.h"
#import "WebNetscapePluginEmbeddedView.h"
#import "WebNetscapePluginPackage.h"
#import "WebNullPluginView.h"
#import "WebPlugin.h"
#import "WebPluginController.h"
#import "WebPluginDatabase.h"
#import "WebPluginPackage.h"
#import "WebPluginViewFactoryPrivate.h"
#import "WebPreferencesPrivate.h"
#import "WebResourcePrivate.h"
thatcher's avatar
thatcher committed
69
#import "WebScriptDebugServerPrivate.h"
darin's avatar
darin committed
70 71
#import "WebUIDelegatePrivate.h"
#import "WebViewInternal.h"
kocienda's avatar
kocienda committed
72
#import <Foundation/NSURLConnection.h>
darin's avatar
darin committed
73
#import <Foundation/NSURLRequest.h>
kocienda's avatar
kocienda committed
74
#import <Foundation/NSURLResponse.h>
darin's avatar
darin committed
75
#import <JavaScriptCore/Assertions.h>
mjs's avatar
mjs committed
76 77
#import <JavaScriptCore/JSLock.h>
#import <JavaScriptCore/object.h>
rjw's avatar
WebKit:  
rjw committed
78
#import <JavaVM/jni.h>
ggaren's avatar
ggaren committed
79 80
#import <WebCore/Cache.h>
#import <WebCore/Document.h>
81
#import <WebCore/DocumentLoader.h>
82 83
#import <WebCore/DragController.h>
#import <WebCore/Element.h>
mjs's avatar
mjs committed
84 85
#import <WebCore/FoundationExtras.h>
#import <WebCore/Frame.h>
ggaren's avatar
ggaren committed
86
#import <WebCore/FrameLoader.h>
darin's avatar
darin committed
87
#import <WebCore/FrameLoaderClient.h>
darin's avatar
darin committed
88
#import <WebCore/FrameTree.h>
darin's avatar
darin committed
89
#import <WebCore/HTMLFrameOwnerElement.h>
darin's avatar
darin committed
90
#import <WebCore/Page.h>
darin's avatar
darin committed
91 92
#import <WebCore/ResourceLoader.h>
#import <WebCore/SubresourceLoader.h>
thatcher's avatar
thatcher committed
93
#import <WebCore/WebCoreObjCExtras.h>
darin's avatar
darin committed
94
#import <WebKitSystemInterface.h>
darin's avatar
darin committed
95
#import <wtf/RefPtr.h>
weinig's avatar
weinig committed
96
#import <WebCore/MIMETypeRegistry.h>
rjw's avatar
WebKit:  
rjw committed
97

98 99
// For compatibility with old SPI. 
@interface NSView (OldWebPlugin)
rjw's avatar
WebKit:  
rjw committed
100 101 102
- (void)setIsSelected:(BOOL)f;
@end

rjw's avatar
WebKit:  
rjw committed
103
@interface NSView (JavaPluginSecrets)
darin's avatar
darin committed
104
- (jobject)pollForAppletInWindow:(NSWindow *)window;
rjw's avatar
WebKit:  
rjw committed
105 106
@end

darin's avatar
darin committed
107 108
using namespace WebCore;

109 110 111 112
NSString *WebPluginBaseURLKey =     @"WebPluginBaseURL";
NSString *WebPluginAttributesKey =  @"WebPluginAttributes";
NSString *WebPluginContainerKey =   @"WebPluginContainer";

113 114 115 116
#define KeyboardUIModeDidChangeNotification @"com.apple.KeyboardUIModeDidChange"
#define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode")
#define UniversalAccessDomain CFSTR("com.apple.universalaccess")

mjs's avatar
mjs committed
117
@implementation WebFrameBridge
darin's avatar
darin committed
118

thatcher's avatar
thatcher committed
119 120 121 122 123 124 125
#ifndef BUILDING_ON_TIGER
+ (void)initialize
{
    WebCoreObjCFinalizeOnMainThread(self);
}
#endif

darin's avatar
darin committed
126 127
- (WebView *)webView
{
aroben's avatar
aroben committed
128 129 130
    if (!m_frame)
        return nil;
    
ggaren's avatar
ggaren committed
131
    return kit(m_frame->page());
darin's avatar
darin committed
132 133
}

darin's avatar
darin committed
134
- (void)finishInitializingWithPage:(Page*)page frameName:(NSString *)name frameView:(WebFrameView *)frameView ownerElement:(HTMLFrameOwnerElement*)ownerElement
darin's avatar
darin committed
135 136
{
    ++WebBridgeCount;
darin's avatar
darin committed
137

ggaren's avatar
ggaren committed
138 139 140 141
    WebView *webView = kit(page);

    _frame = [[WebFrame alloc] _initWithWebFrameView:frameView webView:webView bridge:self];

mjs's avatar
mjs committed
142
    m_frame = new Frame(page, ownerElement, new WebFrameLoaderClient(_frame));
ggaren's avatar
ggaren committed
143
    m_frame->setBridge(self);
ggaren's avatar
ggaren committed
144
    m_frame->tree()->setName(name);
mjs's avatar
mjs committed
145
    m_frame->init();
ggaren's avatar
ggaren committed
146
    
darin's avatar
darin committed
147 148
    [self setTextSizeMultiplier:[webView textSizeMultiplier]];
}
darin's avatar
darin committed
149

darin's avatar
darin committed
150
- (id)initMainFrameWithPage:(Page*)page frameName:(NSString *)name frameView:(WebFrameView *)frameView
darin's avatar
darin committed
151
{
ggaren's avatar
ggaren committed
152 153
    self = [super init];
    [self finishInitializingWithPage:page frameName:name frameView:frameView ownerElement:0];
darin's avatar
darin committed
154 155 156
    return self;
}

darin's avatar
darin committed
157
- (id)initSubframeWithOwnerElement:(HTMLFrameOwnerElement*)ownerElement frameName:(NSString *)name frameView:(WebFrameView *)frameView
darin's avatar
darin committed
158
{
ggaren's avatar
ggaren committed
159 160
    self = [super init];
    [self finishInitializingWithPage:ownerElement->document()->frame()->page() frameName:name frameView:frameView ownerElement:ownerElement];
darin's avatar
WebKit:  
darin committed
161
    return self;
darin's avatar
darin committed
162 163
}

164
- (void)fini
darin's avatar
darin committed
165
{
mjs's avatar
mjs committed
166 167 168 169 170 171
    if (_keyboardUIModeAccessed) {
        [[NSDistributedNotificationCenter defaultCenter] 
            removeObserver:self name:KeyboardUIModeDidChangeNotification object:nil];
        [[NSNotificationCenter defaultCenter] 
            removeObserver:self name:WebPreferencesChangedNotification object:nil];
    }
mjs's avatar
mjs committed
172

darin's avatar
WebKit:  
darin committed
173
    ASSERT(_frame == nil);
darin's avatar
darin committed
174
    --WebBridgeCount;
175 176 177 178
}

- (void)dealloc
{
rjw's avatar
rjw committed
179
    [lastDashboardRegions release];
mjs's avatar
mjs committed
180
    [_frame release];
rjw's avatar
rjw committed
181
    
182
    [self fini];
darin's avatar
darin committed
183 184 185
    [super dealloc];
}

186 187
- (void)finalize
{
thatcher's avatar
thatcher committed
188
    ASSERT_MAIN_THREAD();
189 190 191 192
    [self fini];
    [super finalize];
}

mjs's avatar
mjs committed
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
- (WebPreferences *)_preferences
{
    return [[self webView] preferences];
}

- (void)_retrieveKeyboardUIModeFromPreferences:(NSNotification *)notification
{
    CFPreferencesAppSynchronize(UniversalAccessDomain);

    Boolean keyExistsAndHasValidFormat;
    int mode = CFPreferencesGetAppIntegerValue(AppleKeyboardUIMode, UniversalAccessDomain, &keyExistsAndHasValidFormat);
    
    // The keyboard access mode is reported by two bits:
    // Bit 0 is set if feature is on
    // Bit 1 is set if full keyboard access works for any control, not just text boxes and lists
    // We require both bits to be on.
    // I do not know that we would ever get one bit on and the other off since
    // checking the checkbox in system preferences which is marked as "Turn on full keyboard access"
    // turns on both bits.
darin's avatar
darin committed
212
    _keyboardUIMode = (mode & 0x2) ? KeyboardAccessFull : KeyboardAccessDefault;
mjs's avatar
mjs committed
213 214
    
    // check for tabbing to links
darin's avatar
darin committed
215
    if ([[self _preferences] tabsToLinks])
darin's avatar
darin committed
216
        _keyboardUIMode = (KeyboardUIMode)(_keyboardUIMode | KeyboardAccessTabsToLinks);
mjs's avatar
mjs committed
217 218
}

darin's avatar
darin committed
219
- (KeyboardUIMode)keyboardUIMode
mjs's avatar
mjs committed
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
{
    if (!_keyboardUIModeAccessed) {
        _keyboardUIModeAccessed = YES;
        [self _retrieveKeyboardUIModeFromPreferences:nil];
        
        [[NSDistributedNotificationCenter defaultCenter] 
            addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:) 
            name:KeyboardUIModeDidChangeNotification object:nil];

        [[NSNotificationCenter defaultCenter] 
            addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:) 
                   name:WebPreferencesChangedNotification object:nil];
    }
    return _keyboardUIMode;
}

cblu's avatar
Tests:  
cblu committed
236 237 238 239 240
- (WebFrame *)webFrame
{
    return _frame;
}

mjs's avatar
mjs committed
241
- (WebCoreFrameBridge *)mainFrame
cblu's avatar
cblu committed
242
{
darin's avatar
WebKit:  
darin committed
243
    ASSERT(_frame != nil);
darin's avatar
darin committed
244
    return [[[self webView] mainFrame] _bridge];
cblu's avatar
cblu committed
245 246
}

kocienda's avatar
kocienda committed
247 248 249 250 251 252
- (NSView *)documentView
{
    ASSERT(_frame != nil);
    return [[_frame frameView] documentView];
}

mjs's avatar
mjs committed
253 254
- (NSResponder *)firstResponder
{
darin's avatar
WebKit:  
darin committed
255
    ASSERT(_frame != nil);
darin's avatar
darin committed
256
    WebView *webView = [self webView];
rjw's avatar
rjw committed
257
    return [[webView _UIDelegateForwarder] webViewFirstResponder:webView];
mjs's avatar
mjs committed
258 259 260 261
}

- (void)makeFirstResponder:(NSResponder *)view
{
darin's avatar
WebKit:  
darin committed
262
    ASSERT(_frame != nil);
darin's avatar
darin committed
263
    WebView *webView = [self webView];
adele's avatar
adele committed
264 265 266
    ASSERT([view isKindOfClass:[NSView class]]);
    ASSERT([(NSView *)view window]);
    ASSERT([(NSView *)view window] == [webView window]);
mjs's avatar
mjs committed
267
    [webView _pushPerformingProgrammaticFocus];
rjw's avatar
rjw committed
268
    [[webView _UIDelegateForwarder] webView:webView makeFirstResponder:view];
mjs's avatar
mjs committed
269
    [webView _popPerformingProgrammaticFocus];
mjs's avatar
mjs committed
270 271
}

mjs's avatar
mjs committed
272 273 274 275 276 277
- (void)willMakeFirstResponderForNodeFocus
{
    ASSERT([[[_frame frameView] documentView] isKindOfClass:[WebHTMLView class]]);
    [(WebHTMLView *)[[_frame frameView] documentView] _willMakeFirstResponderForNodeFocus];
}

sullivan's avatar
sullivan committed
278
- (BOOL)textViewWasFirstResponderAtMouseDownTime:(NSTextView *)textView;
darin's avatar
darin committed
279 280 281
{
    ASSERT(_frame != nil);
    NSView *documentView = [[_frame frameView] documentView];
282
    if (![documentView isKindOfClass:[WebHTMLView class]])
darin's avatar
darin committed
283 284
        return NO;
    WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
sullivan's avatar
sullivan committed
285
    return [webHTMLView _textViewWasFirstResponderAtMouseDownTime:textView];
darin's avatar
darin committed
286 287
}

mjs's avatar
mjs committed
288 289
- (NSWindow *)window
{
darin's avatar
WebKit:  
darin committed
290 291
    ASSERT(_frame != nil);
    return [[_frame frameView] window];
mjs's avatar
mjs committed
292 293
}

mjs's avatar
mjs committed
294
- (void)runOpenPanelForFileButtonWithResultListener:(id<WebCoreOpenPanelResultListener>)resultListener
mjs's avatar
mjs committed
295
{
darin's avatar
darin committed
296
    WebView *wv = [self webView];
mjs's avatar
mjs committed
297
    [[wv _UIDelegateForwarder] webView:wv runOpenPanelForFileButtonWithResultListener:(id<WebOpenPanelResultListener>)resultListener];
mjs's avatar
mjs committed
298 299
}

darin's avatar
darin committed
300 301
- (WebDataSource *)dataSource
{
darin's avatar
WebKit:  
darin committed
302
    ASSERT(_frame != nil);
mjs's avatar
mjs committed
303
    WebDataSource *dataSource = [_frame _dataSource];
darin's avatar
darin committed
304 305 306 307 308 309

    ASSERT(dataSource != nil);

    return dataSource;
}

darin's avatar
WebKit:  
darin committed
310
- (void)close
darin's avatar
darin committed
311
{
thatcher's avatar
thatcher committed
312
    [super close];
mjs's avatar
mjs committed
313
    [_frame release];
darin's avatar
WebKit:  
darin committed
314
    _frame = nil;
315
}
316

ggaren's avatar
ggaren committed
317
- (Frame*)createChildFrameNamed:(NSString *)frameName 
darin's avatar
darin committed
318
                                      withURL:(NSURL *)URL
ggaren's avatar
ggaren committed
319
                                     referrer:(const String&)referrer
darin's avatar
darin committed
320
                                 ownerElement:(HTMLFrameOwnerElement*)ownerElement
darin's avatar
darin committed
321 322 323
                              allowsScrolling:(BOOL)allowsScrolling 
                                  marginWidth:(int)width
                                 marginHeight:(int)height
darin's avatar
darin committed
324
{
mjs's avatar
mjs committed
325
    ASSERT(_frame);
darin's avatar
darin committed
326
    
mjs's avatar
mjs committed
327 328 329 330
    WebFrameView *childView = [[WebFrameView alloc] initWithFrame:NSMakeRect(0,0,0,0)];
    [childView setAllowsScrolling:allowsScrolling];
    [childView _setMarginWidth:width];
    [childView _setMarginHeight:height];
331

ggaren's avatar
ggaren committed
332 333
    WebFrameBridge *newBridge = [[WebFrameBridge alloc] initSubframeWithOwnerElement:ownerElement frameName:frameName frameView:childView];
    [childView release];
mjs's avatar
mjs committed
334 335

    if (!newBridge)
ggaren's avatar
ggaren committed
336 337 338 339
        return 0;

    [_frame _addChild:[newBridge webFrame]];
    [newBridge release];
340

ggaren's avatar
ggaren committed
341 342
    RefPtr<Frame> newFrame = [newBridge _frame];
    
lars's avatar
lars committed
343
    [_frame _loadURL:URL referrer:referrer intoChild:kit(newFrame.get())];
ggaren's avatar
ggaren committed
344 345 346 347

    // The frame's onload handler may have removed it from the document.
    if (!newFrame->tree()->parent())
        return 0;
darin's avatar
darin committed
348

ggaren's avatar
ggaren committed
349
    return newFrame.get();
darin's avatar
darin committed
350 351
}

352
- (NSView *)pluginViewWithPackage:(WebPluginPackage *)pluginPackage
cblu's avatar
cblu committed
353 354
                   attributeNames:(NSArray *)attributeNames
                  attributeValues:(NSArray *)attributeValues
355
                          baseURL:(NSURL *)baseURL
tomernic's avatar
tomernic committed
356
                       DOMElement:(DOMElement *)element
andersca's avatar
andersca committed
357
                     loadManually:(BOOL)loadManually
cblu's avatar
cblu committed
358
{
darin's avatar
WebKit:  
darin committed
359
    WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
360
    ASSERT([docView isKindOfClass:[WebHTMLView class]]);
361
        
362 363
    WebPluginController *pluginController = [docView _pluginController];
    
cblu's avatar
cblu committed
364
    // Store attributes in a dictionary so they can be passed to WebPlugins.
thatcher's avatar
thatcher committed
365
    NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
cblu's avatar
cblu committed
366
    
367 368 369
    [pluginPackage load];
    Class viewFactory = [pluginPackage viewFactory];
    
cblu's avatar
cblu committed
370
    NSView *view = nil;
371
    NSDictionary *arguments = nil;
372
    
373
    if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
374
        arguments = [NSDictionary dictionaryWithObjectsAndKeys:
375 376 377
            baseURL, WebPlugInBaseURLKey,
            attributes, WebPlugInAttributesKey,
            pluginController, WebPlugInContainerKey,
andersca's avatar
andersca committed
378 379
            [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
            [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
tomernic's avatar
tomernic committed
380
            element, WebPlugInContainingElementKey,
381 382
            nil];
        LOG(Plugins, "arguments:\n%@", arguments);
383
    } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
384
        arguments = [NSDictionary dictionaryWithObjectsAndKeys:
385 386 387
            baseURL, WebPluginBaseURLKey,
            attributes, WebPluginAttributesKey,
            pluginController, WebPluginContainerKey,
tomernic's avatar
tomernic committed
388
            element, WebPlugInContainingElementKey,
389 390
            nil];
        LOG(Plugins, "arguments:\n%@", arguments);
391
    }
thatcher's avatar
thatcher committed
392

393
    view = [WebPluginController plugInViewWithArguments:arguments fromPluginPackage:pluginPackage];
cblu's avatar
cblu committed
394
    [attributes release];
395
    return view;
cblu's avatar
cblu committed
396 397
}

cblu's avatar
cblu committed
398
- (NSString *)valueForKey:(NSString *)key keys:(NSArray *)keys values:(NSArray *)values
cblu's avatar
cblu committed
399
{
cblu's avatar
cblu committed
400 401
    unsigned count = [keys count];
    unsigned i;
402
    for (i = 0; i < count; i++)
mjs's avatar
mjs committed
403
        if ([[keys objectAtIndex:i] _webkit_isCaseInsensitiveEqualToString:key])
cblu's avatar
cblu committed
404 405 406 407
            return [values objectAtIndex:i];
    return nil;
}

andersca's avatar
andersca committed
408 409 410 411 412 413 414
- (NSView *)viewForPluginWithFrame:(NSRect)frame
                               URL:(NSURL *)URL
                    attributeNames:(NSArray *)attributeNames
                   attributeValues:(NSArray *)attributeValues
                          MIMEType:(NSString *)MIMEType
                        DOMElement:(DOMElement *)element
                      loadManually:(BOOL)loadManually
cblu's avatar
cblu committed
415 416
{
    ASSERT([attributeNames count] == [attributeValues count]);
cblu's avatar
cblu committed
417

cblu's avatar
cblu committed
418
    WebBasePluginPackage *pluginPackage = nil;
cblu's avatar
cblu committed
419 420
    NSView *view = nil;
    int errorCode = 0;
thatcher's avatar
thatcher committed
421

thatcher's avatar
thatcher committed
422 423
    WebView *webView = [self webView];
    SEL selector = @selector(webView:plugInViewWithArguments:);
thatcher's avatar
thatcher committed
424

thatcher's avatar
thatcher committed
425
    if ([[webView UIDelegate] respondsToSelector:selector]) {
thatcher's avatar
thatcher committed
426
        NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithObjects:attributeValues forKeys:attributeNames];
thatcher's avatar
thatcher committed
427
        NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
thatcher's avatar
thatcher committed
428
            attributes, WebPlugInAttributesKey,
andersca's avatar
andersca committed
429 430
            [NSNumber numberWithInt:loadManually ? WebPlugInModeFull : WebPlugInModeEmbed], WebPlugInModeKey,
            [NSNumber numberWithBool:!loadManually], WebPlugInShouldLoadMainResourceKey,
tomernic's avatar
tomernic committed
431
            element, WebPlugInContainingElementKey,
thatcher's avatar
thatcher committed
432
            URL, WebPlugInBaseURLKey, // URL might be nil, so add it last
thatcher's avatar
thatcher committed
433
            nil];
thatcher's avatar
thatcher committed
434 435 436

        view = CallUIDelegate(webView, selector, arguments);

thatcher's avatar
thatcher committed
437
        [attributes release];
thatcher's avatar
thatcher committed
438 439
        [arguments release];

thatcher's avatar
thatcher committed
440 441 442 443
        if (view)
            return view;
    }

mjs's avatar
mjs committed
444
    if ([MIMEType length] != 0)
tomernic's avatar
tomernic committed
445
        pluginPackage = [[self webView] _pluginForMIMEType:MIMEType];
mjs's avatar
mjs committed
446
    else
cblu's avatar
cblu committed
447
        MIMEType = nil;
cblu's avatar
cblu committed
448 449 450
    
    NSString *extension = [[URL path] pathExtension];
    if (!pluginPackage && [extension length] != 0) {
tomernic's avatar
tomernic committed
451
        pluginPackage = [[self webView] _pluginForExtension:extension];
cblu's avatar
cblu committed
452
        if (pluginPackage) {
453
            NSString *newMIMEType = [pluginPackage MIMETypeForExtension:extension];
mjs's avatar
mjs committed
454
            if ([newMIMEType length] != 0)
455
                MIMEType = newMIMEType;
cblu's avatar
cblu committed
456
        }
cblu's avatar
cblu committed
457 458
    }

cblu's avatar
cblu committed
459
    NSURL *baseURL = [self baseURL];
cblu's avatar
cblu committed
460
    if (pluginPackage) {
461
        if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
cblu's avatar
cblu committed
462
            view = [self pluginViewWithPackage:(WebPluginPackage *)pluginPackage
cblu's avatar
cblu committed
463 464
                                attributeNames:attributeNames
                               attributeValues:attributeValues
tomernic's avatar
tomernic committed
465
                                       baseURL:baseURL
andersca's avatar
andersca committed
466 467
                                    DOMElement:element
                                  loadManually:loadManually];
kdecker's avatar
kdecker committed
468 469 470 471
            
        }
#ifndef __LP64__
        else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
andersca's avatar
andersca committed
472
            WebNetscapePluginEmbeddedView *embeddedView = [[[WebNetscapePluginEmbeddedView alloc] initWithFrame:frame
473
                                                           pluginPackage:(WebNetscapePluginPackage *)pluginPackage
cblu's avatar
cblu committed
474 475
                                                                     URL:URL
                                                                 baseURL:baseURL
cblu's avatar
cblu committed
476
                                                                MIMEType:MIMEType
cblu's avatar
cblu committed
477
                                                           attributeKeys:attributeNames
andersca's avatar
andersca committed
478
                                                         attributeValues:attributeValues
tomernic's avatar
tomernic committed
479 480
                                                            loadManually:loadManually
                                                              DOMElement:element] autorelease];
mjs's avatar
mjs committed
481
            view = embeddedView;
kdecker's avatar
kdecker committed
482 483
        } 
#endif
mjs's avatar
mjs committed
484
    } else
rjw's avatar
rjw committed
485
        errorCode = WebKitErrorCannotFindPlugIn;
cblu's avatar
cblu committed
486

mjs's avatar
mjs committed
487
    if (!errorCode && !view)
rjw's avatar
rjw committed
488
        errorCode = WebKitErrorCannotLoadPlugIn;
cblu's avatar
cblu committed
489

490
    if (errorCode) {
cblu's avatar
cblu committed
491 492
        NSString *pluginPage = [self valueForKey:@"pluginspage" keys:attributeNames values:attributeValues];
        NSURL *pluginPageURL = pluginPage != nil ? [self URLWithAttributeString:pluginPage] : nil;
cblu's avatar
WebKit:  
cblu committed
493
        NSError *error = [[NSError alloc] _initWithPluginErrorCode:errorCode
darin's avatar
darin committed
494
                                                        contentURL:URL
cblu's avatar
cblu committed
495
                                                     pluginPageURL:pluginPageURL
cblu's avatar
WebKit:  
cblu committed
496 497
                                                        pluginName:[pluginPackage name]
                                                          MIMEType:MIMEType];
andersca's avatar
andersca committed
498
        WebNullPluginView *nullView = [[[WebNullPluginView alloc] initWithFrame:frame error:error DOMElement:element] autorelease];
mjs's avatar
mjs committed
499
        view = nullView;
cblu's avatar
WebKit:  
cblu committed
500
        [error release];
cblu's avatar
cblu committed
501 502
    }
    
cblu's avatar
cblu committed
503
    ASSERT(view);
cblu's avatar
cblu committed
504
    return view;
cblu's avatar
cblu committed
505 506
}

andersca's avatar
andersca committed
507 508
- (void)redirectDataToPlugin:(NSView *)pluginView
{
mjs's avatar
mjs committed
509
    WebHTMLRepresentation *representation = (WebHTMLRepresentation *)[[_frame _dataSource] representation];
andersca's avatar
andersca committed
510

kdecker's avatar
kdecker committed
511
#ifndef __LP64__
andersca's avatar
andersca committed
512 513 514
    if ([pluginView isKindOfClass:[WebNetscapePluginEmbeddedView class]])
        [representation _redirectDataToManualLoader:(WebNetscapePluginEmbeddedView *)pluginView forPluginView:pluginView];
    else {
kdecker's avatar
kdecker committed
515 516 517
#else
    {
#endif
andersca's avatar
andersca committed
518 519 520 521 522 523
        WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
        ASSERT([docView isKindOfClass:[WebHTMLView class]]);
        
        WebPluginController *pluginController = [docView _pluginController];
        [representation _redirectDataToManualLoader:pluginController forPluginView:pluginView];
    }
kdecker's avatar
kdecker committed
524

andersca's avatar
andersca committed
525 526
}

cblu's avatar
cblu committed
527
- (NSView *)viewForJavaAppletWithFrame:(NSRect)theFrame
cblu's avatar
cblu committed
528 529
                        attributeNames:(NSArray *)attributeNames
                       attributeValues:(NSArray *)attributeValues
tomernic's avatar
tomernic committed
530 531
                               baseURL:(NSURL *)baseURL
                            DOMElement:(DOMElement *)element
cblu's avatar
cblu committed
532
{
cblu's avatar
cblu committed
533
    NSString *MIMEType = @"application/x-java-applet";
cblu's avatar
cblu committed
534
    WebBasePluginPackage *pluginPackage;
cblu's avatar
cblu committed
535 536
    NSView *view = nil;
    
tomernic's avatar
tomernic committed
537
    pluginPackage = [[self webView] _pluginForMIMEType:MIMEType];
cblu's avatar
cblu committed
538

cblu's avatar
cblu committed
539
    if (pluginPackage) {
540
        if ([pluginPackage isKindOfClass:[WebPluginPackage class]]) {
cblu's avatar
cblu committed
541 542 543 544 545 546 547 548 549 550 551
            // For some reason, the Java plug-in requires that we pass the dimension of the plug-in as attributes.
            NSMutableArray *names = [attributeNames mutableCopy];
            NSMutableArray *values = [attributeValues mutableCopy];
            if ([self valueForKey:@"width" keys:attributeNames values:attributeValues] == nil) {
                [names addObject:@"width"];
                [values addObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.width]];
            }
            if ([self valueForKey:@"height" keys:attributeNames values:attributeValues] == nil) {
                [names addObject:@"height"];
                [values addObject:[NSString stringWithFormat:@"%d", (int)theFrame.size.height]];
            }
cblu's avatar
cblu committed
552
            view = [self pluginViewWithPackage:(WebPluginPackage *)pluginPackage
cblu's avatar
cblu committed
553 554
                                attributeNames:names
                               attributeValues:values
tomernic's avatar
tomernic committed
555
                                       baseURL:baseURL
andersca's avatar
andersca committed
556 557
                                    DOMElement:element
                                  loadManually:NO];
cblu's avatar
cblu committed
558 559
            [names release];
            [values release];
kdecker's avatar
kdecker committed
560 561 562 563
            
        } 
#ifndef __LP64__
        else if ([pluginPackage isKindOfClass:[WebNetscapePluginPackage class]]) {
cblu's avatar
cblu committed
564
            view = [[[WebNetscapePluginEmbeddedView alloc] initWithFrame:theFrame
565
                                                           pluginPackage:(WebNetscapePluginPackage *)pluginPackage
cblu's avatar
cblu committed
566
                                                                     URL:nil
cblu's avatar
cblu committed
567
                                                                 baseURL:baseURL
cblu's avatar
cblu committed
568
                                                                MIMEType:MIMEType
cblu's avatar
cblu committed
569
                                                           attributeKeys:attributeNames
andersca's avatar
andersca committed
570
                                                         attributeValues:attributeValues
tomernic's avatar
tomernic committed
571 572
                                                            loadManually:NO
                                                              DOMElement:element] autorelease];
573
        } else {
cblu's avatar
cblu committed
574
            ASSERT_NOT_REACHED();
cblu's avatar
cblu committed
575
        }
kdecker's avatar
kdecker committed
576
#endif
cblu's avatar
cblu committed
577 578
    }

579
    if (!view) {
cblu's avatar
WebKit:  
cblu committed
580
        NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorJavaUnavailable
kocienda's avatar
kocienda committed
581 582
                                                        contentURL:nil
                                                     pluginPageURL:nil
cblu's avatar
WebKit:  
cblu committed
583 584
                                                        pluginName:[pluginPackage name]
                                                          MIMEType:MIMEType];
ggaren's avatar
ggaren committed
585
        view = [[[WebNullPluginView alloc] initWithFrame:theFrame error:error DOMElement:element] autorelease];
cblu's avatar
WebKit:  
cblu committed
586
        [error release];
cblu's avatar
cblu committed
587
    }
cblu's avatar
cblu committed
588 589 590 591

    ASSERT(view);

    return view;
cblu's avatar
cblu committed
592 593
}

andersca's avatar
andersca committed
594
- (ObjectContentType)determineObjectFromMIMEType:(NSString*)MIMEType URL:(NSURL*)URL
cblu's avatar
cblu committed
595
{
kdecker's avatar
kdecker committed
596 597 598 599 600 601
    // This is a quirk that ensures Tiger Mail's WebKit plug-in will load during layout
    // and not attach time. (5520541)
    static BOOL isTigerMail = WKAppVersionCheckLessThan(@"com.apple.mail", -1, 3.0);
    if (isTigerMail && [MIMEType isEqualToString:@"application/x-apple-msg-attachment"])
        return ObjectContentNetscapePlugin;
    
602
    if ([MIMEType length] == 0) {
603
        // Try to guess the MIME type based off the extension.
cblu's avatar
cblu committed
604
        NSString *extension = [[URL path] pathExtension];
605
        if ([extension length] > 0) {
mjs's avatar
mjs committed
606
            MIMEType = WKGetMIMETypeForExtension(extension);
andersca's avatar
andersca committed
607
            if ([MIMEType length] == 0) {
608
                // If no MIME type is specified, use a plug-in if we have one that can handle the extension.
andersca's avatar
andersca committed
609
                if (WebBasePluginPackage *package = [[self webView] _pluginForExtension:extension]) {
andersca's avatar
andersca committed
610
                    if ([package isKindOfClass:[WebPluginPackage class]]) 
andersca's avatar
andersca committed
611
                        return ObjectContentOtherPlugin;
andersca's avatar
andersca committed
612 613 614 615
#ifndef __LP64__
                    else {
                        ASSERT([package isKindOfClass:[WebNetscapePluginPackage class]]);
                        return ObjectContentNetscapePlugin;
andersca's avatar
andersca committed
616
                    }
andersca's avatar
andersca committed
617
#endif
andersca's avatar
andersca committed
618 619
                }
            }
cblu's avatar
cblu committed
620
        }
621
    }
622 623

    if ([MIMEType length] == 0)
andersca's avatar
andersca committed
624
        return ObjectContentFrame; // Go ahead and hope that we can display the content.
andersca's avatar
andersca committed
625

weinig's avatar
weinig committed
626
    if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType))
andersca's avatar
andersca committed
627 628 629
        return ObjectContentImage;

    if (WebBasePluginPackage *package = [[self webView] _pluginForMIMEType:MIMEType]) {
andersca's avatar
andersca committed
630
        if ([package isKindOfClass:[WebPluginPackage class]]) 
andersca's avatar
andersca committed
631
            return ObjectContentOtherPlugin;
andersca's avatar
andersca committed
632 633 634 635
#ifndef __LP64__
        else {
            ASSERT([package isKindOfClass:[WebNetscapePluginPackage class]]);
            return ObjectContentNetscapePlugin;
andersca's avatar
andersca committed
636
        }
andersca's avatar
andersca committed
637
#endif
andersca's avatar
andersca committed
638
    }
andersca's avatar
andersca committed
639 640

    if ([WebFrameView _viewClassForMIMEType:MIMEType])
andersca's avatar
andersca committed
641
        return ObjectContentFrame;
andersca's avatar
andersca committed
642
    
andersca's avatar
andersca committed
643
    return ObjectContentNone;
cblu's avatar
cblu committed
644 645
}

rjw's avatar
WebKit:  
rjw committed
646 647
- (jobject)getAppletInView:(NSView *)view
{
darin's avatar
darin committed
648
    if ([view respondsToSelector:@selector(webPlugInGetApplet)])
649 650
        return [view webPlugInGetApplet];
    return [self pollForAppletInView:view];
rjw's avatar
WebKit:  
rjw committed
651 652
}

rjw's avatar
WebKit:  
rjw committed
653
// NOTE: pollForAppletInView: will block until the block is ready to use, or
654
// until a timeout is exceeded.  It will return nil if the timeout is
rjw's avatar
WebKit:  
rjw committed
655
// exceeded.
rjw's avatar
WebKit:  
rjw committed
656
// Deprecated, use getAppletInView:.
darin's avatar
darin committed
657
- (jobject)pollForAppletInView:(NSView *)view
rjw's avatar
WebKit:  
rjw committed
658
{
659
    if ([view respondsToSelector:@selector(pollForAppletInWindow:)])
rjw's avatar
WebKit:  
rjw committed
660
        // The Java VM needs the containing window of the view to
661
        // initialize. The view may not yet be in the window's view 
rjw's avatar
WebKit:  
rjw committed
662 663
        // hierarchy, so we have to pass the window when requesting
        // the applet.
664 665
        return [view pollForAppletInWindow:[[self webView] window]];
    return 0;
rjw's avatar
WebKit:  
rjw committed
666 667
}

kocienda's avatar
kocienda committed
668
- (void)respondToChangedContents
kocienda's avatar
kocienda committed
669
{
darin's avatar
darin committed
670
    NSView <WebDocumentView> *view = [[_frame frameView] documentView];
671
    if ([view isKindOfClass:[WebHTMLView class]])
darin's avatar
darin committed
672
        [(WebHTMLView *)view _updateFontPanel];
darin's avatar
darin committed
673
    [[NSNotificationCenter defaultCenter] postNotificationName:WebViewDidChangeNotification object:[self webView]];
kocienda's avatar
kocienda committed
674 675
}

darin's avatar
darin committed
676
- (NSUndoManager *)undoManager
kocienda's avatar
kocienda committed
677
{
darin's avatar
darin committed
678
    return [[self webView] undoManager];
kocienda's avatar
kocienda committed
679
}
rjw's avatar
WebKit:  
rjw committed
680

kocienda's avatar
kocienda committed
681 682
- (void)issuePasteCommand
{
justing's avatar
justing committed
683 684 685
    NSView* documentView = [[_frame frameView] documentView];
    if ([documentView isKindOfClass:[WebHTMLView class]])
        [(WebHTMLView*)documentView paste:nil];
kocienda's avatar
kocienda committed
686 687
}

cblu's avatar
Tests:  
cblu committed
688 689
- (void)setIsSelected:(BOOL)isSelected forView:(NSView *)view
{
690
    if ([view respondsToSelector:@selector(webPlugInSetIsSelected:)])
rjw's avatar
WebKit:  
rjw committed
691
        [view webPlugInSetIsSelected:isSelected];
692
    else if ([view respondsToSelector:@selector(setIsSelected:)])
rjw's avatar
WebKit:  
rjw committed
693
        [view setIsSelected:isSelected];
cblu's avatar
Tests:  
cblu committed
694 695
}

rjw's avatar
WebKit:  
rjw committed
696 697
- (void)windowObjectCleared
{
ggaren's avatar
ggaren committed
698
    WebView *webView = getWebView(_frame);
timothy@apple.com's avatar
timothy@apple.com committed
699 700 701 702 703
    WebFrameLoadDelegateImplementationCache* implementations = WebViewGetFrameLoadDelegateImplementations(webView);
    if (implementations->didClearWindowObjectForFrameFunc)
        CallFrameLoadDelegate(implementations->didClearWindowObjectForFrameFunc, webView, @selector(webView:didClearWindowObject:forFrame:), m_frame->windowScriptObject(), _frame);
    else if (implementations->windowScriptObjectAvailableFunc)
        CallFrameLoadDelegate(implementations->windowScriptObjectAvailableFunc, webView, @selector(webView:windowScriptObjectAvailable:), m_frame->windowScriptObject());
ggaren's avatar
ggaren committed
704

ggaren's avatar
ggaren committed
705 706
    if ([webView scriptDebugDelegate] || [WebScriptDebugServer listenerCount]) {
        [_frame _detachScriptDebugger];
mjs's avatar
mjs committed
707
        [_frame _attachScriptDebugger];
thatcher's avatar
thatcher committed
708
    }
rjw's avatar
WebKit:  
rjw committed
709 710
}

rjw's avatar
rjw committed
711 712 713 714 715
- (BOOL)_compareDashboardRegions:(NSDictionary *)regions
{
    return [lastDashboardRegions isEqualToDictionary:regions];
}

rjw's avatar
rjw committed
716
- (void)dashboardRegionsChanged:(NSMutableDictionary *)regions
rjw's avatar
rjw committed
717
{
thatcher's avatar
thatcher committed
718 719 720
    WebView *webView = [self webView];
    [webView _addScrollerDashboardRegions:regions];

rjw's avatar
rjw committed
721
    if (![self _compareDashboardRegions:regions]) {
thatcher's avatar
thatcher committed
722 723 724 725
        CallUIDelegate(webView, @selector(webView:dashboardRegionsChanged:), regions);

        [lastDashboardRegions release];
        lastDashboardRegions = [regions retain];
rjw's avatar
rjw committed
726
    }
rjw's avatar
rjw committed
727 728
}

adele's avatar
adele committed
729 730
- (void)willPopupMenu:(NSMenu *)menu
{
thatcher's avatar
thatcher committed
731
    CallUIDelegate([self webView], @selector(webView:willPopupMenu:), menu);
adele's avatar
adele committed
732 733
}

thatcher's avatar
thatcher committed
734
- (NSRect)customHighlightRect:(NSString*)type forLine:(NSRect)lineRect representedNode:(WebCore::Node *)node
hyatt's avatar
hyatt committed
735 736 737 738 739 740 741 742
{
    ASSERT(_frame != nil);
    NSView *documentView = [[_frame frameView] documentView];
    if (![documentView isKindOfClass:[WebHTMLView class]])
        return NSZeroRect;

    WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
    id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
thatcher's avatar
thatcher committed
743 744
    if ([(NSObject *)highlighter respondsToSelector:@selector(highlightRectForLine:representedNode:)])
        return [highlighter highlightRectForLine:lineRect representedNode:kit(node)];
hyatt's avatar
hyatt committed
745 746 747
    return [highlighter highlightRectForLine:lineRect];
}

thatcher's avatar
thatcher committed
748
- (void)paintCustomHighlight:(NSString*)type forBox:(NSRect)boxRect onLine:(NSRect)lineRect behindText:(BOOL)text entireLine:(BOOL)line representedNode:(WebCore::Node *)node
749 750 751 752 753 754 755 756
{
    ASSERT(_frame != nil);
    NSView *documentView = [[_frame frameView] documentView];
    if (![documentView isKindOfClass:[WebHTMLView class]])
        return;

    WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
    id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
thatcher's avatar
thatcher committed
757 758 759 760
    if ([(NSObject *)highlighter respondsToSelector:@selector(paintHighlightForBox:onLine:behindText:entireLine:representedNode:)])
        [highlighter paintHighlightForBox:boxRect onLine:lineRect behindText:text entireLine:line representedNode:kit(node)];
    else
        [highlighter paintHighlightForBox:boxRect onLine:lineRect behindText:text entireLine:line];
761 762
}

andersca's avatar
andersca committed
763 764
- (NSString*)imageTitleForFilename:(NSString*)filename size:(NSSize)size
{
765
    return [NSString stringWithFormat:UI_STRING("%@ %.0f×%.0f pixels", "window title for a standalone image (uses multiplication symbol, not x)"), filename, size.width, size.height];
andersca's avatar
andersca committed
766 767
}

darin's avatar
darin committed
768
@end