1/* 2 * Copyright (C) 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 "ObjCController.h" 31 32// Avoid compile error in DOMPrivate.h. 33@class NSFont; 34 35#import <JavaScriptCore/JavaScriptCore.h> 36#import <WebKit/DOMAbstractView.h> 37#import <WebKit/DOMPrivate.h> 38#import <WebKit/WebScriptObject.h> 39#import <WebKit/WebView.h> 40#import <pthread.h> 41#import <wtf/Assertions.h> 42 43// Remove this once hasWebScriptKey has been made public. 44@interface WebScriptObject (StagedForPublic) 45- (BOOL)hasWebScriptKey:(NSString *)name; 46@end 47 48static void* runJavaScriptThread(void* arg) 49{ 50 JSGlobalContextRef ctx = JSGlobalContextCreate(0); 51 JSStringRef scriptRef = JSStringCreateWithUTF8CString("'Hello World!'"); 52 53 JSValueRef exception = 0; 54 JSEvaluateScript(ctx, scriptRef, 0, 0, 1, &exception); 55 ASSERT(!exception); 56 57 JSGlobalContextRelease(ctx); 58 JSStringRelease(scriptRef); 59 60 return 0; 61} 62 63@implementation ObjCController 64 65+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector 66{ 67 if (0 68 || aSelector == @selector(classNameOf:) 69 || aSelector == @selector(objectOfClass:) 70 || aSelector == @selector(arrayOfString) 71 || aSelector == @selector(identityIsEqual::) 72 || aSelector == @selector(longLongRoundTrip:) 73 || aSelector == @selector(unsignedLongLongRoundTrip:) 74 || aSelector == @selector(testWrapperRoundTripping:) 75 || aSelector == @selector(accessStoredWebScriptObject) 76 || aSelector == @selector(storeWebScriptObject:) 77 || aSelector == @selector(testValueForKey) 78 || aSelector == @selector(testHasWebScriptKey:) 79 || aSelector == @selector(testArray) 80 || aSelector == @selector(setSelectElement:selectedIndex:allowingMultiple:) 81 ) 82 return NO; 83 return YES; 84} 85 86+ (NSString *)webScriptNameForSelector:(SEL)aSelector 87{ 88 if (aSelector == @selector(classNameOf:)) 89 return @"className"; 90 if (aSelector == @selector(objectOfClass:)) 91 return @"objectOfClass"; 92 if (aSelector == @selector(arrayOfString)) 93 return @"arrayOfString"; 94 if (aSelector == @selector(identityIsEqual::)) 95 return @"identityIsEqual"; 96 if (aSelector == @selector(longLongRoundTrip:)) 97 return @"longLongRoundTrip"; 98 if (aSelector == @selector(unsignedLongLongRoundTrip:)) 99 return @"unsignedLongLongRoundTrip"; 100 if (aSelector == @selector(testWrapperRoundTripping:)) 101 return @"testWrapperRoundTripping"; 102 if (aSelector == @selector(storeWebScriptObject:)) 103 return @"storeWebScriptObject"; 104 if (aSelector == @selector(testValueForKey)) 105 return @"testValueForKey"; 106 if (aSelector == @selector(testHasWebScriptKey:)) 107 return @"testHasWebScriptKey"; 108 if (aSelector == @selector(testArray)) 109 return @"testArray"; 110 if (aSelector == @selector(setSelectElement:selectedIndex:allowingMultiple:)) 111 return @"setSelectElementSelectedIndexAllowingMultiple"; 112 113 return nil; 114} 115 116- (NSString *)classNameOf:(id)object 117{ 118 if (!object) 119 return @"nil"; 120 return NSStringFromClass([object class]); 121} 122 123- (id)objectOfClass:(NSString *)aClass 124{ 125 if ([aClass isEqualToString:@"NSNull"]) 126 return [NSNull null]; 127 if ([aClass isEqualToString:@"WebUndefined"]) 128 return [WebUndefined undefined]; 129 if ([aClass isEqualToString:@"NSCFBoolean"]) 130 return [NSNumber numberWithBool:true]; 131 if ([aClass isEqualToString:@"NSCFNumber"]) 132 return [NSNumber numberWithInt:1]; 133 if ([aClass isEqualToString:@"NSCFString"]) 134 return @""; 135 if ([aClass isEqualToString:@"WebScriptObject"]) 136 return self; 137 if ([aClass isEqualToString:@"NSArray"]) 138 return [NSArray array]; 139 140 return nil; 141} 142 143- (NSArray *)arrayOfString 144{ 145 NSString *strings[3]; 146 strings[0] = @"one"; 147 strings[1] = @"two"; 148 strings[2] = @"three"; 149 NSArray *array = [NSArray arrayWithObjects:strings count:3]; 150 return array; 151} 152 153- (BOOL)identityIsEqual:(WebScriptObject *)a :(WebScriptObject *)b 154{ 155 if ([a isKindOfClass:[NSString class]] && [b isKindOfClass:[NSString class]]) 156 return [(NSString *)a isEqualToString:(NSString *)b]; 157 return a == b; 158} 159 160- (long long)longLongRoundTrip:(long long)num 161{ 162 return num; 163} 164 165- (unsigned long long)unsignedLongLongRoundTrip:(unsigned long long)num 166{ 167 return num; 168} 169 170- (void)testValueForKey 171{ 172 ASSERT(storedWebScriptObject); 173 174 @try { 175 [storedWebScriptObject valueForKey:@"ThisKeyDoesNotExist"]; 176 } @catch (NSException *e) { 177 } 178 179 pthread_t pthread; 180 pthread_create(&pthread, 0, &runJavaScriptThread, 0); 181 pthread_join(pthread, 0); 182} 183 184- (BOOL)testHasWebScriptKey:(NSString *)key 185{ 186 ASSERT(storedWebScriptObject); 187 return [storedWebScriptObject hasWebScriptKey:key]; 188} 189 190- (BOOL)testWrapperRoundTripping:(WebScriptObject *)webScriptObject 191{ 192 JSObjectRef jsObject = [webScriptObject JSObject]; 193 194 if (!jsObject) 195 return false; 196 197 if (!webScriptObject) 198 return false; 199 200 if ([[webScriptObject evaluateWebScript:@"({ })"] class] != [webScriptObject class]) 201 return false; 202 203 [webScriptObject setValue:[NSNumber numberWithInt:666] forKey:@"key"]; 204 if (![[webScriptObject valueForKey:@"key"] isKindOfClass:[NSNumber class]] || 205 ![[webScriptObject valueForKey:@"key"] isEqualToNumber:[NSNumber numberWithInt:666]]) 206 return false; 207 208 [webScriptObject removeWebScriptKey:@"key"]; 209 @try { 210 if ([webScriptObject valueForKey:@"key"]) 211 return false; 212 } @catch(NSException *exception) { 213 // NSObject throws an exception if the key doesn't exist. 214 } 215 216 [webScriptObject setWebScriptValueAtIndex:0 value:webScriptObject]; 217 if ([webScriptObject webScriptValueAtIndex:0] != webScriptObject) 218 return false; 219 220 if ([[webScriptObject stringRepresentation] isEqualToString:@"[Object object]"]) 221 return false; 222 223 if ([webScriptObject callWebScriptMethod:@"returnThis" withArguments:nil] != webScriptObject) 224 return false; 225 226 return true; 227} 228 229- (void)accessStoredWebScriptObject 230{ 231#if !ASSERT_DISABLED 232 BOOL isWindowObject = [storedWebScriptObject isKindOfClass:[DOMAbstractView class]]; 233 JSObjectRef jsObject = [storedWebScriptObject JSObject]; 234 ASSERT((jsObject && isWindowObject) || (!jsObject && !isWindowObject)); 235#endif 236 [storedWebScriptObject callWebScriptMethod:@"" withArguments:nil]; 237 [storedWebScriptObject evaluateWebScript:@""]; 238 [storedWebScriptObject setValue:[WebUndefined undefined] forKey:@"key"]; 239 [storedWebScriptObject valueForKey:@"key"]; 240 [storedWebScriptObject removeWebScriptKey:@"key"]; 241 [storedWebScriptObject stringRepresentation]; 242 [storedWebScriptObject webScriptValueAtIndex:0]; 243 [storedWebScriptObject setWebScriptValueAtIndex:0 value:[WebUndefined undefined]]; 244 [storedWebScriptObject setException:@"exception"]; 245} 246 247- (void)storeWebScriptObject:(WebScriptObject *)webScriptObject 248{ 249 if (webScriptObject == storedWebScriptObject) 250 return; 251 252 [storedWebScriptObject release]; 253 storedWebScriptObject = [webScriptObject retain]; 254} 255 256- (NSArray *)testArray 257{ 258 return [NSArray array]; 259} 260 261- (void)dealloc 262{ 263 [storedWebScriptObject release]; 264 [super dealloc]; 265} 266 267- (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args 268{ 269 // FIXME: Perhaps we should log that this has been called. 270 return nil; 271} 272 273// MARK: - 274// MARK: Testing Objective-C DOM HTML Bindings 275 276- (void)setSelectElement:(WebScriptObject *)element selectedIndex:(int)index allowingMultiple:(BOOL)allowingMultiple 277{ 278 if (![element isKindOfClass:[DOMHTMLSelectElement class]]) 279 return; 280 281 DOMHTMLSelectElement *select = (DOMHTMLSelectElement*)element; 282 [select _activateItemAtIndex:index allowMultipleSelection:allowingMultiple]; 283} 284 285@end 286