]>
Commit | Line | Data |
---|---|---|
93a37866 A |
1 | /* |
2 | * Copyright (C) 2013 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 | * 1. Redistributions of source code must retain the above copyright | |
8 | * notice, this list of conditions and the following disclaimer. | |
9 | * 2. Redistributions in binary form must reproduce the above copyright | |
10 | * notice, this list of conditions and the following disclaimer in the | |
11 | * documentation and/or other materials provided with the distribution. | |
12 | * | |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | |
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | |
17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
24 | */ | |
25 | ||
26 | #ifndef JSValue_h | |
27 | #define JSValue_h | |
28 | ||
29 | #if JSC_OBJC_API_ENABLED | |
30 | ||
31 | #import <CoreGraphics/CGGeometry.h> | |
32 | ||
33 | @class JSContext; | |
34 | ||
35 | // A JSValue is a reference to a value within the JavaScript object space of a | |
36 | // JSVirtualMachine. All instances of JSValue originate from a JSContext and | |
37 | // hold a strong reference to this JSContext. As long as any value associated with | |
38 | // a particular JSContext is retained, that JSContext will remain alive. | |
39 | // Where an instance method is invoked upon a JSValue, and this returns another | |
40 | // JSValue, the returned JSValue will originate from the same JSContext as the | |
41 | // JSValue on which the method was invoked. | |
42 | // | |
43 | // For all methods taking arguments of type id, arguments will be converted | |
44 | // into a JavaScript value according to the conversion specified below. | |
45 | // All JavaScript values are associated with a particular JSVirtualMachine | |
46 | // (the associated JSVirtualMachine is available indirectly via the context | |
47 | // property). An instance of JSValue may only be passed as an argument to | |
48 | // methods on instances of JSValue and JSContext that belong to the same | |
49 | // JSVirtualMachine - passing a JSValue to a method on an object originating | |
50 | // from a different JSVirtualMachine will result in an Objective-C exception | |
51 | // being raised. | |
52 | // | |
53 | // Conversion between Objective-C and JavaScript types. | |
54 | // | |
55 | // When converting between JavaScript values and Objective-C objects a copy is | |
56 | // performed. Values of types listed below are copied to the corresponding | |
57 | // types on conversion in each direction. For NSDictionaries, entries in the | |
58 | // dictionary that are keyed by strings are copied onto a JavaScript object. | |
59 | // For dictionaries and arrays, conversion is recursive, with the same object | |
60 | // conversion being applied to all entries in the collection. | |
61 | // | |
62 | // Objective-C type | JavaScript type | |
63 | // --------------------+--------------------- | |
64 | // nil | undefined | |
65 | // NSNull | null | |
66 | // NSString | string | |
67 | // NSNumber | number, boolean | |
68 | // NSDictionary | Object object | |
69 | // NSArray | Array object | |
70 | // NSDate | Date object | |
71 | // NSBlock * | Function object * | |
72 | // id ** | Wrapper object ** | |
73 | // Class *** | Constructor object *** | |
74 | // | |
75 | // * Instances of NSBlock with supported arguments types will be presented to | |
76 | // JavaScript as a callable Function object. For more information on supported | |
77 | // argument types see JSExport.h. If a JavaScript Function originating from an | |
78 | // Objective-C block is converted back to an Objective-C object the block will | |
79 | // be returned. All other JavaScript functions will be converted in the same | |
80 | // manner as a JavaScript object of type Object. | |
81 | // | |
82 | // ** For Objective-C instances that do not derive from the set of types listed | |
83 | // above, a wrapper object to provide a retaining handle to the Objective-C | |
84 | // instance from JavaScript. For more information on these wrapper objects, see | |
85 | // JSExport.h. When a JavaScript wrapper object is converted back to Objective-C | |
86 | // the Objective-C instance being retained by the wrapper is returned. | |
87 | // | |
88 | // *** For Objective-C Class objects a constructor object containing exported | |
89 | // class methods will be returned. See JSExport.h for more information on | |
90 | // constructor objects. | |
91 | ||
92 | NS_CLASS_AVAILABLE(10_9, 7_0) | |
93 | @interface JSValue : NSObject | |
94 | ||
95 | // Create a JSValue by converting an Objective-C object. | |
96 | + (JSValue *)valueWithObject:(id)value inContext:(JSContext *)context; | |
97 | // Create a JavaScript value from an Objective-C primitive type. | |
98 | + (JSValue *)valueWithBool:(BOOL)value inContext:(JSContext *)context; | |
99 | + (JSValue *)valueWithDouble:(double)value inContext:(JSContext *)context; | |
100 | + (JSValue *)valueWithInt32:(int32_t)value inContext:(JSContext *)context; | |
101 | + (JSValue *)valueWithUInt32:(uint32_t)value inContext:(JSContext *)context; | |
102 | // Create a JavaScript value in this context. | |
103 | + (JSValue *)valueWithNewObjectInContext:(JSContext *)context; | |
104 | + (JSValue *)valueWithNewArrayInContext:(JSContext *)context; | |
105 | + (JSValue *)valueWithNewRegularExpressionFromPattern:(NSString *)pattern flags:(NSString *)flags inContext:(JSContext *)context; | |
106 | + (JSValue *)valueWithNewErrorFromMessage:(NSString *)message inContext:(JSContext *)context; | |
107 | + (JSValue *)valueWithNullInContext:(JSContext *)context; | |
108 | + (JSValue *)valueWithUndefinedInContext:(JSContext *)context; | |
109 | ||
110 | // Convert this value to a corresponding Objective-C object, according to the | |
111 | // conversion specified above. | |
112 | - (id)toObject; | |
113 | // Convert this value to a corresponding Objective-C object, if the result is | |
114 | // not of the specified class then nil will be returned. | |
115 | - (id)toObjectOfClass:(Class)expectedClass; | |
116 | // The value is copied to a boolean according to the conversion specified by the | |
117 | // JavaScript language. | |
118 | - (BOOL)toBool; | |
119 | // The value is copied to a number according to the conversion specified by the | |
120 | // JavaScript language. | |
121 | - (double)toDouble; | |
122 | // The value is copied to an integer according to the conversion specified by | |
123 | // the JavaScript language. | |
124 | - (int32_t)toInt32; | |
125 | // The value is copied to an integer according to the conversion specified by | |
126 | // the JavaScript language. | |
127 | - (uint32_t)toUInt32; | |
128 | // If the value is a boolean, a NSNumber value of @YES or @NO will be returned. | |
129 | // For all other types the value will be copied to a number according to the | |
130 | // conversion specified by the JavaScript language. | |
131 | - (NSNumber *)toNumber; | |
132 | // The value is copied to a string according to the conversion specified by the | |
133 | // JavaScript language. | |
134 | - (NSString *)toString; | |
135 | // The value is converted to a number representing a time interval since 1970, | |
136 | // and a new NSDate instance is returned. | |
137 | - (NSDate *)toDate; | |
138 | // If the value is null or undefined then nil is returned. | |
139 | // If the value is not an object then a JavaScript TypeError will be thrown. | |
140 | // The property "length" is read from the object, converted to an unsigned | |
141 | // integer, and an NSArray of this size is allocated. Properties corresponding | |
142 | // to indicies within the array bounds will be copied to the array, with | |
143 | // Objective-C objects converted to equivalent JSValues as specified. | |
144 | - (NSArray *)toArray; | |
145 | // If the value is null or undefined then nil is returned. | |
146 | // If the value is not an object then a JavaScript TypeError will be thrown. | |
147 | // All enumerable properties of the object are copied to the dictionary, with | |
148 | // Objective-C objects converted to equivalent JSValues as specified. | |
149 | - (NSDictionary *)toDictionary; | |
150 | ||
151 | // Access a property from the value. This method will return the JavaScript value | |
152 | // 'undefined' if the property does not exist. | |
153 | - (JSValue *)valueForProperty:(NSString *)property; | |
154 | // Set a property on the value. | |
155 | - (void)setValue:(id)value forProperty:(NSString *)property; | |
156 | // Delete a property from the value, returns YES if deletion is successful. | |
157 | - (BOOL)deleteProperty:(NSString *)property; | |
158 | // Returns YES if property is present on the value. | |
159 | // This method has the same function as the JavaScript operator "in". | |
160 | - (BOOL)hasProperty:(NSString *)property; | |
161 | // This method may be used to create a data or accessor property on an object; | |
162 | // this method operates in accordance with the Object.defineProperty method in | |
163 | // the JavaScript language. | |
164 | - (void)defineProperty:(NSString *)property descriptor:(id)descriptor; | |
165 | ||
166 | // Access an indexed property from the value. This method will return the | |
167 | // JavaScript value 'undefined' if no property exists at that index. | |
168 | - (JSValue *)valueAtIndex:(NSUInteger)index; | |
169 | // Set an indexed property on the value. For JSValues that are JavaScript arrays, | |
170 | // indices greater than UINT_MAX - 1 will not affect the length of the array. | |
171 | - (void)setValue:(id)value atIndex:(NSUInteger)index; | |
172 | ||
173 | // All JavaScript values are precisely one of these types. | |
174 | - (BOOL)isUndefined; | |
175 | - (BOOL)isNull; | |
176 | - (BOOL)isBoolean; | |
177 | - (BOOL)isNumber; | |
178 | - (BOOL)isString; | |
179 | - (BOOL)isObject; | |
180 | ||
181 | // This method has the same function as the JavaScript operator "===". | |
182 | - (BOOL)isEqualToObject:(id)value; | |
183 | // This method has the same function as the JavaScript operator "==". | |
184 | - (BOOL)isEqualWithTypeCoercionToObject:(id)value; | |
185 | // This method has the same function as the JavaScript operator "instanceof". | |
186 | - (BOOL)isInstanceOf:(id)value; | |
187 | ||
188 | // Call this value as a function passing the specified arguments. | |
189 | - (JSValue *)callWithArguments:(NSArray *)arguments; | |
190 | // Call this value as a constructor passing the specified arguments. | |
191 | - (JSValue *)constructWithArguments:(NSArray *)arguments; | |
192 | // Access the property named "method" from this value; call the value resulting | |
193 | // from the property access as a function, passing this value as the "this" | |
194 | // value, and the specified arguments. | |
195 | - (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments; | |
196 | ||
197 | // The JSContext that this value originates from. | |
198 | @property(readonly, retain) JSContext *context; | |
199 | ||
200 | @end | |
201 | ||
202 | // Objective-C methods exported to JavaScript may have argument and/or return | |
203 | // values of struct types, provided that conversion to and from the struct is | |
204 | // supported by JSValue. Support is provided for any types where JSValue | |
205 | // contains both a class method "valueWith<Type>:inContext:", and and instance | |
206 | // method "to<Type>" - where the string "<Type>" in these selector names match, | |
207 | // with the first argument to the former being of the same struct type as the | |
208 | // return type of the latter. | |
209 | // Support is provided for structs of type CGPoint, NSRange, CGRect and CGSize. | |
210 | @interface JSValue(StructSupport) | |
211 | ||
212 | // This method returns a newly allocated JavaScript object containing properties | |
213 | // named "x" and "y", with values from the CGPoint. | |
214 | + (JSValue *)valueWithPoint:(CGPoint)point inContext:(JSContext *)context; | |
215 | // This method returns a newly allocated JavaScript object containing properties | |
216 | // named "location" and "length", with values from the NSRange. | |
217 | + (JSValue *)valueWithRange:(NSRange)range inContext:(JSContext *)context; | |
218 | // This method returns a newly allocated JavaScript object containing properties | |
219 | // named "x", "y", "width", and "height", with values from the CGRect. | |
220 | + (JSValue *)valueWithRect:(CGRect)rect inContext:(JSContext *)context; | |
221 | // This method returns a newly allocated JavaScript object containing properties | |
222 | // named "width" and "height", with values from the CGSize. | |
223 | + (JSValue *)valueWithSize:(CGSize)size inContext:(JSContext *)context; | |
224 | ||
225 | // Convert a value to type CGPoint by reading properties named "x" and "y" from | |
226 | // this value, and converting the results to double. | |
227 | - (CGPoint)toPoint; | |
228 | // Convert a value to type NSRange by accessing properties named "location" and | |
229 | // "length" from this value converting the results to double. | |
230 | - (NSRange)toRange; | |
231 | // Convert a value to type CGRect by reading properties named "x", "y", "width", | |
232 | // and "height" from this value, and converting the results to double. | |
233 | - (CGRect)toRect; | |
234 | // Convert a value to type CGSize by accessing properties named "width" and | |
235 | // "height" from this value converting the results to double. | |
236 | - (CGSize)toSize; | |
237 | ||
238 | @end | |
239 | ||
240 | // Instances of JSValue implement the following methods in order to enable | |
241 | // support for subscript access by key and index, for example: | |
242 | // | |
243 | // JSValue *objectA, *objectB; | |
244 | // JSValue *v1 = object[@"X"]; // Get value for property "X" from 'object'. | |
245 | // JSValue *v2 = object[42]; // Get value for index 42 from 'object'. | |
246 | // object[@"Y"] = v1; // Assign 'v1' to property "Y" of 'object'. | |
247 | // object[101] = v2; // Assign 'v2' to index 101 of 'object'. | |
248 | // | |
249 | // An object key passed as a subscript will be converted to a JavaScript value, | |
250 | // and then the value converted to a string used as a property name. | |
251 | @interface JSValue(SubscriptSupport) | |
252 | ||
253 | - (JSValue *)objectForKeyedSubscript:(id)key; | |
254 | - (JSValue *)objectAtIndexedSubscript:(NSUInteger)index; | |
255 | - (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key; | |
256 | - (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index; | |
257 | ||
258 | @end | |
259 | ||
260 | // These functions are for bridging between the C API and the Objective-C API. | |
261 | @interface JSValue(JSValueRefSupport) | |
262 | // Creates a JSValue, wrapping its C API counterpart. | |
263 | + (JSValue *)valueWithJSValueRef:(JSValueRef)value inContext:(JSContext *)context; | |
264 | // Returns the C API counterpart wrapped by a JSContext. | |
265 | - (JSValueRef)JSValueRef; | |
266 | @end | |
267 | ||
268 | #ifdef __cplusplus | |
269 | extern "C" { | |
270 | #endif | |
271 | ||
272 | // These keys may assist in creating a property descriptor for use with the | |
273 | // defineProperty method on JSValue. | |
274 | // Property descriptors must fit one of three descriptions: | |
275 | // Data Descriptor: | |
276 | // - A descriptor containing one or both of the keys "value" and "writable", | |
277 | // and optionally containing one or both of the keys "enumerable" and | |
278 | // "configurable". A data descriptor may not contain either the "get" or | |
279 | // "set" key. | |
280 | // A data descriptor may be used to create or modify the attributes of a | |
281 | // data property on an object (replacing any existing accessor property). | |
282 | // Accessor Descriptor: | |
283 | // - A descriptor containing one or both of the keys "get" and "set", and | |
284 | // optionally containing one or both of the keys "enumerable" and | |
285 | // "configurable". An accessor descriptor may not contain either the "value" | |
286 | // or "writable" key. | |
287 | // An accessor descriptor may be used to create or modify the attributes of | |
288 | // an accessor property on an object (replacing any existing data property). | |
289 | // Generic Descriptor: | |
290 | // - A descriptor containing one or both of the keys "enumerable" and | |
291 | // "configurable". A generic descriptor may not contain any of the keys | |
292 | // "value", " writable", "get", or "set". | |
293 | // A generic descriptor may be used to modify the attributes of an existing | |
294 | // data or accessor property, or to create a new data property. | |
295 | JS_EXPORT extern NSString * const JSPropertyDescriptorWritableKey; | |
296 | JS_EXPORT extern NSString * const JSPropertyDescriptorEnumerableKey; | |
297 | JS_EXPORT extern NSString * const JSPropertyDescriptorConfigurableKey; | |
298 | JS_EXPORT extern NSString * const JSPropertyDescriptorValueKey; | |
299 | JS_EXPORT extern NSString * const JSPropertyDescriptorGetKey; | |
300 | JS_EXPORT extern NSString * const JSPropertyDescriptorSetKey; | |
301 | ||
302 | #ifdef __cplusplus | |
303 | } // extern "C" | |
304 | #endif | |
305 | ||
306 | #endif | |
307 | ||
308 | #endif // JSValue_h |