1/* 2 * Copyright (C) 2006. 2007 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#import "config.h" 30#import "UIDelegate.h" 31 32#import "DumpRenderTree.h" 33#import "DumpRenderTreeDraggingInfo.h" 34#import "EventSendingController.h" 35#import "LayoutTestController.h" 36#import <WebKit/WebApplicationCache.h> 37#import <WebKit/WebFramePrivate.h> 38#import <WebKit/WebHTMLViewPrivate.h> 39#import <WebKit/WebQuotaManager.h> 40#import <WebKit/WebSecurityOriginPrivate.h> 41#import <WebKit/WebUIDelegatePrivate.h> 42#import <WebKit/WebView.h> 43#import <WebKit/WebViewPrivate.h> 44#import <wtf/Assertions.h> 45 46DumpRenderTreeDraggingInfo *draggingInfo = nil; 47 48@implementation UIDelegate 49 50- (void)webView:(WebView *)sender setFrame:(NSRect)frame 51{ 52 m_frame = frame; 53} 54 55- (NSRect)webViewFrame:(WebView *)sender 56{ 57 return m_frame; 58} 59 60- (void)webView:(WebView *)sender addMessageToConsole:(NSDictionary *)dictionary withSource:(NSString *)source 61{ 62 NSString *message = [dictionary objectForKey:@"message"]; 63 NSNumber *lineNumber = [dictionary objectForKey:@"lineNumber"]; 64 65 NSRange range = [message rangeOfString:@"file://"]; 66 if (range.location != NSNotFound) 67 message = [[message substringToIndex:range.location] stringByAppendingString:[[message substringFromIndex:NSMaxRange(range)] lastPathComponent]]; 68 69 printf ("CONSOLE MESSAGE: line %d: %s\n", [lineNumber intValue], [message UTF8String]); 70} 71 72- (void)modalWindowWillClose:(NSNotification *)notification 73{ 74 [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowWillCloseNotification object:nil]; 75 [NSApp abortModal]; 76} 77 78- (void)webViewRunModal:(WebView *)sender 79{ 80 gLayoutTestController->setWindowIsKey(false); 81 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modalWindowWillClose:) name:NSWindowWillCloseNotification object:nil]; 82 [NSApp runModalForWindow:[sender window]]; 83 gLayoutTestController->setWindowIsKey(true); 84} 85 86- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame 87{ 88 if (!done) 89 printf("ALERT: %s\n", [message UTF8String]); 90} 91 92- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame 93{ 94 if (!done) 95 printf("CONFIRM: %s\n", [message UTF8String]); 96 return YES; 97} 98 99- (NSString *)webView:(WebView *)sender runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WebFrame *)frame 100{ 101 if (!done) 102 printf("PROMPT: %s, default text: %s\n", [prompt UTF8String], [defaultText UTF8String]); 103 return defaultText; 104} 105 106- (BOOL)webView:(WebView *)c runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame 107{ 108 if (!done) 109 printf("CONFIRM NAVIGATION: %s\n", [message UTF8String]); 110 return YES; 111} 112 113 114- (void)webView:(WebView *)sender dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag forView:(NSView *)view 115{ 116 assert(!draggingInfo); 117 draggingInfo = [[DumpRenderTreeDraggingInfo alloc] initWithImage:anImage offset:initialOffset pasteboard:pboard source:sourceObj]; 118 [sender draggingUpdated:draggingInfo]; 119 [EventSendingController replaySavedEvents]; 120} 121 122- (void)webViewFocus:(WebView *)webView 123{ 124 gLayoutTestController->setWindowIsKey(true); 125} 126 127- (void)webViewUnfocus:(WebView *)webView 128{ 129 gLayoutTestController->setWindowIsKey(false); 130} 131 132- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request 133{ 134 if (!gLayoutTestController->canOpenWindows()) 135 return nil; 136 137 // Make sure that waitUntilDone has been called. 138 ASSERT(gLayoutTestController->waitToDump()); 139 140 WebView *webView = createWebViewAndOffscreenWindow(); 141 142 if (gLayoutTestController->newWindowsCopyBackForwardList()) 143 [webView _loadBackForwardListFromOtherView:sender]; 144 145 return [webView autorelease]; 146} 147 148- (void)webViewClose:(WebView *)sender 149{ 150 NSWindow* window = [sender window]; 151 152 if (gLayoutTestController->callCloseOnWebViews()) 153 [sender close]; 154 155 [window close]; 156} 157 158- (void)webView:(WebView *)sender frame:(WebFrame *)frame exceededDatabaseQuotaForSecurityOrigin:(WebSecurityOrigin *)origin database:(NSString *)databaseIdentifier 159{ 160 if (!done && gLayoutTestController->dumpDatabaseCallbacks()) { 161 printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%s, %s, %i} database:%s\n", [[origin protocol] UTF8String], [[origin host] UTF8String], 162 [origin port], [databaseIdentifier UTF8String]); 163 } 164 165 static const unsigned long long defaultQuota = 5 * 1024 * 1024; 166 [[origin databaseQuotaManager] setQuota:defaultQuota]; 167} 168 169- (void)webView:(WebView *)sender exceededApplicationCacheOriginQuotaForSecurityOrigin:(WebSecurityOrigin *)origin 170{ 171 if (!done && gLayoutTestController->dumpApplicationCacheDelegateCallbacks()) { 172 printf("UI DELEGATE APPLICATION CACHE CALLBACK: exceededApplicationCacheOriginQuotaForSecurityOrigin:{%s, %s, %i}\n", 173 [[origin protocol] UTF8String], [[origin host] UTF8String], [origin port]); 174 } 175 176 static const unsigned long long defaultOriginQuota = [WebApplicationCache defaultOriginQuota]; 177 [[origin applicationCacheQuotaManager] setQuota:defaultOriginQuota]; 178} 179 180- (void)webView:(WebView *)sender setStatusText:(NSString *)text 181{ 182 if (gLayoutTestController->dumpStatusCallbacks()) 183 printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", [text UTF8String]); 184} 185 186- (void)webView:(WebView *)webView decidePolicyForGeolocationRequestFromOrigin:(WebSecurityOrigin *)origin frame:(WebFrame *)frame listener:(id<WebGeolocationPolicyListener>)listener 187{ 188 if (!gLayoutTestController->isGeolocationPermissionSet()) { 189 if (!m_pendingGeolocationPermissionListeners) 190 m_pendingGeolocationPermissionListeners = [[NSMutableSet set] retain]; 191 [m_pendingGeolocationPermissionListeners addObject:listener]; 192 return; 193 } 194 195 if (gLayoutTestController->geolocationPermission()) 196 [listener allow]; 197 else 198 [listener deny]; 199} 200 201- (void)didSetMockGeolocationPermission 202{ 203 ASSERT(gLayoutTestController->isGeolocationPermissionSet()); 204 if (m_pendingGeolocationPermissionListeners && !m_timer) 205 m_timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(timerFired) userInfo:0 repeats:NO]; 206} 207 208- (int)numberOfPendingGeolocationPermissionRequests 209{ 210 if (!m_pendingGeolocationPermissionListeners) 211 return 0; 212 return [m_pendingGeolocationPermissionListeners count]; 213} 214 215 216- (void)timerFired 217{ 218 ASSERT(gLayoutTestController->isGeolocationPermissionSet()); 219 m_timer = 0; 220 NSEnumerator* enumerator = [m_pendingGeolocationPermissionListeners objectEnumerator]; 221 id<WebGeolocationPolicyListener> listener; 222 while ((listener = [enumerator nextObject])) { 223 if (gLayoutTestController->geolocationPermission()) 224 [listener allow]; 225 else 226 [listener deny]; 227 } 228 [m_pendingGeolocationPermissionListeners removeAllObjects]; 229 [m_pendingGeolocationPermissionListeners release]; 230 m_pendingGeolocationPermissionListeners = nil; 231} 232 233- (BOOL)webView:(WebView *)sender shouldHaltPlugin:(DOMNode *)pluginNode 234{ 235 return NO; 236} 237 238- (BOOL)webView:(WebView *)webView supportsFullScreenForElement:(DOMElement*)element withKeyboard:(BOOL)withKeyboard 239{ 240 return YES; 241} 242 243- (void)webView:(WebView *)webView enterFullScreenForElement:(DOMElement*)element listener:(NSObject<WebKitFullScreenListener>*)listener 244{ 245 [listener webkitWillEnterFullScreen]; 246 [listener webkitDidEnterFullScreen]; 247} 248 249- (void)webView:(WebView *)webView exitFullScreenForElement:(DOMElement*)element listener:(NSObject<WebKitFullScreenListener>*)listener 250{ 251 [listener webkitWillExitFullScreen]; 252 [listener webkitDidExitFullScreen]; 253} 254 255- (BOOL)webView:(WebView *)webView didPressMissingPluginButton:(DOMElement *)element 256{ 257 printf("MISSING PLUGIN BUTTON PRESSED\n"); 258 return TRUE; 259} 260 261- (void)dealloc 262{ 263 [draggingInfo release]; 264 draggingInfo = nil; 265 [m_pendingGeolocationPermissionListeners release]; 266 m_pendingGeolocationPermissionListeners = nil; 267 268 [super dealloc]; 269} 270 271@end 272