OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 // Conversions for IDBKey. | 6 // Conversions for IDBKey. |
7 // | 7 // |
8 // Per http://www.w3.org/TR/IndexedDB/#key-construct | 8 // Per http://www.w3.org/TR/IndexedDB/#key-construct |
9 // | 9 // |
10 // "A value is said to be a valid key if it is one of the following types: Array | 10 // "A value is said to be a valid key if it is one of the following types: Array |
11 // JavaScript objects [ECMA-262], DOMString [WEBIDL], Date [ECMA-262] or float | 11 // JavaScript objects [ECMA-262], DOMString [WEBIDL], Date [ECMA-262] or float |
12 // [WEBIDL]. However Arrays are only valid keys if every item in the array is | 12 // [WEBIDL]. However Arrays are only valid keys if every item in the array is |
13 // defined and is a valid key (i.e. sparse arrays can not be valid keys) and if | 13 // defined and is a valid key (i.e. sparse arrays can not be valid keys) and if |
14 // the Array doesn't directly or indirectly contain itself. Any non-numeric | 14 // the Array doesn't directly or indirectly contain itself. Any non-numeric |
15 // properties are ignored, and thus does not affect whether the Array is a valid | 15 // properties are ignored, and thus does not affect whether the Array is a valid |
16 // key. Additionally, if the value is of type float, it is only a valid key if | 16 // key. Additionally, if the value is of type float, it is only a valid key if |
17 // it is not NaN, and if the value is of type Date it is only a valid key if its | 17 // it is not NaN, and if the value is of type Date it is only a valid key if its |
18 // [[PrimitiveValue]] internal property, as defined by [ECMA-262], is not NaN." | 18 // [[PrimitiveValue]] internal property, as defined by [ECMA-262], is not NaN." |
19 | 19 |
20 // What is required is to ensure that an Lists in the key are actually | 20 // What is required is to ensure that an Lists in the key are actually |
21 // JavaScript arrays, and any Dates are JavaScript Dates. | 21 // JavaScript arrays, and any Dates are JavaScript Dates. |
22 | 22 |
23 // Conversions for Window. These check if the window is the local | 23 // Conversions for Window. These check if the window is the local |
24 // window, and if it's not, wraps or unwraps it with a secure wrapper. | 24 // window, and if it's not, wraps or unwraps it with a secure wrapper. |
25 // We need to test for EventTarget here as well as it's a base type. | 25 // We need to test for EventTarget here as well as it's a base type. |
26 // We omit an unwrapper for Window as no methods take a non-local | 26 // We omit an unwrapper for Window as no methods take a non-local |
27 // window as a parameter. | 27 // window as a parameter. |
28 | 28 |
29 Window _convertNativeToDart_Window(win) { | 29 Window _convertNativeToDart_Window(win) { |
30 return _DOMWindowCrossFrameImpl._createSafe(win); | 30 return _DOMWindowCrossFrame._createSafe(win); |
31 } | 31 } |
32 | 32 |
33 EventTarget _convertNativeToDart_EventTarget(e) { | 33 EventTarget _convertNativeToDart_EventTarget(e) { |
34 // Assume it's a Window if it contains the setInterval property. It may be | 34 // Assume it's a Window if it contains the setInterval property. It may be |
35 // from a different frame - without a patched prototype - so we cannot | 35 // from a different frame - without a patched prototype - so we cannot |
36 // rely on Dart type checking. | 36 // rely on Dart type checking. |
37 if (JS('bool', r'"setInterval" in #', e)) | 37 if (JS('bool', r'"setInterval" in #', e)) |
38 return _DOMWindowCrossFrameImpl._createSafe(e); | 38 return _DOMWindowCrossFrame._createSafe(e); |
39 else | 39 else |
40 return e; | 40 return e; |
41 } | 41 } |
42 | 42 |
43 EventTarget _convertDartToNative_EventTarget(e) { | 43 EventTarget _convertDartToNative_EventTarget(e) { |
44 if (e is _DOMWindowCrossFrameImpl) { | 44 if (e is _DOMWindowCrossFrame) { |
45 return e._window; | 45 return e._window; |
46 } else { | 46 } else { |
47 return e; | 47 return e; |
48 } | 48 } |
49 } | 49 } |
50 | 50 |
51 // Conversions for ImageData | 51 // Conversions for ImageData |
52 // | 52 // |
53 // On Firefox, the returned ImageData is a plain object. | 53 // On Firefox, the returned ImageData is a plain object. |
54 | 54 |
(...skipping 13 matching lines...) Expand all Loading... |
68 | 68 |
69 return new _TypedImageData( | 69 return new _TypedImageData( |
70 JS('var', '#.data', nativeImageData), | 70 JS('var', '#.data', nativeImageData), |
71 JS('var', '#.height', nativeImageData), | 71 JS('var', '#.height', nativeImageData), |
72 JS('var', '#.width', nativeImageData)); | 72 JS('var', '#.width', nativeImageData)); |
73 } | 73 } |
74 | 74 |
75 // We can get rid of this conversion if _TypedImageData implements the fields | 75 // We can get rid of this conversion if _TypedImageData implements the fields |
76 // with native names. | 76 // with native names. |
77 _convertDartToNative_ImageData(ImageData imageData) { | 77 _convertDartToNative_ImageData(ImageData imageData) { |
78 if (imageData is _ImageDataImpl) return imageData; | 78 if (imageData is _TypedImageData) { |
79 return JS('Object', '{data: #, height: #, width: #}', | 79 return JS('Object', '{data: #, height: #, width: #}', |
80 imageData.data, imageData.height, imageData.width); | 80 imageData.data, imageData.height, imageData.width); |
| 81 } |
| 82 return imageData; |
81 } | 83 } |
82 | 84 |
83 | 85 |
84 /// Converts a JavaScript object with properties into a Dart Map. | 86 /// Converts a JavaScript object with properties into a Dart Map. |
85 /// Not suitable for nested objects. | 87 /// Not suitable for nested objects. |
86 Map _convertNativeToDart_Dictionary(object) { | 88 Map _convertNativeToDart_Dictionary(object) { |
87 if (object == null) return null; | 89 if (object == null) return null; |
88 var dict = {}; | 90 var dict = {}; |
89 for (final key in JS('List', 'Object.getOwnPropertyNames(#)', object)) { | 91 for (final key in JS('List', 'Object.getOwnPropertyNames(#)', object)) { |
90 dict[key] = JS('var', '#[#]', object, key); | 92 dict[key] = JS('var', '#[#]', object, key); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 throw new UnimplementedError('structured clone of RegExp'); | 226 throw new UnimplementedError('structured clone of RegExp'); |
225 } | 227 } |
226 | 228 |
227 // The browser's internal structured cloning algorithm will copy certain | 229 // The browser's internal structured cloning algorithm will copy certain |
228 // types of object, but it will copy only its own implementations and not | 230 // types of object, but it will copy only its own implementations and not |
229 // just any Dart implementations of the interface. | 231 // just any Dart implementations of the interface. |
230 | 232 |
231 // TODO(sra): The JavaScript objects suitable for direct cloning by the | 233 // TODO(sra): The JavaScript objects suitable for direct cloning by the |
232 // structured clone algorithm could be tagged with an private interface. | 234 // structured clone algorithm could be tagged with an private interface. |
233 | 235 |
234 if (e is _FileImpl) return e; | 236 if (e is File) return e; |
235 if (e is File) { | 237 if (e is Blob) return e; |
236 throw new UnimplementedError('structured clone of File'); | 238 if (e is _FileList) return e; |
237 } | |
238 | |
239 if (e is _BlobImpl) return e; | |
240 if (e is Blob) { | |
241 throw new UnimplementedError('structured clone of Blob'); | |
242 } | |
243 | |
244 if (e is _FileListImpl) return e; | |
245 | 239 |
246 // TODO(sra): Firefox: How to convert _TypedImageData on the other end? | 240 // TODO(sra): Firefox: How to convert _TypedImageData on the other end? |
247 if (e is _ImageDataImpl) return e; | 241 if (e is ImageData) return e; |
248 if (e is ImageData) { | 242 if (e is ArrayBuffer) return e; |
249 throw new UnimplementedError('structured clone of ImageData'); | |
250 } | |
251 | 243 |
252 if (e is _ArrayBufferImpl) return e; | 244 if (e is ArrayBufferView) return e; |
253 if (e is ArrayBuffer) { | |
254 throw new UnimplementedError('structured clone of ArrayBuffer'); | |
255 } | |
256 | |
257 if (e is _ArrayBufferViewImpl) return e; | |
258 if (e is ArrayBufferView) { | |
259 throw new UnimplementedError('structured clone of ArrayBufferView'); | |
260 } | |
261 | 245 |
262 if (e is Map) { | 246 if (e is Map) { |
263 var slot = findSlot(e); | 247 var slot = findSlot(e); |
264 var copy = readSlot(slot); | 248 var copy = readSlot(slot); |
265 if (copy != null) return copy; | 249 if (copy != null) return copy; |
266 copy = JS('var', '{}'); | 250 copy = JS('var', '{}'); |
267 writeSlot(slot, copy); | 251 writeSlot(slot, copy); |
268 e.forEach((key, value) { | 252 e.forEach((key, value) { |
269 JS('void', '#[#] = #', copy, key, walk(value)); | 253 JS('void', '#[#] = #', copy, key, walk(value)); |
270 }); | 254 }); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 } | 415 } |
432 | 416 |
433 | 417 |
434 bool _isJavaScriptDate(value) => JS('bool', '# instanceof Date', value); | 418 bool _isJavaScriptDate(value) => JS('bool', '# instanceof Date', value); |
435 bool _isJavaScriptRegExp(value) => JS('bool', '# instanceof RegExp', value); | 419 bool _isJavaScriptRegExp(value) => JS('bool', '# instanceof RegExp', value); |
436 bool _isJavaScriptArray(value) => JS('bool', '# instanceof Array', value); | 420 bool _isJavaScriptArray(value) => JS('bool', '# instanceof Array', value); |
437 bool _isJavaScriptSimpleObject(value) => | 421 bool _isJavaScriptSimpleObject(value) => |
438 JS('bool', 'Object.getPrototypeOf(#) === Object.prototype', value); | 422 JS('bool', 'Object.getPrototypeOf(#) === Object.prototype', value); |
439 bool _isImmutableJavaScriptArray(value) => | 423 bool _isImmutableJavaScriptArray(value) => |
440 JS('bool', r'!!(#.immutable$list)', value); | 424 JS('bool', r'!!(#.immutable$list)', value); |
OLD | NEW |