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() |
| 5 .convertDartToNative_PrepareForStructuredClone(value); |
5 | 6 |
6 convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) => | 7 convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) => |
7 new _AcceptStructuredCloneDartium().convertNativeToDart_AcceptStructuredClon
e(object, mustCopy: mustCopy); | 8 new _AcceptStructuredCloneDartium() |
| 9 .convertNativeToDart_AcceptStructuredClone(object, mustCopy: mustCopy); |
8 | 10 |
9 class _StructuredCloneDartium extends _StructuredClone { | 11 class _StructuredCloneDartium extends _StructuredClone { |
10 newJsMap() => js.JsNative.newObject(); | 12 newJsMap() => js.JsNative.newObject(); |
11 putIntoMap(map, key, value) => js.JsNative.setProperty(map, key, value); | 13 putIntoMap(map, key, value) => js.JsNative.setProperty(map, key, value); |
12 newJsList(length) => js.JsNative.newArray()..length = length; | 14 newJsList(length) => js.JsNative.newArray()..length = length; |
13 cloneNotRequired(e) => | 15 cloneNotRequired(e) => e is js.JSObject || e is TypedData || e is ByteBuffer; |
14 e is js.JSObject || e is TypedData || e is ByteBuffer; | |
15 } | 16 } |
16 | 17 |
17 /// A version of _AcceptStructuredClone, but using a different algorithm | 18 /// A version of _AcceptStructuredClone, but using a different algorithm |
18 /// so we can take advantage of an identity HashMap on Dartium without | 19 /// 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 /// the bad side-effect of modifying the JS source objects if we do the same in |
20 /// dart2js. | 21 /// dart2js. |
21 /// | 22 /// |
22 /// This no longer inherits anything from _AcceptStructuredClone | 23 /// This no longer inherits anything from _AcceptStructuredClone |
23 /// and is never used polymorphically with it, so it doesn't inherit. | 24 /// and is never used polymorphically with it, so it doesn't inherit. |
24 class _AcceptStructuredCloneDartium { | 25 class _AcceptStructuredCloneDartium { |
(...skipping 12 matching lines...) Expand all Loading... |
37 | 38 |
38 // Keep track of the clones, keyed by the original object. If we're | 39 // Keep track of the clones, keyed by the original object. If we're |
39 // not copying, these may be the same. | 40 // not copying, these may be the same. |
40 var clones = new HashMap.identity(); | 41 var clones = new HashMap.identity(); |
41 bool mustCopy = false; | 42 bool mustCopy = false; |
42 | 43 |
43 Object findSlot(value) { | 44 Object findSlot(value) { |
44 return clones.putIfAbsent(value, () => null); | 45 return clones.putIfAbsent(value, () => null); |
45 } | 46 } |
46 | 47 |
47 writeSlot(original, x) { clones[original] = x; } | 48 writeSlot(original, x) { |
| 49 clones[original] = x; |
| 50 } |
48 | 51 |
49 walk(e) { | 52 walk(e) { |
50 if (e == null) return e; | 53 if (e == null) return e; |
51 if (e is bool) return e; | 54 if (e is bool) return e; |
52 if (e is num) return e; | 55 if (e is num) return e; |
53 if (e is String) return e; | 56 if (e is String) return e; |
54 if (e is DateTime) return e; | 57 if (e is DateTime) return e; |
55 | 58 |
56 if (isJavaScriptRegExp(e)) { | 59 if (isJavaScriptRegExp(e)) { |
57 // TODO(sra). | 60 // TODO(sra). |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) { | 101 convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) { |
99 this.mustCopy = mustCopy; | 102 this.mustCopy = mustCopy; |
100 var copy = walk(object); | 103 var copy = walk(object); |
101 return copy; | 104 return copy; |
102 } | 105 } |
103 } | 106 } |
104 | 107 |
105 final _dateConstructor = js.JsNative.getProperty(window, "Date"); | 108 final _dateConstructor = js.JsNative.getProperty(window, "Date"); |
106 final _regexConstructor = js.JsNative.getProperty(window, "RegExp"); | 109 final _regexConstructor = js.JsNative.getProperty(window, "RegExp"); |
107 | 110 |
108 bool isJavaScriptDate(value) => value is js.JSObject && js.JsNative.instanceof(v
alue, _dateConstructor); | 111 bool isJavaScriptDate(value) => |
109 bool isJavaScriptRegExp(value) => value is js.JSObject && js.JsNative.instanceof
(value, _regexConstructor); | 112 value is js.JSObject && js.JsNative.instanceof(value, _dateConstructor); |
| 113 bool isJavaScriptRegExp(value) => |
| 114 value is js.JSObject && js.JsNative.instanceof(value, _regexConstructor); |
110 bool isJavaScriptArray(value) => value is js.JSArray; | 115 bool isJavaScriptArray(value) => value is js.JSArray; |
111 | 116 |
112 final _object = js.JsNative.getProperty(window, "Object"); | 117 final _object = js.JsNative.getProperty(window, "Object"); |
113 final _getPrototypeOf = js.JsNative.getProperty(_object, "getPrototypeOf"); | 118 final _getPrototypeOf = js.JsNative.getProperty(_object, "getPrototypeOf"); |
114 _getProto(object) { | 119 _getProto(object) { |
115 return _getPrototypeOf(object); | 120 return _getPrototypeOf(object); |
116 } | 121 } |
| 122 |
117 final _objectProto = js.JsNative.getProperty(_object, "prototype"); | 123 final _objectProto = js.JsNative.getProperty(_object, "prototype"); |
118 | 124 |
119 bool isJavaScriptSimpleObject(value) { | 125 bool isJavaScriptSimpleObject(value) { |
120 if (value is! js.JSObject) return false; | 126 if (value is! js.JSObject) return false; |
121 var proto = _getProto(value); | 127 var proto = _getProto(value); |
122 return proto == _objectProto || proto == null; | 128 return proto == _objectProto || proto == null; |
123 } | 129 } |
124 | 130 |
125 // TODO(jacobr): this makes little sense unless we are doing something | 131 // TODO(jacobr): this makes little sense unless we are doing something |
126 // ambitious to make Dartium and Dart2Js interop well with each other. | 132 // ambitious to make Dartium and Dart2Js interop well with each other. |
127 bool isImmutableJavaScriptArray(value) => | 133 bool isImmutableJavaScriptArray(value) => |
128 isJavaScriptArray(value) && js.JsNative.getProperty(value, "immutable$list")
!= null; | 134 isJavaScriptArray(value) && |
| 135 js.JsNative.getProperty(value, "immutable$list") != null; |
129 | 136 |
130 final _promiseConstructor = js.JsNative.getProperty(window, 'Promise'); | 137 final _promiseConstructor = js.JsNative.getProperty(window, 'Promise'); |
131 bool isJavaScriptPromise(value) => value is js.JSObject && identical(js.JsNative
.getProperty(value, 'constructor'), _promiseConstructor); | 138 bool isJavaScriptPromise(value) => |
| 139 value is js.JSObject && |
| 140 identical( |
| 141 js.JsNative.getProperty(value, 'constructor'), _promiseConstructor); |
132 | 142 |
133 Future convertNativePromiseToDartFuture(js.JSObject promise) { | 143 Future convertNativePromiseToDartFuture(js.JSObject promise) { |
134 var completer = new Completer(); | 144 var completer = new Completer(); |
135 var newPromise = js.JsNative.callMethod(js.JsNative.callMethod(promise, | 145 var newPromise = js.JsNative.callMethod( |
136 "then", [js.allowInterop((result) => completer.complete(result))]), | 146 js.JsNative.callMethod(promise, "then", |
137 "catch", [js.allowInterop((result) => completer.completeError(result))]); | 147 [js.allowInterop((result) => completer.complete(result))]), |
| 148 "catch", |
| 149 [js.allowInterop((result) => completer.completeError(result))]); |
138 return completer.future; | 150 return completer.future; |
139 } | 151 } |
140 | 152 |
141 convertDartToNative_DateTime(DateTime date) { | 153 convertDartToNative_DateTime(DateTime date) { |
142 return date; | 154 return date; |
143 } | 155 } |
144 | 156 |
145 /// Creates a Dart Rectangle from a Javascript object with properties | 157 /// Creates a Dart Rectangle from a Javascript object with properties |
146 /// left, top, width and height or a 4 element array of integers. Used internall
y in Dartium. | 158 /// left, top, width and height or a 4 element array of integers. Used internall
y in Dartium. |
147 Rectangle make_dart_rectangle(r) { | 159 Rectangle make_dart_rectangle(r) { |
(...skipping 13 matching lines...) Expand all Loading... |
161 // is the Dartium only version it uses dart:js. | 173 // is the Dartium only version it uses dart:js. |
162 // TODO(alanknight): This could probably be unified with the dart2js conversions | 174 // TODO(alanknight): This could probably be unified with the dart2js conversions |
163 // code in html_common and be more general. | 175 // code in html_common and be more general. |
164 convertDartToNative_Dictionary(Map dict) { | 176 convertDartToNative_Dictionary(Map dict) { |
165 if (dict == null) return null; | 177 if (dict == null) return null; |
166 var jsObject = js.JsNative.newObject(); | 178 var jsObject = js.JsNative.newObject(); |
167 dict.forEach((String key, value) { | 179 dict.forEach((String key, value) { |
168 if (value is List) { | 180 if (value is List) { |
169 var jsArray = js.JsNative.newArray(); | 181 var jsArray = js.JsNative.newArray(); |
170 value.forEach((elem) { | 182 value.forEach((elem) { |
171 jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem); | 183 jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem) : elem); |
172 }); | 184 }); |
173 js.JsNative.setProperty(jsObject, key, jsArray); | 185 js.JsNative.setProperty(jsObject, key, jsArray); |
174 } else { | 186 } else { |
175 js.JsNative.setProperty(jsObject, key, value); | 187 js.JsNative.setProperty(jsObject, key, value); |
176 } | 188 } |
177 }); | 189 }); |
178 return jsObject; | 190 return jsObject; |
179 } | 191 } |
180 | 192 |
181 // Creates a Dart class to allow members of the Map to be fetched (as if getters
exist). | 193 // Creates a Dart class to allow members of the Map to be fetched (as if getters
exist). |
182 // TODO(terry): Need to use package:js but that's a problem in dart:html. Talk t
o | 194 // TODO(terry): Need to use package:js but that's a problem in dart:html. Talk t
o |
183 // Jacob about how to do this properly using dart:js. | 195 // Jacob about how to do this properly using dart:js. |
184 class _ReturnedDictionary { | 196 class _ReturnedDictionary { |
185 Map _values; | 197 Map _values; |
186 | 198 |
187 noSuchMethod(Invocation invocation) { | 199 noSuchMethod(Invocation invocation) { |
188 var key = MirrorSystem.getName(invocation.memberName); | 200 var key = MirrorSystem.getName(invocation.memberName); |
189 if (invocation.isGetter) { | 201 if (invocation.isGetter) { |
190 return _values[key]; | 202 return _values[key]; |
191 } else if (invocation.isSetter && key.endsWith('=')) { | 203 } else if (invocation.isSetter && key.endsWith('=')) { |
192 key = key.substring(0, key.length-1); | 204 key = key.substring(0, key.length - 1); |
193 _values[key] = invocation.positionalArguments[0]; | 205 _values[key] = invocation.positionalArguments[0]; |
194 } | 206 } |
195 } | 207 } |
196 | 208 |
197 Map get toMap => _values; | 209 Map get toMap => _values; |
198 | 210 |
199 _ReturnedDictionary(Map value): _values = value != null ? value : {}; | 211 _ReturnedDictionary(Map value) : _values = value != null ? value : {}; |
200 } | 212 } |
201 | 213 |
202 // Helper function to wrapped a returned dictionary from blink to a Dart looking | 214 // Helper function to wrapped a returned dictionary from blink to a Dart looking |
203 // class. | 215 // class. |
204 convertNativeDictionaryToDartDictionary(values) { | 216 convertNativeDictionaryToDartDictionary(values) { |
205 if (values is! Map) { | 217 if (values is! Map) { |
206 // TODO(jacobr): wish wwe didn't have to do this. | 218 // TODO(jacobr): wish wwe didn't have to do this. |
207 values = convertNativeToDart_SerializedScriptValue(values); | 219 values = convertNativeToDart_SerializedScriptValue(values); |
208 } | 220 } |
209 return values != null ? new _ReturnedDictionary(values) : null; | 221 return values != null ? new _ReturnedDictionary(values) : null; |
210 } | 222 } |
211 | 223 |
212 convertNativeToDart_Dictionary(values) => convertNativeToDart_SerializedScriptVa
lue(values); | 224 convertNativeToDart_Dictionary(values) => |
| 225 convertNativeToDart_SerializedScriptValue(values); |
213 | 226 |
214 // Conversion function place holder (currently not used in dart2js or dartium). | 227 // Conversion function place holder (currently not used in dart2js or dartium). |
215 List convertDartToNative_StringArray(List<String> input) => input; | 228 List convertDartToNative_StringArray(List<String> input) => input; |
216 | 229 |
217 // Converts a Dart list into a JsArray. For the Dartium version only. | 230 // Converts a Dart list into a JsArray. For the Dartium version only. |
218 convertDartToNative_List(List input) => new js.JsArray()..addAll(input); | 231 convertDartToNative_List(List input) => new js.JsArray()..addAll(input); |
219 | 232 |
220 // Incredibly slow implementation to lookup the runtime type for an object. | 233 // Incredibly slow implementation to lookup the runtime type for an object. |
221 // Fortunately, performance doesn't matter much as the results are cached | 234 // Fortunately, performance doesn't matter much as the results are cached |
222 // as long as the object being looked up has a valid prototype. | 235 // as long as the object being looked up has a valid prototype. |
223 // TODO(jacobr): we should track the # of lookups to ensure that things aren't | 236 // TODO(jacobr): we should track the # of lookups to ensure that things aren't |
224 // going off the rails due to objects with null prototypes, etc. | 237 // going off the rails due to objects with null prototypes, etc. |
225 // Note: unlike all other methods in this class, here we intentionally use | 238 // Note: unlike all other methods in this class, here we intentionally use |
226 // the old JsObject types to bootstrap the new typed bindings. | 239 // the old JsObject types to bootstrap the new typed bindings. |
227 Type lookupType(js.JsObject jsObject, bool isElement) { | 240 Type lookupType(js.JsObject jsObject, bool isElement) { |
228 try { | 241 try { |
229 // TODO(jacobr): add static methods that return the runtime type of the patch | 242 // TODO(jacobr): add static methods that return the runtime type of the patc
h |
230 // class so that this code works as expected. | 243 // class so that this code works as expected. |
231 if (jsObject is js.JsArray) { | 244 if (jsObject is js.JsArray) { |
232 return js.JSArray.instanceRuntimeType; | 245 return js.JSArray.instanceRuntimeType; |
233 } | 246 } |
234 if (jsObject is js.JsFunction) { | 247 if (jsObject is js.JsFunction) { |
235 return js.JSFunction.instanceRuntimeType; | 248 return js.JSFunction.instanceRuntimeType; |
236 } | 249 } |
237 | 250 |
238 var constructor = js.JsNative.getProperty(jsObject, 'constructor'); | 251 var constructor = js.JsNative.getProperty(jsObject, 'constructor'); |
239 if (constructor == null) { | 252 if (constructor == null) { |
240 // Perfectly valid case for JavaScript objects where __proto__ has | 253 // Perfectly valid case for JavaScript objects where __proto__ has |
241 // intentionally been set to null. | 254 // intentionally been set to null. |
242 // We should track and warn about this case as peformance will be poor. | 255 // We should track and warn about this case as peformance will be poor. |
243 return js.JSObject.instanceRuntimeType; | 256 return js.JSObject.instanceRuntimeType; |
244 } | 257 } |
245 var jsTypeName = js.JsNative.getProperty(constructor, 'name'); | 258 var jsTypeName = js.JsNative.getProperty(constructor, 'name'); |
246 if (jsTypeName is! String || jsTypeName.length == 0) { | 259 if (jsTypeName is! String || jsTypeName.length == 0) { |
247 // Not an html type. | 260 // Not an html type. |
248 return js.JSObject.instanceRuntimeType; | 261 return js.JSObject.instanceRuntimeType; |
249 } | 262 } |
250 | 263 |
251 var dartClass_instance; | 264 var dartClass_instance; |
252 var customElementClass = null; | 265 var customElementClass = null; |
253 var extendsTag = ""; | 266 var extendsTag = ""; |
254 | 267 |
255 Type type = getHtmlCreateType(jsTypeName); | 268 Type type = getHtmlCreateType(jsTypeName); |
256 if (type != null) return type; | 269 if (type != null) return type; |
257 | 270 |
258 // Start walking the prototype chain looking for a JS class. | 271 // Start walking the prototype chain looking for a JS class. |
259 var prototype = js.JsNative.getProperty(jsObject, '__proto__'); | 272 var prototype = js.JsNative.getProperty(jsObject, '__proto__'); |
260 while (prototype != null) { | 273 while (prototype != null) { |
261 // We're a Dart class that's pointing to a JS class. | 274 // We're a Dart class that's pointing to a JS class. |
262 var constructor = js.JsNative.getProperty(prototype, 'constructor'); | 275 var constructor = js.JsNative.getProperty(prototype, 'constructor'); |
263 if (constructor != null) { | 276 if (constructor != null) { |
264 jsTypeName = js.JsNative.getProperty(constructor, 'name'); | 277 jsTypeName = js.JsNative.getProperty(constructor, 'name'); |
265 type = getHtmlCreateType(jsTypeName); | 278 type = getHtmlCreateType(jsTypeName); |
266 if (type != null) return type; | 279 if (type != null) return type; |
267 } | 280 } |
268 prototype = js.JsNative.getProperty(prototype, '__proto__'); | 281 prototype = js.JsNative.getProperty(prototype, '__proto__'); |
269 } | 282 } |
270 } catch (e) { | 283 } catch (e) { |
271 // This case can happen for cross frame objects. | 284 // This case can happen for cross frame objects. |
272 if (js.JsNative.hasProperty(e, "postMessage")) { | 285 if (js.JsNative.hasProperty(e, "postMessage")) { |
273 // assume this is a Window. To match Dart2JS, separate conversion code | 286 // assume this is a Window. To match Dart2JS, separate conversion code |
274 // in dart:html will switch the wrapper to a cross frame window as | 287 // in dart:html will switch the wrapper to a cross frame window as |
275 // required. | 288 // required. |
276 // TODO(jacobr): we could consider removing this code completely. | 289 // TODO(jacobr): we could consider removing this code completely. |
277 return Window.instanceRuntimeType; | 290 return Window.instanceRuntimeType; |
278 } | 291 } |
279 } | 292 } |
280 return js.JSObject.instanceRuntimeType; | 293 return js.JSObject.instanceRuntimeType; |
281 } | 294 } |
OLD | NEW |