Files
quark-shell-mac/quark-shell/QSHWebScriptObjectConverter.m
2014-11-26 23:28:55 -08:00

145 lines
4.9 KiB
Objective-C

//
// QSHWebScriptObjectConverter.m
// quark-shell
//
// Created by Xhacker Liu on 6/14/14.
// Copyright (c) 2014 Xhacker. All rights reserved.
//
#import "QSHWebScriptObjectConverter.h"
@interface QSHWebScriptObjectConverter ()
@property (nonatomic, weak) WebView *webView;
@end
@implementation QSHWebScriptObjectConverter
- (instancetype)initWithWebView:(WebView *)webView
{
self = [super init];
if (self) {
_webView = webView;
[self registerJavaScriptHelpers];
}
return self;
}
- (void)registerJavaScriptHelpers
{
NSString *bridgeUtil = @"QSHBridgeUtil = {};";
NSString *isArray = @"QSHBridgeUtil.isArray = function(obj) { return obj.constructor == Array; };";
NSString *isObject = @"QSHBridgeUtil.isObject = function(obj) { return obj.constructor == Object; };";
NSString *dictionaryKeys = @"QSHBridgeUtil.dictionaryKeys = function(obj) { \
var a = []; \
for (var key in obj) { \
if (!obj.hasOwnProperty(key)) { \
continue; \
} \
a.push(key); \
} \
return a; \
}";
NSString *callFunction = @"QSHBridgeUtil.callFunction = function(func) { func(); };";
NSString *callFunctionWithArgs = @"QSHBridgeUtil.callFunctionWithArgs = function(func, args) { func.apply(null, args); };";
WebScriptObject *win = self.webView.windowScriptObject;
[win evaluateWebScript:bridgeUtil];
[win evaluateWebScript:isArray];
[win evaluateWebScript:isObject];
[win evaluateWebScript:dictionaryKeys];
[win evaluateWebScript:callFunction];
[win evaluateWebScript:callFunctionWithArgs];
}
- (BOOL)isArray:(WebScriptObject *)obj
{
WebScriptObject *win = self.webView.windowScriptObject;
WebScriptObject *bridgeUtil = [win evaluateWebScript:@"QSHBridgeUtil"];
NSNumber *result = [bridgeUtil callWebScriptMethod:@"isArray" withArguments:@[obj]];
return result.boolValue;
}
- (BOOL)isDictionary:(WebScriptObject *)obj
{
WebScriptObject *win = self.webView.windowScriptObject;
WebScriptObject *bridgeUtil = [win evaluateWebScript:@"QSHBridgeUtil"];
NSNumber *result = [bridgeUtil callWebScriptMethod:@"isObject" withArguments:@[obj]];
return result.boolValue;
}
- (NSDictionary *)dictionaryFromWebScriptObject:(WebScriptObject *)webScriptObject
{
WebScriptObject *win = self.webView.windowScriptObject;
WebScriptObject *bridgeUtil = [win evaluateWebScript:@"QSHBridgeUtil"];
WebScriptObject *keysObject = [bridgeUtil callWebScriptMethod:@"dictionaryKeys" withArguments:@[webScriptObject]];
NSArray *keys = [self arrayFromWebScriptObject:keysObject];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:keys.count];
for (NSString *key in keys) {
id item = [webScriptObject valueForKey:key];
if ([item isKindOfClass:[WebScriptObject class]]) {
if ([self isArray:item]) {
dict[key] = [self arrayFromWebScriptObject:item];
}
else if ([self isDictionary:item]) {
dict[key] = [self dictionaryFromWebScriptObject:item];
}
else {
dict[key] = item;
}
}
else {
dict[key] = item;
}
}
return dict;
}
- (NSArray *)arrayFromWebScriptObject:(WebScriptObject *)webScriptObject
{
NSUInteger count = [[webScriptObject valueForKey:@"length"] integerValue];
NSMutableArray *a = [NSMutableArray array];
for (unsigned i = 0; i < count; i++) {
id item = [webScriptObject webScriptValueAtIndex:i];
if ([item isKindOfClass:[WebScriptObject class]]) {
if ([self isArray:item]) {
[a addObject:[self arrayFromWebScriptObject:item]];
}
else if ([self isDictionary:item]) {
[a addObject:[self dictionaryFromWebScriptObject:item]];
}
else {
[a addObject:item];
}
}
else {
[a addObject:item];
}
}
return a;
}
- (void)callFunction:(WebScriptObject *)webScriptObject
{
WebScriptObject *win = self.webView.windowScriptObject;
WebScriptObject *bridgeUtil = [win evaluateWebScript:@"QSHBridgeUtil"];
[bridgeUtil callWebScriptMethod:@"callFunction" withArguments:@[webScriptObject]];
}
- (void)callFunction:(WebScriptObject *)webScriptObject
withArgs:(NSArray *)args
{
WebScriptObject *win = self.webView.windowScriptObject;
WebScriptObject *bridgeUtil = [win evaluateWebScript:@"QSHBridgeUtil"];
[bridgeUtil callWebScriptMethod:@"callFunctionWithArgs" withArguments:@[webScriptObject, args]];
}
@end