Permalink
Browse files

Refactored GAScriptObject to use GAScriptEngine instead of UIWebView …

…directly. This simplified much of the code, and helped fix memory management issues for block-based callbacks. UIWebView category exposes more built-in objects now.
  • Loading branch information...
Andrew Goodale
Andrew Goodale committed Feb 7, 2012
1 parent d033b32 commit 7c89c56aae5fd44d529742d8aab8e3e9a7a01965
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2011 Andrew Goodale. All rights reserved.
+ Copyright (c) 2011-2012 Andrew Goodale. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
@@ -27,19 +27,23 @@
*/
#import <Foundation/Foundation.h>
-#import "GAScriptObject.h"
+#import "GAScriptEngine.h"
typedef void (^GAScriptBlock)(NSArray *);
/**
- * Wraps a block so it can be called from JavaScript. Not public right now,
- * but it could be useful for allowing people to use in their own classes.
+ * Wraps a block so it can be called from JavaScript. This opbject can be used to pass
+ * blocks as arguments to JavaScript function calls.
*/
@interface GAScriptBlockObject : NSObject
{
- GAScriptBlock _blockObject;
+ NSString* m_blockId;
+ GAScriptBlock m_block;
}
+@property (nonatomic, readonly) NSString* blockId;
+@property (nonatomic, readonly) GAScriptBlock block;
+
+ (id)scriptBlockWithBlock:(GAScriptBlock)block;
- (id)initWithBlock:(GAScriptBlock)block;
@@ -52,13 +56,8 @@ typedef void (^GAScriptBlock)(NSArray *);
* Add support for functions that are proxies to a block. When the function is called from JavaScript,
* the block will be invoked.
*/
-@interface GAScriptObject (Blocks)
+@interface GAScriptEngine (Blocks)
-/**
- * Creates a JavaScript function that will invoke the given block when called. The block will be copied
- * and a reference managed by this script object instance. Make sure your block is on the heap if it's
- * needed after this script object is deallocated.
- */
-- (void)setFunctionForKey:(NSString *)key withBlock:(void(^)(NSArray* arguments))block;
+- (void)addBlockCallback:(GAScriptBlockObject *)blockObject;
@end
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2011 Andrew Goodale. All rights reserved.
+ Copyright (c) 2011-2012 Andrew Goodale. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
@@ -30,6 +30,9 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
@implementation GAScriptBlockObject
+@synthesize blockId = m_blockId,
+ block = m_block;
+
+ (id)scriptBlockWithBlock:(GAScriptBlock)block
{
return [[[GAScriptBlockObject alloc] initWithBlock:block] autorelease];
@@ -39,15 +42,17 @@ - (id)initWithBlock:(GAScriptBlock)block
{
if ((self = [super init]))
{
- _blockObject = [block copy];
+ m_block = [block copy];
+ m_blockId = [[NSString alloc] initWithFormat:@"block-%u", [self hash]];
}
return self;
}
- (void)dealloc
{
- [_blockObject release];
+ [m_blockId release];
+ [m_block release];
[super dealloc];
}
@@ -58,33 +63,11 @@ - (void)dealloc
*/
- (NSString *)stringForJavaScript
{
- NSAssert(_blockObject, @"Block for callback cannot be NULL!");
- // NSLog(@"ScriptBlockObject: function () { GAJavaScript.invocation(%p, arguments); }", (void *)_blockObject);
+ NSAssert(m_block, @"Block for callback cannot be NULL!");
+ GADebugStr(@"ScriptBlockObject: function () { GAJavaScript.invocation('%@', arguments); }", m_blockId);
- return [NSString stringWithFormat:@"function () { GAJavaScript.invocation(%p, arguments); }", (void *)_blockObject];
+ return [NSString stringWithFormat:@"function () { GAJavaScript.invocation('%@', arguments); }", m_blockId];
}
@end
-#pragma mark GAScriptObject (Blocks)
-
-@implementation GAScriptObject (Blocks)
-
-- (void)setFunctionForKey:(NSString *)key withBlock:(void(^)(NSArray* arguments))block
-{
- GAScriptBlockObject* myBlock = [[GAScriptBlockObject alloc] initWithBlock:block];
-
- [self setValue:myBlock forKey:key];
-
- // Save the block object so that we can keep the block alive while this object is used.
- // The block might be stack-based, which would likely go out-of-scope before the callback
- // is received.
- //
- if (m_blocks == nil)
- m_blocks = [[NSMutableSet alloc] initWithCapacity:4];
-
- [m_blocks addObject:myBlock];
- [myBlock release];
-}
-
-@end
View
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2011 Andrew Goodale. All rights reserved.
+ Copyright (c) 2011-2012 Andrew Goodale. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
@@ -28,6 +28,8 @@
#import <UIKit/UIKit.h>
+static NSString* const GAJavaScriptErrorDomain;
+
@class GAScriptObject;
/**
@@ -39,11 +41,11 @@
@private
UIWebView* m_webView;
id<UIWebViewDelegate> m_delegate;
-
- GAScriptObject* m_document;
- GAScriptObject* m_window;
-
+
NSMutableArray* m_receivers;
+
+ /* A dictionary of NSString->Block */
+ NSMutableDictionary* m_blocks;
}
/**
@@ -52,19 +54,14 @@
@property (nonatomic, readonly) UIWebView* webView;
/**
- * A reference to the "document" object for this UIWebView.
+ * An array of objects that take callbacks from JavaScript code.
*/
-@property (nonatomic, readonly) GAScriptObject* documentObject;
+@property (nonatomic, retain) NSMutableArray* receivers;
/**
- * A reference to the "window" object for thi UIWebView.
+ * Access the script engine attached to the given view
*/
-@property (nonatomic, readonly) GAScriptObject* windowObject;
-
-/**
- * An array of objects that take callbacks from JavaScript code.
- */
-@property (nonatomic, retain) NSMutableArray* receivers;
++ (GAScriptEngine *)scriptEngineForView:(UIWebView *)webView;
/**
* The designated initializer.
@@ -79,7 +76,7 @@
- (id)initWithSuperview:(UIView *)superview delegate:(id<UIWebViewDelegate>)delegate;
/*
- * Creates a new (empty) object
+ * Creates a new Object instance.
*/
- (GAScriptObject *)newScriptObject;
@@ -90,7 +87,7 @@
/*
* Returns a script object bound to the given reference. The script object will have
- * a "weak" reference to the JavaScript object
+ * a "weak" reference to the JavaScript object (i.e. it won't prevent the object from being collected).
*/
- (GAScriptObject *)scriptObjectWithReference:(NSString *)reference;
@@ -104,4 +101,14 @@
*/
- (id)callFunction:(NSString *)functionName withObject:(id)argument;
+/*
+ * Call a function at global scope with multiple arguments.
+ */
+- (id)callFunction:(NSString *)functionName withArguments:(NSArray *)arguments;
+
+/*
+ * Generic evaluation of script
+ */
+- (id)evalWithFormat:(NSString *)script, ...;
+
@end
Oops, something went wrong.

0 comments on commit 7c89c56

Please sign in to comment.