| 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 |