blob: c1a10a7b753610bc28bc8f7ace29121e64562a2d [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 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 "config.h"
#import "ObjCController.h"
// Avoid compile error in DOMPrivate.h.
@class NSFont;
#import <JavaScriptCore/JavaScriptCore.h>
#import <WebKit/DOMAbstractView.h>
#import <WebKit/DOMPrivate.h>
#import <WebKit/WebScriptObject.h>
#import <WebKit/WebView.h>
#import <pthread.h>
#import <wtf/Assertions.h>
// Remove this once hasWebScriptKey has been made public.
@interface WebScriptObject (StagedForPublic)
- (BOOL)hasWebScriptKey:(NSString *)name;
@end
static void* runJavaScriptThread(void* arg)
{
JSGlobalContextRef ctx = JSGlobalContextCreate(0);
JSStringRef scriptRef = JSStringCreateWithUTF8CString("'Hello World!'");
JSValueRef exception = 0;
JSEvaluateScript(ctx, scriptRef, 0, 0, 1, &exception);
ASSERT(!exception);
JSGlobalContextRelease(ctx);
JSStringRelease(scriptRef);
return 0;
}
@implementation ObjCController
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
if (0
|| aSelector == @selector(classNameOf:)
|| aSelector == @selector(isObject:instanceOf:)
|| aSelector == @selector(objectOfClass:)
|| aSelector == @selector(arrayOfString)
|| aSelector == @selector(identityIsEqual::)
|| aSelector == @selector(longLongRoundTrip:)
|| aSelector == @selector(unsignedLongLongRoundTrip:)
|| aSelector == @selector(testWrapperRoundTripping:)
|| aSelector == @selector(accessStoredWebScriptObject)
|| aSelector == @selector(storeWebScriptObject:)
|| aSelector == @selector(testValueForKey)
|| aSelector == @selector(testHasWebScriptKey:)
|| aSelector == @selector(testArray)
|| aSelector == @selector(testArrayOfObjects)
|| aSelector == @selector(testObject)
|| aSelector == @selector(setSelectElement:selectedIndex:allowingMultiple:)
)
return NO;
return YES;
}
+ (NSString *)webScriptNameForSelector:(SEL)aSelector
{
if (aSelector == @selector(classNameOf:))
return @"className";
if (aSelector == @selector(isObject:instanceOf:))
return @"isObjectInstanceOf";
if (aSelector == @selector(objectOfClass:))
return @"objectOfClass";
if (aSelector == @selector(arrayOfString))
return @"arrayOfString";
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";
if (aSelector == @selector(testHasWebScriptKey:))
return @"testHasWebScriptKey";
if (aSelector == @selector(testArray))
return @"testArray";
if (aSelector == @selector(testArrayOfObjects))
return @"testArrayOfObjects";
if (aSelector == @selector(testObject))
return @"testObject";
if (aSelector == @selector(setSelectElement:selectedIndex:allowingMultiple:))
return @"setSelectElementSelectedIndexAllowingMultiple";
return nil;
}
- (BOOL)isObject:(id)object instanceOf:(NSString *)aClass
{
if (!object)
return [aClass isEqualToString:@"nil"];
return [object isKindOfClass:NSClassFromString(aClass)];
}
- (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 @YES;
if ([aClass isEqualToString:@"NSCFNumber"])
return @(1);
if ([aClass isEqualToString:@"NSCFString"])
return @"";
if ([aClass isEqualToString:@"WebScriptObject"])
return self;
if ([aClass isEqualToString:@"NSArray"])
return @[];
return nil;
}
- (NSArray *)arrayOfString
{
return @[ @"one", @"two", @"three" ];
}
- (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)testHasWebScriptKey:(NSString *)key
{
ASSERT(storedWebScriptObject);
return [storedWebScriptObject hasWebScriptKey:key];
}
- (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:@(666) forKey:@"key"];
id value = [webScriptObject valueForKey:@"key"];
if (![value isKindOfClass:NSNumber.class])
return false;
if (![value isEqualToNumber:@(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_ENABLED
BOOL isWindowObject = [storedWebScriptObject isKindOfClass:[DOMAbstractView class]];
JSObjectRef jsObject = [storedWebScriptObject JSObject];
ASSERT((jsObject && isWindowObject) || (!jsObject && !isWindowObject));
#endif
[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];
}
- (NSArray *)testArray
{
return @[];
}
- (NSArray *)testArrayOfObjects
{
return @[ [[[NSObject alloc] init] autorelease], [[[NSObject alloc] init] autorelease], [[[NSObject alloc] init] autorelease]];
}
- (NSObject *)testObject
{
return [[[NSObject alloc] init] autorelease];
}
- (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;
}
// MARK: -
// MARK: Testing Objective-C DOM HTML Bindings
- (void)setSelectElement:(WebScriptObject *)element selectedIndex:(int)index allowingMultiple:(BOOL)allowingMultiple
{
if (![element isKindOfClass:[DOMHTMLSelectElement class]])
return;
DOMHTMLSelectElement *select = (DOMHTMLSelectElement*)element;
[select _activateItemAtIndex:index allowMultipleSelection:allowingMultiple];
}
@end