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 ImageData) return imageData; |
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 } | 81 } |
82 | 82 |
83 | 83 |
84 /// Converts a JavaScript object with properties into a Dart Map. | 84 /// Converts a JavaScript object with properties into a Dart Map. |
85 /// Not suitable for nested objects. | 85 /// Not suitable for nested objects. |
86 Map _convertNativeToDart_Dictionary(object) { | 86 Map _convertNativeToDart_Dictionary(object) { |
87 if (object == null) return null; | 87 if (object == null) return null; |
88 var dict = {}; | 88 var dict = {}; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 throw const NotImplementedException('structured clone of RegExp'); | 224 throw const NotImplementedException('structured clone of RegExp'); |
225 } | 225 } |
226 | 226 |
227 // The browser's internal structured cloning algorithm will copy certain | 227 // The browser's internal structured cloning algorithm will copy certain |
228 // types of object, but it will copy only its own implementations and not | 228 // types of object, but it will copy only its own implementations and not |
229 // just any Dart implementations of the interface. | 229 // just any Dart implementations of the interface. |
230 | 230 |
231 // TODO(sra): The JavaScript objects suitable for direct cloning by the | 231 // TODO(sra): The JavaScript objects suitable for direct cloning by the |
232 // structured clone algorithm could be tagged with an private interface. | 232 // structured clone algorithm could be tagged with an private interface. |
233 | 233 |
234 if (e is _FileImpl) return e; | 234 if (e is File) return e; |
235 if (e is File) { | 235 if (e is Blob) return e; |
236 throw const NotImplementedException('structured clone of File'); | 236 if (e is _FileList) return e; |
237 } | |
238 | |
239 if (e is _BlobImpl) return e; | |
240 if (e is Blob) { | |
241 throw const NotImplementedException('structured clone of Blob'); | |
242 } | |
243 | |
244 if (e is _FileListImpl) return e; | |
245 | 237 |
246 // TODO(sra): Firefox: How to convert _TypedImageData on the other end? | 238 // TODO(sra): Firefox: How to convert _TypedImageData on the other end? |
247 if (e is _ImageDataImpl) return e; | 239 if (e is ImageData) return e; |
248 if (e is ImageData) { | 240 if (e is ArrayBuffer) return e; |
249 throw const NotImplementedException('structured clone of ImageData'); | |
250 } | |
251 | 241 |
252 if (e is _ArrayBufferImpl) return e; | 242 if (e is ArrayBufferView) return e; |
253 if (e is ArrayBuffer) { | |
254 throw const NotImplementedException('structured clone of ArrayBuffer'); | |
255 } | |
256 | |
257 if (e is _ArrayBufferViewImpl) return e; | |
258 if (e is ArrayBufferView) { | |
259 throw const NotImplementedException('structured clone of ArrayBufferView')
; | |
260 } | |
261 | 243 |
262 if (e is Map) { | 244 if (e is Map) { |
263 var slot = findSlot(e); | 245 var slot = findSlot(e); |
264 var copy = readSlot(slot); | 246 var copy = readSlot(slot); |
265 if (copy != null) return copy; | 247 if (copy != null) return copy; |
266 copy = JS('var', '{}'); | 248 copy = JS('var', '{}'); |
267 writeSlot(slot, copy); | 249 writeSlot(slot, copy); |
268 e.forEach((key, value) { | 250 e.forEach((key, value) { |
269 JS('void', '#[#] = #', copy, key, walk(value)); | 251 JS('void', '#[#] = #', copy, key, walk(value)); |
270 }); | 252 }); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 } | 413 } |
432 | 414 |
433 | 415 |
434 bool _isJavaScriptDate(value) => JS('bool', '# instanceof Date', value); | 416 bool _isJavaScriptDate(value) => JS('bool', '# instanceof Date', value); |
435 bool _isJavaScriptRegExp(value) => JS('bool', '# instanceof RegExp', value); | 417 bool _isJavaScriptRegExp(value) => JS('bool', '# instanceof RegExp', value); |
436 bool _isJavaScriptArray(value) => JS('bool', '# instanceof Array', value); | 418 bool _isJavaScriptArray(value) => JS('bool', '# instanceof Array', value); |
437 bool _isJavaScriptSimpleObject(value) => | 419 bool _isJavaScriptSimpleObject(value) => |
438 JS('bool', 'Object.getPrototypeOf(#) === Object.prototype', value); | 420 JS('bool', 'Object.getPrototypeOf(#) === Object.prototype', value); |
439 bool _isImmutableJavaScriptArray(value) => | 421 bool _isImmutableJavaScriptArray(value) => |
440 JS('bool', r'!!(#.immutable$list)', value); | 422 JS('bool', r'!!(#.immutable$list)', value); |
OLD | NEW |