blob: 9ca9299de2aaf2db3a37bba2f5678458d26eb5bf [file] [log] [blame]
/*
* Copyright (C) 2007 Apple Inc. All rights reserved.
*
* 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.
*/
#import "ObjCController.h"
#import <JavaScriptCore/JavaScriptCore.h>
#import <WebKit/DOMAbstractView.h>
#import <WebKit/WebScriptObject.h>
#import <WebKit/WebView.h>
#import <pthread.h>
#import <wtf/Assertions.h>
static void* runJavaScriptThread(void* arg)
{
JSGlobalContextRef ctx = JSGlobalContextCreate(0);
JSStringRef scriptRef = JSStringCreateWithUTF8CString("'Hello World!'");
JSValueRef exception = 0;
JSEvaluateScript(ctx, scriptRef, 0, 0, 0, &exception);
ASSERT(!exception);
JSGlobalContextRelease(ctx);
JSStringRelease(scriptRef);
return 0;
}
@implementation ObjCController
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
if (0
|| aSelector == @selector(classNameOf:)
|| aSelector == @selector(objectOfClass:)
|| aSelector == @selector(identityIsEqual::)
|| aSelector == @selector(longLongRoundTrip:)
|| aSelector == @selector(unsignedLongLongRoundTrip:)
|| aSelector == @selector(testWrapperRoundTripping:)
|| aSelector == @selector(accessStoredWebScriptObject)
|| aSelector == @selector(storeWebScriptObject:)
|| aSelector == @selector(testValueForKey)
)
return NO;
return YES;
}
+ (NSString *)webScriptNameForSelector:(SEL)aSelector
{
if (aSelector == @selector(classNameOf:))
return @"className";
if (aSelector == @selector(objectOfClass:))
return @"objectOfClass";
if (aSelector == @selector(identityIsEqual::))
return @"identityIsEqual";
if (aSelector == @selector(longLongRoundTrip:))
return @"longLongRoundTrip";
if (aSelector == @selector(unsignedLongLongRoundTrip:))
return @"unsignedLongLongRoundTrip";
if (aSelector == @selector(testWrapperRoundTripping:))
return @"testWrapperRoundTripping";
if (aSelector == @selector(storeWebScriptObject:))
return @"storeWebScriptObject";
if (aSelector == @selector(testValueForKey))
return @"testValueForKey";
return nil;
}
- (NSString *)classNameOf:(id)object
{
if (!object)
return @"nil";
return NSStringFromClass([object class]);
}
- (id)objectOfClass:(NSString *)aClass
{
if ([aClass isEqualToString:@"NSNull"])
return [NSNull null];
if ([aClass isEqualToString:@"WebUndefined"])
return [WebUndefined undefined];
if ([aClass isEqualToString:@"NSCFBoolean"])
return [NSNumber numberWithBool:true];
if ([aClass isEqualToString:@"NSCFNumber"])
return [NSNumber numberWithInt:1];
if ([aClass isEqualToString:@"NSCFString"])
return @"";
if ([aClass isEqualToString:@"WebScriptObject"])
return self;
if ([aClass isEqualToString:@"NSArray"])
return [NSArray array];
return nil;
}
- (BOOL)identityIsEqual:(WebScriptObject *)a :(WebScriptObject *)b
{
if ([a isKindOfClass:[NSString class]] && [b isKindOfClass:[NSString class]])
return [(NSString *)a isEqualToString:(NSString *)b];
return a == b;
}
- (long long)longLongRoundTrip:(long long)num
{
return num;
}
- (unsigned long long)unsignedLongLongRoundTrip:(unsigned long long)num
{
return num;
}
- (void)testValueForKey
{
ASSERT(storedWebScriptObject);
@try {
[storedWebScriptObject valueForKey:@"ThisKeyDoesNotExist"];
} @catch (NSException *e) {
}
pthread_t pthread;
pthread_create(&pthread, 0, &runJavaScriptThread, 0);
pthread_join(pthread, 0);
}
- (BOOL)testWrapperRoundTripping:(WebScriptObject *)webScriptObject
{
JSObjectRef jsObject = [webScriptObject JSObject];
if (!jsObject)
return false;
if (!webScriptObject)
return false;
if ([[webScriptObject evaluateWebScript:@"({ })"] class] != [webScriptObject class])
return false;
[webScriptObject setValue:[NSNumber numberWithInt:666] forKey:@"key"];
if (![[webScriptObject valueForKey:@"key"] isKindOfClass:[NSNumber class]] ||
![[webScriptObject valueForKey:@"key"] isEqualToNumber:[NSNumber numberWithInt:666]])
return false;
[webScriptObject removeWebScriptKey:@"key"];
@try {
if ([webScriptObject valueForKey:@"key"])
return false;
} @catch(NSException *exception) {
// NSObject throws an exception if the key doesn't exist.
}
[webScriptObject setWebScriptValueAtIndex:0 value:webScriptObject];
if ([webScriptObject webScriptValueAtIndex:0] != webScriptObject)
return false;
if ([[webScriptObject stringRepresentation] isEqualToString:@"[Object object]"])
return false;
if ([webScriptObject callWebScriptMethod:@"returnThis" withArguments:nil] != webScriptObject)
return false;
return true;
}
- (void)accessStoredWebScriptObject
{
#if !ASSERT_DISABLED
BOOL isWindowObject = [storedWebScriptObject isKindOfClass:[DOMAbstractView class]];
#endif
JSObjectRef jsObject = [storedWebScriptObject JSObject];
ASSERT((jsObject && isWindowObject) || (!jsObject && !isWindowObject));
[storedWebScriptObject callWebScriptMethod:@"" withArguments:nil];
[storedWebScriptObject evaluateWebScript:@""];
[storedWebScriptObject setValue:[WebUndefined undefined] forKey:@"key"];
[storedWebScriptObject valueForKey:@"key"];
[storedWebScriptObject removeWebScriptKey:@"key"];
[storedWebScriptObject stringRepresentation];
[storedWebScriptObject webScriptValueAtIndex:0];
[storedWebScriptObject setWebScriptValueAtIndex:0 value:[WebUndefined undefined]];
[storedWebScriptObject setException:@"exception"];
}
- (void)storeWebScriptObject:(WebScriptObject *)webScriptObject
{
if (webScriptObject == storedWebScriptObject)
return;
[storedWebScriptObject release];
storedWebScriptObject = [webScriptObject retain];
}
- (void)dealloc
{
[storedWebScriptObject release];
[super dealloc];
}
- (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args
{
// FIXME: Perhaps we should log that this has been called.
return nil;
}
@end