OLD | NEW |
1 part of html_common; | 1 part of html_common; |
2 | 2 |
3 convertDartToNative_PrepareForStructuredClone(value) => | 3 convertDartToNative_PrepareForStructuredClone(value) => |
4 new _StructuredCloneDartium().convertDartToNative_PrepareForStructuredClone(
value); | 4 new _StructuredCloneDartium().convertDartToNative_PrepareForStructuredClone(
value); |
5 | 5 |
6 convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) => | 6 convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) => |
7 new _AcceptStructuredCloneDartium().convertNativeToDart_AcceptStructuredClon
e(object, mustCopy: mustCopy); | 7 new _AcceptStructuredCloneDartium().convertNativeToDart_AcceptStructuredClon
e(object, mustCopy: mustCopy); |
8 | 8 |
9 class _StructuredCloneDartium extends _StructuredClone { | 9 class _StructuredCloneDartium extends _StructuredClone { |
10 newJsMap() => new js.JsObject(js.context["Object"]); | 10 newJsMap() => new js.JsObject(js.context["Object"]); |
11 putIntoMap(map, key, value) => map[key] = value; | 11 putIntoMap(map, key, value) => map[key] = value; |
12 // TODO(alanknight): Don't create two extra lists to get a fixed-length JS lis
t. | 12 // TODO(alanknight): Don't create two extra lists to get a fixed-length JS lis
t. |
13 newJsList(length) => new js.JsArray.from(new List(length)); | 13 newJsList(length) => new js.JsArray.from(new List(length)); |
14 cloneNotRequired(e) => e is js.JsObject; | 14 cloneNotRequired(e) => e is js.JsObject; |
15 } | 15 } |
16 | 16 |
17 class _AcceptStructuredCloneDartium extends _AcceptStructuredClone { | 17 /// A version of _AcceptStructuredClone, but using a different algorithm |
| 18 /// so we can take advantage of an identity HashMap on Dartium without |
| 19 /// the bad side-effect of modifying the JS source objects if we do the same in |
| 20 /// dart2js. |
| 21 /// |
| 22 /// This no longer inherits anything from _AcceptStructuredClone |
| 23 /// and is never used polymorphically with it, so it doesn't inherit. |
| 24 class _AcceptStructuredCloneDartium { |
18 newDartList(length) => new List(length); | 25 newDartList(length) => new List(length); |
19 | 26 |
20 // JsObjects won't be identical, but will be equal only if the underlying | 27 // JsObjects won't be identical, but will be equal only if the underlying |
21 // Js entities are identical. | 28 // Js entities are identical. |
22 bool identicalInJs(a, b) => | 29 bool identicalInJs(a, b) => |
23 (a is js.JsObject) ? a == b : identical(a, b); | 30 (a is js.JsObject) ? a == b : identical(a, b); |
24 | 31 |
25 void forEachJsField(jsObject, action) { | 32 void forEachJsField(jsObject, action) { |
26 var keys = js.context["Object"].callMethod("keys", [jsObject]); | 33 var keys = js.context["Object"].callMethod("keys", [jsObject]); |
27 for (var key in keys) { | 34 for (var key in keys) { |
28 action(key, jsObject[key]); | 35 action(key, jsObject[key]); |
29 } | 36 } |
30 } | 37 } |
| 38 |
| 39 // Keep track of the clones, keyed by the original object. If we're |
| 40 // not copying, these may be the same. |
| 41 var clones = new HashMap.identity(); |
| 42 bool mustCopy = false; |
| 43 |
| 44 Object findSlot(value) { |
| 45 return clones.putIfAbsent(value, () => null); |
| 46 } |
| 47 |
| 48 writeSlot(original, x) { clones[original] = x; } |
| 49 |
| 50 walk(e) { |
| 51 if (e == null) return e; |
| 52 if (e is bool) return e; |
| 53 if (e is num) return e; |
| 54 if (e is String) return e; |
| 55 |
| 56 if (isJavaScriptDate(e)) { |
| 57 return convertNativeToDart_DateTime(e); |
| 58 } |
| 59 |
| 60 if (isJavaScriptRegExp(e)) { |
| 61 // TODO(sra). |
| 62 throw new UnimplementedError('structured clone of RegExp'); |
| 63 } |
| 64 |
| 65 if (isJavaScriptPromise(e)) { |
| 66 return convertNativePromiseToDartFuture(e); |
| 67 } |
| 68 |
| 69 if (isJavaScriptSimpleObject(e)) { |
| 70 // TODO(sra): If mustCopy is false, swizzle the prototype for one of a Map |
| 71 // implementation that uses the properies as storage. |
| 72 var copy = findSlot(e); |
| 73 if (copy != null) return copy; |
| 74 copy = {}; |
| 75 |
| 76 writeSlot(e, copy); |
| 77 forEachJsField(e, (key, value) => copy[key] = walk(value)); |
| 78 return copy; |
| 79 } |
| 80 |
| 81 if (isJavaScriptArray(e)) { |
| 82 var copy = findSlot(e); |
| 83 if (copy != null) return copy; |
| 84 |
| 85 int length = e.length; |
| 86 // Since a JavaScript Array is an instance of Dart List, we can modify it |
| 87 // in-place unless we must copy. |
| 88 copy = mustCopy ? newDartList(length) : e; |
| 89 writeSlot(e, copy); |
| 90 |
| 91 for (int i = 0; i < length; i++) { |
| 92 copy[i] = walk(e[i]); |
| 93 } |
| 94 return copy; |
| 95 } |
| 96 |
| 97 // Assume anything else is already a valid Dart object, either by having |
| 98 // already been processed, or e.g. a clonable native class. |
| 99 return e; |
| 100 } |
| 101 |
| 102 convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) { |
| 103 this.mustCopy = mustCopy; |
| 104 var copy = walk(object); |
| 105 return copy; |
| 106 } |
31 } | 107 } |
32 | 108 |
33 final _dateConstructor = js.context["Date"]; | 109 final _dateConstructor = js.context["Date"]; |
34 final _regexConstructor = js.context["RegExp"]; | 110 final _regexConstructor = js.context["RegExp"]; |
35 | 111 |
36 bool isJavaScriptDate(value) => value is js.JsObject && value.instanceof(_dateCo
nstructor); | 112 bool isJavaScriptDate(value) => value is js.JsObject && value.instanceof(_dateCo
nstructor); |
37 bool isJavaScriptRegExp(value) => value is js.JsObject && value.instanceof(_rege
xConstructor); | 113 bool isJavaScriptRegExp(value) => value is js.JsObject && value.instanceof(_rege
xConstructor); |
38 bool isJavaScriptArray(value) => value is js.JsArray; | 114 bool isJavaScriptArray(value) => value is js.JsArray; |
39 | 115 |
40 final _object = js.context["Object"]; | 116 final _object = js.context["Object"]; |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 {'type': dartClass, 'extends': extendTag != null ? extendTag : "" }; | 479 {'type': dartClass, 'extends': extendTag != null ? extendTag : "" }; |
404 } | 480 } |
405 | 481 |
406 Type getCustomElementType(object) { | 482 Type getCustomElementType(object) { |
407 var entry = getCustomElementEntry(object); | 483 var entry = getCustomElementEntry(object); |
408 if (entry != null) { | 484 if (entry != null) { |
409 return entry['type']; | 485 return entry['type']; |
410 } | 486 } |
411 return null; | 487 return null; |
412 } | 488 } |
OLD | NEW |