| Index: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
|
| diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
|
| index 4a8670bd65178dbd7914982df4ac822520dfaddc..9f4449d9553869aa66619d446048d105f9597664 100644
|
| --- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
|
| +++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
|
| @@ -391,7 +391,28 @@ bool hasField(type, name) => _hasSigEntry(type, _fieldSig, name);
|
|
|
| final _extensionType = JS('', 'Symbol("extensionType")');
|
|
|
| -getExtensionType(obj) => JS('', '#[#]', obj, _extensionType);
|
| +getExtensionType(obj) {
|
| + var result = JS('', '#[#]', obj, _extensionType);
|
| + if (result != null) return result;
|
| +
|
| + if (JS('bool', 'typeof # != "object" || # instanceof #.Object', obj, obj,
|
| + global_)) {
|
| + return null;
|
| + }
|
| +
|
| + // This is an object from another frame. Check to see if we have registered
|
| + // an extension in case this is a DOM/native type.
|
| + var jsType = JS('', '#.constructor', obj);
|
| + var tag = JS('', '#.name', jsType);
|
| + if (JS('bool', '#.has(#)', _extMap, tag)) {
|
| + var jsProto = JS('', '#.__proto__', obj);
|
| + var dartType = JS('', '#.get(#)', _extMap, tag);
|
| + _installExtension(jsType, jsProto, dartType);
|
| + return dartType;
|
| + }
|
| +
|
| + return null;
|
| +}
|
|
|
| final dartx = JS('', 'dartx');
|
|
|
| @@ -437,6 +458,15 @@ void _installPropertiesForObject(jsProto) {
|
| }
|
| }
|
|
|
| +var _extMap;
|
| +
|
| +_cacheExtension(jsProto, dartType) {
|
| + if (_extMap == null) _extMap = JS('', 'new Map()');
|
| + // TODO(vsm): Make this work on non-Chrome browsers.
|
| + var tag = JS('', '#.constructor.name', jsProto);
|
| + JS('', '#.set(#, #)', _extMap, tag, dartType);
|
| +}
|
| +
|
| /// Copy symbols from the prototype of the source to destination.
|
| /// These are the only properties safe to copy onto an existing public
|
| /// JavaScript class.
|
| @@ -452,13 +482,21 @@ registerExtension(jsType, dartExtType) => JS(
|
| // broken.
|
| if (!jsProto) return;
|
|
|
| - $_installProperties(jsProto, $dartExtType, jsProto[$_extensionType]);
|
| + $_cacheExtension(jsProto, $dartExtType);
|
|
|
| // Mark the JS type's instances so we can easily check for extensions.
|
| - jsProto[$_extensionType] = $dartExtType;
|
| + $_installExtension(jsType, jsProto, dartExtType);
|
| +})()''');
|
| +
|
| +_installExtension(jsType, jsProto, dartType) => JS(
|
| + '',
|
| + '''(() => {
|
| + $_installProperties(jsProto, $dartType, jsProto[$_extensionType]);
|
|
|
| + // Mark the JS type's instances so we can easily check for extensions.
|
| + jsProto[$_extensionType] = $dartType;
|
| function updateSig(sigF) {
|
| - let originalDesc = $getOwnPropertyDescriptor($dartExtType, sigF);
|
| + let originalDesc = $getOwnPropertyDescriptor($dartType, sigF);
|
| if (originalDesc === void 0) return;
|
| let originalSigFn = originalDesc.get;
|
| $assert_(originalSigFn);
|
| @@ -468,7 +506,7 @@ registerExtension(jsType, dartExtType) => JS(
|
| updateSig($_fieldSig);
|
| updateSig($_getterSig);
|
| updateSig($_setterSig);
|
| -})()''');
|
| + })()''');
|
|
|
| ///
|
| /// Mark a concrete type as implementing extension methods.
|
|
|