~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebKit/mac/WebCoreSupport/WebChromeClient.mm

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
 
3
 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *
 
9
 * 1.  Redistributions of source code must retain the above copyright
 
10
 *     notice, this list of conditions and the following disclaimer. 
 
11
 * 2.  Redistributions in binary form must reproduce the above copyright
 
12
 *     notice, this list of conditions and the following disclaimer in the
 
13
 *     documentation and/or other materials provided with the distribution. 
 
14
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 
15
 *     its contributors may be used to endorse or promote products derived
 
16
 *     from this software without specific prior written permission. 
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 
19
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
20
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
21
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 
22
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
23
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
25
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
28
 */
 
29
 
 
30
#import "WebChromeClient.h"
 
31
 
 
32
#import "DOMElementInternal.h"
 
33
#import "DOMNodeInternal.h"
 
34
#import "WebBasePluginPackage.h"
 
35
#import "WebDefaultUIDelegate.h"
 
36
#import "WebDelegateImplementationCaching.h"
 
37
#import "WebElementDictionary.h"
 
38
#import "WebFrameInternal.h"
 
39
#import "WebFrameView.h"
 
40
#import "WebHTMLViewInternal.h"
 
41
#import "WebHistoryInternal.h"
 
42
#import "WebKitFullScreenListener.h"
 
43
#import "WebKitPrefix.h"
 
44
#import "WebKitSystemInterface.h"
 
45
#import "WebNSURLRequestExtras.h"
 
46
#import "WebOpenPanelResultListener.h"
 
47
#import "WebPlugin.h"
 
48
#import "WebQuotaManager.h"
 
49
#import "WebSecurityOriginInternal.h"
 
50
#import "WebUIDelegatePrivate.h"
 
51
#import "WebView.h"
 
52
#import "WebViewInternal.h"
 
53
#import <Foundation/Foundation.h>
 
54
#import <WebCore/BlockExceptions.h>
 
55
#import <WebCore/Console.h>
 
56
#import <WebCore/ContextMenu.h>
 
57
#import <WebCore/ContextMenuController.h>
 
58
#import <WebCore/Cursor.h>
 
59
#import <WebCore/Element.h>
 
60
#import <WebCore/FileChooser.h>
 
61
#import <WebCore/FileIconLoader.h>
 
62
#import <WebCore/FloatRect.h>
 
63
#import <WebCore/Frame.h>
 
64
#import <WebCore/FrameLoadRequest.h>
 
65
#import <WebCore/FrameView.h>
 
66
#import <WebCore/HTMLNames.h>
 
67
#import <WebCore/HTMLPlugInImageElement.h>
 
68
#import <WebCore/HitTestResult.h>
 
69
#import <WebCore/Icon.h>
 
70
#import <WebCore/IntPoint.h>
 
71
#import <WebCore/IntRect.h>
 
72
#import <WebCore/NavigationAction.h>
 
73
#import <WebCore/NotImplemented.h>
 
74
#import <WebCore/Page.h>
 
75
#import <WebCore/PlatformScreen.h>
 
76
#import <WebCore/PopupMenuMac.h>
 
77
#import <WebCore/ResourceRequest.h>
 
78
#import <WebCore/SearchPopupMenuMac.h>
 
79
#import <WebCore/Widget.h>
 
80
#import <WebCore/WindowFeatures.h>
 
81
#import <wtf/PassRefPtr.h>
 
82
#import <wtf/Vector.h>
 
83
#import <wtf/text/WTFString.h>
 
84
 
 
85
#if USE(ACCELERATED_COMPOSITING)
 
86
#import <WebCore/GraphicsLayer.h>
 
87
#endif
 
88
 
 
89
#if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
 
90
#import "NetscapePluginHostManager.h"
 
91
#endif
 
92
 
 
93
NSString *WebConsoleMessageHTMLMessageSource = @"HTMLMessageSource";
 
94
NSString *WebConsoleMessageXMLMessageSource = @"XMLMessageSource";
 
95
NSString *WebConsoleMessageJSMessageSource = @"JSMessageSource";
 
96
NSString *WebConsoleMessageNetworkMessageSource = @"NetworkMessageSource";
 
97
NSString *WebConsoleMessageConsoleAPIMessageSource = @"ConsoleAPIMessageSource";
 
98
NSString *WebConsoleMessageOtherMessageSource = @"OtherMessageSource";
 
99
 
 
100
NSString *WebConsoleMessageLogMessageType = @"LogMessageType";
 
101
NSString *WebConsoleMessageDirMessageType = @"DirMessageType";
 
102
NSString *WebConsoleMessageClearMessageType = @"ClearMessageType";
 
103
NSString *WebConsoleMessageDirXMLMessageType = @"DirXMLMessageType";
 
104
NSString *WebConsoleMessageTraceMessageType = @"TraceMessageType";
 
105
NSString *WebConsoleMessageStartGroupMessageType = @"StartGroupMessageType";
 
106
NSString *WebConsoleMessageStartGroupCollapsedMessageType = @"StartGroupCollapsedMessageType";
 
107
NSString *WebConsoleMessageEndGroupMessageType = @"EndGroupMessageType";
 
108
NSString *WebConsoleMessageAssertMessageType = @"AssertMessageType";
 
109
 
 
110
NSString *WebConsoleMessageTipMessageLevel = @"TipMessageLevel";
 
111
NSString *WebConsoleMessageLogMessageLevel = @"LogMessageLevel";
 
112
NSString *WebConsoleMessageWarningMessageLevel = @"WarningMessageLevel";
 
113
NSString *WebConsoleMessageErrorMessageLevel = @"ErrorMessageLevel";
 
114
NSString *WebConsoleMessageDebugMessageLevel = @"DebugMessageLevel";
 
115
 
 
116
@interface NSApplication (WebNSApplicationDetails)
 
117
- (NSCursor *)_cursorRectCursor;
 
118
@end
 
119
 
 
120
@interface NSView (WebNSViewDetails)
 
121
- (NSView *)_findLastViewInKeyViewLoop;
 
122
@end
 
123
 
 
124
// For compatibility with old SPI.
 
125
@interface NSView (WebOldWebKitPlugInDetails)
 
126
- (void)setIsSelected:(BOOL)isSelected;
 
127
@end
 
128
 
 
129
@interface NSWindow (AppKitSecretsIKnowAbout)
 
130
- (NSRect)_growBoxRect;
 
131
@end
 
132
 
 
133
using namespace WebCore;
 
134
using namespace HTMLNames;
 
135
 
 
136
WebChromeClient::WebChromeClient(WebView *webView) 
 
137
    : m_webView(webView)
 
138
{
 
139
}
 
140
 
 
141
void WebChromeClient::chromeDestroyed()
 
142
{
 
143
    delete this;
 
144
}
 
145
 
 
146
// These functions scale between window and WebView coordinates because JavaScript/DOM operations 
 
147
// assume that the WebView and the window share the same coordinate system.
 
148
 
 
149
void WebChromeClient::setWindowRect(const FloatRect& rect)
 
150
{
 
151
    NSRect windowRect = toDeviceSpace(rect, [m_webView window]);
 
152
    [[m_webView _UIDelegateForwarder] webView:m_webView setFrame:windowRect];
 
153
}
 
154
 
 
155
FloatRect WebChromeClient::windowRect()
 
156
{
 
157
    NSRect windowRect = [[m_webView _UIDelegateForwarder] webViewFrame:m_webView];
 
158
    return toUserSpace(windowRect, [m_webView window]);
 
159
}
 
160
 
 
161
// FIXME: We need to add API for setting and getting this.
 
162
FloatRect WebChromeClient::pageRect()
 
163
{
 
164
    return [m_webView frame];
 
165
}
 
166
 
 
167
void WebChromeClient::focus()
 
168
{
 
169
    [[m_webView _UIDelegateForwarder] webViewFocus:m_webView];
 
170
}
 
171
 
 
172
void WebChromeClient::unfocus()
 
173
{
 
174
    [[m_webView _UIDelegateForwarder] webViewUnfocus:m_webView];
 
175
}
 
176
 
 
177
bool WebChromeClient::canTakeFocus(FocusDirection)
 
178
{
 
179
    // There's unfortunately no way to determine if we will become first responder again
 
180
    // once we give it up, so we just have to guess that we won't.
 
181
    return true;
 
182
}
 
183
 
 
184
void WebChromeClient::takeFocus(FocusDirection direction)
 
185
{
 
186
    if (direction == FocusDirectionForward) {
 
187
        // Since we're trying to move focus out of m_webView, and because
 
188
        // m_webView may contain subviews within it, we ask it for the next key
 
189
        // view of the last view in its key view loop. This makes m_webView
 
190
        // behave as if it had no subviews, which is the behavior we want.
 
191
        NSView *lastView = [m_webView _findLastViewInKeyViewLoop];
 
192
        // avoid triggering assertions if the WebView is the only thing in the key loop
 
193
        if ([m_webView _becomingFirstResponderFromOutside] && m_webView == [lastView nextValidKeyView])
 
194
            return;
 
195
        [[m_webView window] selectKeyViewFollowingView:lastView];
 
196
    } else {
 
197
        // avoid triggering assertions if the WebView is the only thing in the key loop
 
198
        if ([m_webView _becomingFirstResponderFromOutside] && m_webView == [m_webView previousValidKeyView])
 
199
            return;
 
200
        [[m_webView window] selectKeyViewPrecedingView:m_webView];
 
201
    }
 
202
}
 
203
 
 
204
void WebChromeClient::focusedNodeChanged(Node*)
 
205
{
 
206
}
 
207
 
 
208
void WebChromeClient::focusedFrameChanged(Frame*)
 
209
{
 
210
}
 
211
 
 
212
Page* WebChromeClient::createWindow(Frame* frame, const FrameLoadRequest&, const WindowFeatures& features, const NavigationAction&)
 
213
{
 
214
    id delegate = [m_webView UIDelegate];
 
215
    WebView *newWebView;
 
216
    
 
217
    if ([delegate respondsToSelector:@selector(webView:createWebViewWithRequest:windowFeatures:)]) {
 
218
        NSNumber *x = features.xSet ? [[NSNumber alloc] initWithFloat:features.x] : nil;
 
219
        NSNumber *y = features.ySet ? [[NSNumber alloc] initWithFloat:features.y] : nil;
 
220
        NSNumber *width = features.widthSet ? [[NSNumber alloc] initWithFloat:features.width] : nil;
 
221
        NSNumber *height = features.heightSet ? [[NSNumber alloc] initWithFloat:features.height] : nil;
 
222
        NSNumber *menuBarVisible = [[NSNumber alloc] initWithBool:features.menuBarVisible];
 
223
        NSNumber *statusBarVisible = [[NSNumber alloc] initWithBool:features.statusBarVisible];
 
224
        NSNumber *toolBarVisible = [[NSNumber alloc] initWithBool:features.toolBarVisible];
 
225
        NSNumber *scrollbarsVisible = [[NSNumber alloc] initWithBool:features.scrollbarsVisible];
 
226
        NSNumber *resizable = [[NSNumber alloc] initWithBool:features.resizable];
 
227
        NSNumber *fullscreen = [[NSNumber alloc] initWithBool:features.fullscreen];
 
228
        NSNumber *dialog = [[NSNumber alloc] initWithBool:features.dialog];
 
229
        
 
230
        NSMutableDictionary *dictFeatures = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
 
231
                                             menuBarVisible, @"menuBarVisible", 
 
232
                                             statusBarVisible, @"statusBarVisible",
 
233
                                             toolBarVisible, @"toolBarVisible",
 
234
                                             scrollbarsVisible, @"scrollbarsVisible",
 
235
                                             resizable, @"resizable",
 
236
                                             fullscreen, @"fullscreen",
 
237
                                             dialog, @"dialog",
 
238
                                             nil];
 
239
        
 
240
        if (x)
 
241
            [dictFeatures setObject:x forKey:@"x"];
 
242
        if (y)
 
243
            [dictFeatures setObject:y forKey:@"y"];
 
244
        if (width)
 
245
            [dictFeatures setObject:width forKey:@"width"];
 
246
        if (height)
 
247
            [dictFeatures setObject:height forKey:@"height"];
 
248
        
 
249
        newWebView = CallUIDelegate(m_webView, @selector(webView:createWebViewWithRequest:windowFeatures:), nil, dictFeatures);
 
250
        
 
251
        [dictFeatures release];
 
252
        [x release];
 
253
        [y release];
 
254
        [width release];
 
255
        [height release];
 
256
        [menuBarVisible release];
 
257
        [statusBarVisible release];
 
258
        [toolBarVisible release];
 
259
        [scrollbarsVisible release];
 
260
        [resizable release];
 
261
        [fullscreen release];
 
262
        [dialog release];
 
263
    } else if (features.dialog && [delegate respondsToSelector:@selector(webView:createWebViewModalDialogWithRequest:)]) {
 
264
        newWebView = CallUIDelegate(m_webView, @selector(webView:createWebViewModalDialogWithRequest:), nil);
 
265
    } else {
 
266
        newWebView = CallUIDelegate(m_webView, @selector(webView:createWebViewWithRequest:), nil);
 
267
    }
 
268
 
 
269
#if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
 
270
    if (newWebView)
 
271
        WebKit::NetscapePluginHostManager::shared().didCreateWindow();
 
272
#endif
 
273
    
 
274
    return core(newWebView);
 
275
}
 
276
 
 
277
void WebChromeClient::show()
 
278
{
 
279
    [[m_webView _UIDelegateForwarder] webViewShow:m_webView];
 
280
}
 
281
 
 
282
bool WebChromeClient::canRunModal()
 
283
{
 
284
    return [[m_webView UIDelegate] respondsToSelector:@selector(webViewRunModal:)];
 
285
}
 
286
 
 
287
void WebChromeClient::runModal()
 
288
{
 
289
    CallUIDelegate(m_webView, @selector(webViewRunModal:));
 
290
}
 
291
 
 
292
void WebChromeClient::setToolbarsVisible(bool b)
 
293
{
 
294
    [[m_webView _UIDelegateForwarder] webView:m_webView setToolbarsVisible:b];
 
295
}
 
296
 
 
297
bool WebChromeClient::toolbarsVisible()
 
298
{
 
299
    return CallUIDelegateReturningBoolean(NO, m_webView, @selector(webViewAreToolbarsVisible:));
 
300
}
 
301
 
 
302
void WebChromeClient::setStatusbarVisible(bool b)
 
303
{
 
304
    [[m_webView _UIDelegateForwarder] webView:m_webView setStatusBarVisible:b];
 
305
}
 
306
 
 
307
bool WebChromeClient::statusbarVisible()
 
308
{
 
309
    return CallUIDelegateReturningBoolean(NO, m_webView, @selector(webViewIsStatusBarVisible:));
 
310
}
 
311
 
 
312
void WebChromeClient::setScrollbarsVisible(bool b)
 
313
{
 
314
    [[[m_webView mainFrame] frameView] setAllowsScrolling:b];
 
315
}
 
316
 
 
317
bool WebChromeClient::scrollbarsVisible()
 
318
{
 
319
    return [[[m_webView mainFrame] frameView] allowsScrolling];
 
320
}
 
321
 
 
322
void WebChromeClient::setMenubarVisible(bool)
 
323
{
 
324
    // The menubar is always visible in Mac OS X.
 
325
    return;
 
326
}
 
327
 
 
328
bool WebChromeClient::menubarVisible()
 
329
{
 
330
    // The menubar is always visible in Mac OS X.
 
331
    return true;
 
332
}
 
333
 
 
334
void WebChromeClient::setResizable(bool b)
 
335
{
 
336
    [[m_webView _UIDelegateForwarder] webView:m_webView setResizable:b];
 
337
}
 
338
 
 
339
inline static NSString *stringForMessageSource(MessageSource source)
 
340
{
 
341
    switch (source) {
 
342
    case HTMLMessageSource:
 
343
        return WebConsoleMessageHTMLMessageSource;
 
344
    case XMLMessageSource:
 
345
        return WebConsoleMessageXMLMessageSource;
 
346
    case JSMessageSource:
 
347
        return WebConsoleMessageJSMessageSource;
 
348
    case NetworkMessageSource:
 
349
        return WebConsoleMessageNetworkMessageSource;
 
350
    case ConsoleAPIMessageSource:
 
351
        return WebConsoleMessageConsoleAPIMessageSource;
 
352
    case OtherMessageSource:
 
353
        return WebConsoleMessageOtherMessageSource;
 
354
    }
 
355
    ASSERT_NOT_REACHED();
 
356
    return @"";
 
357
}
 
358
 
 
359
inline static NSString *stringForMessageType(MessageType type)
 
360
{
 
361
    switch (type) {
 
362
    case LogMessageType:
 
363
        return WebConsoleMessageLogMessageType;
 
364
    case ClearMessageType:
 
365
        return WebConsoleMessageClearMessageType;
 
366
    case DirMessageType:
 
367
        return WebConsoleMessageDirMessageType;
 
368
    case DirXMLMessageType:
 
369
        return WebConsoleMessageDirXMLMessageType;
 
370
    case TraceMessageType:
 
371
        return WebConsoleMessageTraceMessageType;
 
372
    case StartGroupMessageType:
 
373
        return WebConsoleMessageStartGroupMessageType;
 
374
    case StartGroupCollapsedMessageType:
 
375
        return WebConsoleMessageStartGroupCollapsedMessageType;
 
376
    case EndGroupMessageType:
 
377
        return WebConsoleMessageEndGroupMessageType;
 
378
    case AssertMessageType:
 
379
        return WebConsoleMessageAssertMessageType;
 
380
    }
 
381
    ASSERT_NOT_REACHED();
 
382
    return @"";
 
383
}
 
384
 
 
385
inline static NSString *stringForMessageLevel(MessageLevel level)
 
386
{
 
387
    switch (level) {
 
388
    case TipMessageLevel:
 
389
        return WebConsoleMessageTipMessageLevel;
 
390
    case LogMessageLevel:
 
391
        return WebConsoleMessageLogMessageLevel;
 
392
    case WarningMessageLevel:
 
393
        return WebConsoleMessageWarningMessageLevel;
 
394
    case ErrorMessageLevel:
 
395
        return WebConsoleMessageErrorMessageLevel;
 
396
    case DebugMessageLevel:
 
397
        return WebConsoleMessageDebugMessageLevel;
 
398
    }
 
399
    ASSERT_NOT_REACHED();
 
400
    return @"";
 
401
}
 
402
 
 
403
void WebChromeClient::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned int lineNumber, const String& sourceURL)
 
404
{
 
405
    id delegate = [m_webView UIDelegate];
 
406
    BOOL respondsToNewSelector = NO;
 
407
 
 
408
    SEL selector = @selector(webView:addMessageToConsole:withSource:);
 
409
    if ([delegate respondsToSelector:selector])
 
410
        respondsToNewSelector = YES;
 
411
    else {
 
412
        // The old selector only takes JSMessageSource messages.
 
413
        if (source != JSMessageSource)
 
414
            return;
 
415
        selector = @selector(webView:addMessageToConsole:);
 
416
        if (![delegate respondsToSelector:selector])
 
417
            return;
 
418
    }
 
419
 
 
420
    NSString *messageSource = stringForMessageSource(source);
 
421
    NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
 
422
        (NSString *)message, @"message",
 
423
        [NSNumber numberWithUnsignedInt:lineNumber], @"lineNumber",
 
424
        (NSString *)sourceURL, @"sourceURL",
 
425
        messageSource, @"MessageSource",
 
426
        stringForMessageType(type), @"MessageType",
 
427
        stringForMessageLevel(level), @"MessageLevel",
 
428
        NULL];
 
429
 
 
430
    if (respondsToNewSelector)
 
431
        CallUIDelegate(m_webView, selector, dictionary, messageSource);
 
432
    else
 
433
        CallUIDelegate(m_webView, selector, dictionary);
 
434
 
 
435
    [dictionary release];
 
436
}
 
437
 
 
438
bool WebChromeClient::canRunBeforeUnloadConfirmPanel()
 
439
{
 
440
    return [[m_webView UIDelegate] respondsToSelector:@selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:)];
 
441
}
 
442
 
 
443
bool WebChromeClient::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
 
444
{
 
445
    return CallUIDelegateReturningBoolean(true, m_webView, @selector(webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:), message, kit(frame));
 
446
}
 
447
 
 
448
void WebChromeClient::closeWindowSoon()
 
449
{
 
450
    // We need to remove the parent WebView from WebViewSets here, before it actually
 
451
    // closes, to make sure that JavaScript code that executes before it closes
 
452
    // can't find it. Otherwise, window.open will select a closed WebView instead of 
 
453
    // opening a new one <rdar://problem/3572585>.
 
454
 
 
455
    // We also need to stop the load to prevent further parsing or JavaScript execution
 
456
    // after the window has torn down <rdar://problem/4161660>.
 
457
  
 
458
    // FIXME: This code assumes that the UI delegate will respond to a webViewClose
 
459
    // message by actually closing the WebView. Safari guarantees this behavior, but other apps might not.
 
460
    // This approach is an inherent limitation of not making a close execute immediately
 
461
    // after a call to window.close.
 
462
 
 
463
    [m_webView setGroupName:nil];
 
464
    [m_webView stopLoading:nil];
 
465
    [m_webView performSelector:@selector(_closeWindow) withObject:nil afterDelay:0.0];
 
466
}
 
467
 
 
468
void WebChromeClient::runJavaScriptAlert(Frame* frame, const String& message)
 
469
{
 
470
    id delegate = [m_webView UIDelegate];
 
471
    SEL selector = @selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:);
 
472
    if ([delegate respondsToSelector:selector]) {
 
473
        CallUIDelegate(m_webView, selector, message, kit(frame));
 
474
        return;
 
475
    }
 
476
 
 
477
    // Call the old version of the delegate method if it is implemented.
 
478
    selector = @selector(webView:runJavaScriptAlertPanelWithMessage:);
 
479
    if ([delegate respondsToSelector:selector]) {
 
480
        CallUIDelegate(m_webView, selector, message);
 
481
        return;
 
482
    }
 
483
}
 
484
 
 
485
bool WebChromeClient::runJavaScriptConfirm(Frame* frame, const String& message)
 
486
{
 
487
    id delegate = [m_webView UIDelegate];
 
488
    SEL selector = @selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:);
 
489
    if ([delegate respondsToSelector:selector])
 
490
        return CallUIDelegateReturningBoolean(NO, m_webView, selector, message, kit(frame));
 
491
 
 
492
    // Call the old version of the delegate method if it is implemented.
 
493
    selector = @selector(webView:runJavaScriptConfirmPanelWithMessage:);
 
494
    if ([delegate respondsToSelector:selector])
 
495
        return CallUIDelegateReturningBoolean(NO, m_webView, selector, message);
 
496
 
 
497
    return NO;
 
498
}
 
499
 
 
500
bool WebChromeClient::runJavaScriptPrompt(Frame* frame, const String& prompt, const String& defaultText, String& result)
 
501
{
 
502
    id delegate = [m_webView UIDelegate];
 
503
    SEL selector = @selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:);
 
504
    NSString *defaultString = defaultText;
 
505
    if ([delegate respondsToSelector:selector]) {
 
506
        result = (NSString *)CallUIDelegate(m_webView, selector, prompt, defaultString, kit(frame));
 
507
        return !result.isNull();
 
508
    }
 
509
 
 
510
    // Call the old version of the delegate method if it is implemented.
 
511
    selector = @selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:);
 
512
    if ([delegate respondsToSelector:selector]) {
 
513
        result = (NSString *)CallUIDelegate(m_webView, selector, prompt, defaultString);
 
514
        return !result.isNull();
 
515
    }
 
516
 
 
517
    result = [[WebDefaultUIDelegate sharedUIDelegate] webView:m_webView runJavaScriptTextInputPanelWithPrompt:prompt defaultText:defaultString initiatedByFrame:kit(frame)];
 
518
    return !result.isNull();
 
519
}
 
520
 
 
521
bool WebChromeClient::shouldInterruptJavaScript()
 
522
{
 
523
    return CallUIDelegateReturningBoolean(NO, m_webView, @selector(webViewShouldInterruptJavaScript:));
 
524
}
 
525
 
 
526
void WebChromeClient::setStatusbarText(const String& status)
 
527
{
 
528
    // We want the temporaries allocated here to be released even before returning to the 
 
529
    // event loop; see <http://bugs.webkit.org/show_bug.cgi?id=9880>.
 
530
    NSAutoreleasePool* localPool = [[NSAutoreleasePool alloc] init];
 
531
    CallUIDelegate(m_webView, @selector(webView:setStatusText:), (NSString *)status);
 
532
    [localPool drain];
 
533
}
 
534
 
 
535
IntRect WebChromeClient::windowResizerRect() const
 
536
{
 
537
    return enclosingIntRect([[m_webView window] _growBoxRect]);
 
538
}
 
539
 
 
540
void WebChromeClient::invalidateRootView(const IntRect&, bool immediate)
 
541
{
 
542
    if (immediate) {
 
543
        [[m_webView window] displayIfNeeded];
 
544
        [[m_webView window] flushWindowIfNeeded];
 
545
    }
 
546
}
 
547
 
 
548
void WebChromeClient::invalidateContentsAndRootView(const IntRect& rect, bool immediate)
 
549
{
 
550
}
 
551
 
 
552
void WebChromeClient::invalidateContentsForSlowScroll(const IntRect& rect, bool immediate)
 
553
{
 
554
    invalidateContentsAndRootView(rect, immediate);
 
555
}
 
556
 
 
557
void WebChromeClient::scroll(const IntSize&, const IntRect&, const IntRect&)
 
558
{
 
559
}
 
560
 
 
561
IntPoint WebChromeClient::screenToRootView(const IntPoint& p) const
 
562
{
 
563
    // FIXME: Implement this.
 
564
    return p;
 
565
}
 
566
 
 
567
IntRect WebChromeClient::rootViewToScreen(const IntRect& r) const
 
568
{
 
569
    // FIXME: Implement this.
 
570
    return r;
 
571
}
 
572
 
 
573
PlatformPageClient WebChromeClient::platformPageClient() const
 
574
{
 
575
    return 0;
 
576
}
 
577
 
 
578
void WebChromeClient::contentsSizeChanged(Frame*, const IntSize&) const
 
579
{
 
580
}
 
581
 
 
582
void WebChromeClient::scrollRectIntoView(const IntRect& r) const
 
583
{
 
584
    // FIXME: This scrolling behavior should be under the control of the embedding client,
 
585
    // perhaps in a delegate method, rather than something WebKit does unconditionally.
 
586
    NSView *coordinateView = [[[m_webView mainFrame] frameView] documentView];
 
587
    NSRect rect = r;
 
588
    for (NSView *view = m_webView; view; view = [view superview]) {
 
589
        if ([view isKindOfClass:[NSClipView class]]) {
 
590
            NSClipView *clipView = (NSClipView *)view;
 
591
            NSView *documentView = [clipView documentView];
 
592
            [documentView scrollRectToVisible:[documentView convertRect:rect fromView:coordinateView]];
 
593
        }
 
594
    }
 
595
}
 
596
 
 
597
// End host window methods.
 
598
 
 
599
bool WebChromeClient::shouldUnavailablePluginMessageBeButton(RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason) const
 
600
{
 
601
    if (pluginUnavailabilityReason == RenderEmbeddedObject::PluginInactive)
 
602
        return true;
 
603
 
 
604
    if (pluginUnavailabilityReason == RenderEmbeddedObject::PluginMissing)
 
605
        return [[m_webView UIDelegate] respondsToSelector:@selector(webView:didPressMissingPluginButton:)];
 
606
 
 
607
    return false;
 
608
}
 
609
 
 
610
void WebChromeClient::unavailablePluginButtonClicked(Element* element, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason) const
 
611
{
 
612
    ASSERT(element->hasTagName(objectTag) || element->hasTagName(embedTag) || element->hasTagName(appletTag));
 
613
 
 
614
    if (pluginUnavailabilityReason == RenderEmbeddedObject::PluginInactive) {
 
615
        HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(element);
 
616
 
 
617
        WebBasePluginPackage *pluginPackage = nil;
 
618
        if (!pluginElement->serviceType().isEmpty())
 
619
            pluginPackage = [m_webView _pluginForMIMEType:pluginElement->serviceType()];
 
620
 
 
621
        NSURL *url = pluginElement->document()->completeURL(pluginElement->url());
 
622
        NSString *extension = [[url path] pathExtension];
 
623
        if (!pluginPackage && [extension length])
 
624
            pluginPackage = [m_webView _pluginForExtension:extension];
 
625
 
 
626
        if (pluginPackage && [pluginPackage bundleIdentifier] == "com.oracle.java.JavaAppletPlugin") {
 
627
            // Reactivate the plug-in and reload the page so the plug-in will be instantiated correctly.
 
628
            WKActivateJavaPlugIn();
 
629
            [m_webView reload:nil];
 
630
        }
 
631
 
 
632
        return;
 
633
    }
 
634
 
 
635
    ASSERT(pluginUnavailabilityReason == RenderEmbeddedObject::PluginMissing || pluginUnavailabilityReason == RenderEmbeddedObject::PluginInactive);
 
636
    CallUIDelegate(m_webView, @selector(webView:didPressMissingPluginButton:), kit(element));
 
637
}
 
638
 
 
639
void WebChromeClient::mouseDidMoveOverElement(const HitTestResult& result, unsigned modifierFlags)
 
640
{
 
641
    WebElementDictionary *element = [[WebElementDictionary alloc] initWithHitTestResult:result];
 
642
    [m_webView _mouseDidMoveOverElement:element modifierFlags:modifierFlags];
 
643
    [element release];
 
644
}
 
645
 
 
646
void WebChromeClient::setToolTip(const String& toolTip, TextDirection)
 
647
{
 
648
    NSView<WebDocumentView> *documentView = [[[m_webView _selectedOrMainFrame] frameView] documentView];
 
649
    if ([documentView isKindOfClass:[WebHTMLView class]])
 
650
        [(WebHTMLView *)documentView _setToolTip:toolTip];
 
651
}
 
652
 
 
653
void WebChromeClient::print(Frame* frame)
 
654
{
 
655
    WebFrame *webFrame = kit(frame);
 
656
    if ([[m_webView UIDelegate] respondsToSelector:@selector(webView:printFrame:)])
 
657
        CallUIDelegate(m_webView, @selector(webView:printFrame:), webFrame);
 
658
    else
 
659
        CallUIDelegate(m_webView, @selector(webView:printFrameView:), [webFrame frameView]);
 
660
}
 
661
 
 
662
#if ENABLE(SQL_DATABASE)
 
663
 
 
664
void WebChromeClient::exceededDatabaseQuota(Frame* frame, const String& databaseName)
 
665
{
 
666
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
667
 
 
668
    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:frame->document()->securityOrigin()];
 
669
    // FIXME: remove this workaround once shipping Safari has the necessary delegate implemented.
 
670
    if (WKAppVersionCheckLessThan(@"com.apple.Safari", -1, 3.1)) {
 
671
        const unsigned long long defaultQuota = 5 * 1024 * 1024; // 5 megabytes should hopefully be enough to test storage support.
 
672
        [[webOrigin databaseQuotaManager] setQuota:defaultQuota];
 
673
    } else
 
674
        CallUIDelegate(m_webView, @selector(webView:frame:exceededDatabaseQuotaForSecurityOrigin:database:), kit(frame), webOrigin, (NSString *)databaseName);
 
675
    [webOrigin release];
 
676
 
 
677
    END_BLOCK_OBJC_EXCEPTIONS;
 
678
}
 
679
 
 
680
#endif
 
681
 
 
682
void WebChromeClient::reachedMaxAppCacheSize(int64_t spaceNeeded)
 
683
{
 
684
    // FIXME: Free some space.
 
685
}
 
686
 
 
687
void WebChromeClient::reachedApplicationCacheOriginQuota(SecurityOrigin* origin, int64_t totalSpaceNeeded)
 
688
{
 
689
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
690
 
 
691
    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:origin];
 
692
    CallUIDelegate(m_webView, @selector(webView:exceededApplicationCacheOriginQuotaForSecurityOrigin:totalSpaceNeeded:), webOrigin, static_cast<NSUInteger>(totalSpaceNeeded));
 
693
    [webOrigin release];
 
694
 
 
695
    END_BLOCK_OBJC_EXCEPTIONS;
 
696
}
 
697
 
 
698
void WebChromeClient::populateVisitedLinks()
 
699
{
 
700
    if ([m_webView historyDelegate]) {
 
701
        WebHistoryDelegateImplementationCache* implementations = WebViewGetHistoryDelegateImplementations(m_webView);
 
702
        
 
703
        if (implementations->populateVisitedLinksFunc)
 
704
            CallHistoryDelegate(implementations->populateVisitedLinksFunc, m_webView, @selector(populateVisitedLinksForWebView:));
 
705
 
 
706
        return;
 
707
    }
 
708
 
 
709
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
710
    [[WebHistory optionalSharedHistory] _addVisitedLinksToPageGroup:[m_webView page]->group()];
 
711
    END_BLOCK_OBJC_EXCEPTIONS;
 
712
}
 
713
 
 
714
#if ENABLE(DASHBOARD_SUPPORT)
 
715
 
 
716
void WebChromeClient::annotatedRegionsChanged()
 
717
{
 
718
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
719
    CallUIDelegate(m_webView, @selector(webView:dashboardRegionsChanged:), [m_webView _dashboardRegions]);
 
720
    END_BLOCK_OBJC_EXCEPTIONS;
 
721
}
 
722
 
 
723
#endif
 
724
 
 
725
FloatRect WebChromeClient::customHighlightRect(Node* node, const AtomicString& type, const FloatRect& lineRect)
 
726
{
 
727
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
728
 
 
729
    NSView *documentView = [[kit(node->document()->frame()) frameView] documentView];
 
730
    if (![documentView isKindOfClass:[WebHTMLView class]])
 
731
        return NSZeroRect;
 
732
 
 
733
    WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
 
734
    id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
 
735
    return [highlighter highlightRectForLine:lineRect representedNode:kit(node)];
 
736
 
 
737
    END_BLOCK_OBJC_EXCEPTIONS;
 
738
 
 
739
    return NSZeroRect;
 
740
}
 
741
 
 
742
void WebChromeClient::paintCustomHighlight(Node* node, const AtomicString& type, const FloatRect& boxRect, const FloatRect& lineRect,
 
743
    bool behindText, bool entireLine)
 
744
{
 
745
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
746
 
 
747
    NSView *documentView = [[kit(node->document()->frame()) frameView] documentView];
 
748
    if (![documentView isKindOfClass:[WebHTMLView class]])
 
749
        return;
 
750
 
 
751
    WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
 
752
    id<WebHTMLHighlighter> highlighter = [webHTMLView _highlighterForType:type];
 
753
    [highlighter paintHighlightForBox:boxRect onLine:lineRect behindText:behindText entireLine:entireLine representedNode:kit(node)];
 
754
 
 
755
    END_BLOCK_OBJC_EXCEPTIONS;
 
756
}
 
757
 
 
758
void WebChromeClient::runOpenPanel(Frame*, PassRefPtr<FileChooser> chooser)
 
759
{
 
760
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
761
    BOOL allowMultipleFiles = chooser->settings().allowsMultipleFiles;
 
762
    WebOpenPanelResultListener *listener = [[WebOpenPanelResultListener alloc] initWithChooser:chooser];
 
763
    id delegate = [m_webView UIDelegate];
 
764
    if ([delegate respondsToSelector:@selector(webView:runOpenPanelForFileButtonWithResultListener:allowMultipleFiles:)])
 
765
        CallUIDelegate(m_webView, @selector(webView:runOpenPanelForFileButtonWithResultListener:allowMultipleFiles:), listener, allowMultipleFiles);
 
766
    else if ([delegate respondsToSelector:@selector(webView:runOpenPanelForFileButtonWithResultListener:)])
 
767
        CallUIDelegate(m_webView, @selector(webView:runOpenPanelForFileButtonWithResultListener:), listener);
 
768
    else
 
769
        [listener cancel];
 
770
    [listener release];
 
771
    END_BLOCK_OBJC_EXCEPTIONS;
 
772
}
 
773
 
 
774
void WebChromeClient::loadIconForFiles(const Vector<String>& filenames, FileIconLoader* iconLoader)
 
775
{
 
776
    iconLoader->notifyFinished(Icon::createIconForFiles(filenames));
 
777
}
 
778
 
 
779
void WebChromeClient::setCursor(const WebCore::Cursor& cursor)
 
780
{
 
781
    if ([NSApp _cursorRectCursor])
 
782
        return;
 
783
 
 
784
    NSCursor *platformCursor = cursor.platformCursor();
 
785
    if ([NSCursor currentCursor] == platformCursor)
 
786
        return;
 
787
    [platformCursor set];
 
788
}
 
789
 
 
790
void WebChromeClient::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
 
791
{
 
792
    [NSCursor setHiddenUntilMouseMoves:hiddenUntilMouseMoves];
 
793
}
 
794
 
 
795
KeyboardUIMode WebChromeClient::keyboardUIMode()
 
796
{
 
797
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
798
    return [m_webView _keyboardUIMode];
 
799
    END_BLOCK_OBJC_EXCEPTIONS;
 
800
    return KeyboardAccessDefault;
 
801
}
 
802
 
 
803
NSResponder *WebChromeClient::firstResponder()
 
804
{
 
805
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
806
    return [[m_webView _UIDelegateForwarder] webViewFirstResponder:m_webView];
 
807
    END_BLOCK_OBJC_EXCEPTIONS;
 
808
    return nil;
 
809
}
 
810
 
 
811
void WebChromeClient::makeFirstResponder(NSResponder *responder)
 
812
{
 
813
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
814
    [m_webView _pushPerformingProgrammaticFocus];
 
815
    [[m_webView _UIDelegateForwarder] webView:m_webView makeFirstResponder:responder];
 
816
    [m_webView _popPerformingProgrammaticFocus];
 
817
    END_BLOCK_OBJC_EXCEPTIONS;
 
818
}
 
819
 
 
820
void WebChromeClient::willPopUpMenu(NSMenu *menu)
 
821
{
 
822
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
823
    CallUIDelegate(m_webView, @selector(webView:willPopupMenu:), menu);
 
824
    END_BLOCK_OBJC_EXCEPTIONS;
 
825
}
 
826
 
 
827
bool WebChromeClient::shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename)
 
828
{
 
829
    NSString* filename;
 
830
    if (![[m_webView _UIDelegateForwarder] webView:m_webView shouldReplaceUploadFile:path usingGeneratedFilename:&filename])
 
831
        return false;
 
832
    generatedFilename = filename;
 
833
    return true;
 
834
}
 
835
 
 
836
String WebChromeClient::generateReplacementFile(const String& path)
 
837
{
 
838
    return [[m_webView _UIDelegateForwarder] webView:m_webView generateReplacementFile:path];
 
839
}
 
840
 
 
841
void WebChromeClient::elementDidFocus(const WebCore::Node* node)
 
842
{
 
843
    CallUIDelegate(m_webView, @selector(webView:formDidFocusNode:), kit(const_cast<WebCore::Node*>(node)));
 
844
}
 
845
 
 
846
void WebChromeClient::elementDidBlur(const WebCore::Node* node)
 
847
{
 
848
    CallUIDelegate(m_webView, @selector(webView:formDidBlurNode:), kit(const_cast<WebCore::Node*>(node)));
 
849
}
 
850
 
 
851
bool WebChromeClient::selectItemWritingDirectionIsNatural()
 
852
{
 
853
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
 
854
    return false;
 
855
#else
 
856
    return true;
 
857
#endif
 
858
}
 
859
 
 
860
bool WebChromeClient::selectItemAlignmentFollowsMenuWritingDirection()
 
861
{
 
862
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
 
863
    return true;
 
864
#else
 
865
    return false;
 
866
#endif
 
867
}
 
868
 
 
869
bool WebChromeClient::hasOpenedPopup() const
 
870
{
 
871
    notImplemented();
 
872
    return false;
 
873
}
 
874
 
 
875
PassRefPtr<WebCore::PopupMenu> WebChromeClient::createPopupMenu(WebCore::PopupMenuClient* client) const
 
876
{
 
877
    return adoptRef(new PopupMenuMac(client));
 
878
}
 
879
 
 
880
PassRefPtr<WebCore::SearchPopupMenu> WebChromeClient::createSearchPopupMenu(WebCore::PopupMenuClient* client) const
 
881
{
 
882
    return adoptRef(new SearchPopupMenuMac(client));
 
883
}
 
884
 
 
885
#if USE(ACCELERATED_COMPOSITING)
 
886
 
 
887
void WebChromeClient::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
 
888
{
 
889
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
890
 
 
891
    NSView *documentView = [[kit(frame) frameView] documentView];
 
892
    if (![documentView isKindOfClass:[WebHTMLView class]]) {
 
893
        // We should never be attaching when we don't have a WebHTMLView.
 
894
        ASSERT(!graphicsLayer);
 
895
        return;
 
896
    }
 
897
 
 
898
    WebHTMLView *webHTMLView = (WebHTMLView *)documentView;
 
899
    if (graphicsLayer)
 
900
        [webHTMLView attachRootLayer:graphicsLayer->platformLayer()];
 
901
    else
 
902
        [webHTMLView detachRootLayer];
 
903
    END_BLOCK_OBJC_EXCEPTIONS;
 
904
}
 
905
 
 
906
void WebChromeClient::setNeedsOneShotDrawingSynchronization()
 
907
{
 
908
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
909
    [m_webView _setNeedsOneShotDrawingSynchronization:YES];
 
910
    END_BLOCK_OBJC_EXCEPTIONS;
 
911
}
 
912
 
 
913
void WebChromeClient::scheduleCompositingLayerFlush()
 
914
{
 
915
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
916
    [m_webView _scheduleCompositingLayerFlush];
 
917
    END_BLOCK_OBJC_EXCEPTIONS;
 
918
}
 
919
 
 
920
#endif
 
921
 
 
922
#if ENABLE(VIDEO)
 
923
 
 
924
bool WebChromeClient::supportsFullscreenForNode(const Node* node)
 
925
{
 
926
    return node->hasTagName(WebCore::HTMLNames::videoTag);
 
927
}
 
928
 
 
929
void WebChromeClient::enterFullscreenForNode(Node* node)
 
930
{
 
931
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
932
    [m_webView _enterFullscreenForNode:node];
 
933
    END_BLOCK_OBJC_EXCEPTIONS;
 
934
}
 
935
 
 
936
void WebChromeClient::exitFullscreenForNode(Node*)
 
937
{
 
938
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
939
    [m_webView _exitFullscreen];
 
940
    END_BLOCK_OBJC_EXCEPTIONS;    
 
941
}
 
942
 
 
943
#endif
 
944
 
 
945
#if ENABLE(FULLSCREEN_API)
 
946
 
 
947
bool WebChromeClient::supportsFullScreenForElement(const Element* element, bool withKeyboard)
 
948
{
 
949
    SEL selector = @selector(webView:supportsFullScreenForElement:withKeyboard:);
 
950
    if ([[m_webView UIDelegate] respondsToSelector:selector])
 
951
        return CallUIDelegateReturningBoolean(false, m_webView, selector, kit(const_cast<WebCore::Element*>(element)), withKeyboard);
 
952
    return [m_webView _supportsFullScreenForElement:const_cast<WebCore::Element*>(element) withKeyboard:withKeyboard];
 
953
}
 
954
 
 
955
void WebChromeClient::enterFullScreenForElement(Element* element)
 
956
{
 
957
    SEL selector = @selector(webView:enterFullScreenForElement:listener:);
 
958
    if ([[m_webView UIDelegate] respondsToSelector:selector]) {
 
959
        WebKitFullScreenListener* listener = [[WebKitFullScreenListener alloc] initWithElement:element];
 
960
        CallUIDelegate(m_webView, selector, kit(element), listener);
 
961
        [listener release];
 
962
    } else
 
963
        [m_webView _enterFullScreenForElement:element];
 
964
}
 
965
 
 
966
void WebChromeClient::exitFullScreenForElement(Element* element)
 
967
{
 
968
    SEL selector = @selector(webView:exitFullScreenForElement:listener:);
 
969
    if ([[m_webView UIDelegate] respondsToSelector:selector]) {
 
970
        WebKitFullScreenListener* listener = [[WebKitFullScreenListener alloc] initWithElement:element];
 
971
        CallUIDelegate(m_webView, selector, kit(element), listener);
 
972
        [listener release];
 
973
    } else
 
974
        [m_webView _exitFullScreenForElement:element];
 
975
}
 
976
 
 
977
void WebChromeClient::fullScreenRendererChanged(RenderBox* renderer)
 
978
{
 
979
    SEL selector = @selector(webView:fullScreenRendererChanged:);
 
980
    if ([[m_webView UIDelegate] respondsToSelector:selector])
 
981
        CallUIDelegate(m_webView, selector, (id)renderer);
 
982
}
 
983
 
 
984
#endif