Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: lib/src/js_impl.dart

Issue 615913004: Add @jsify annotation. Support automatically proxying Lists and Maps to Dart in Proxies. Support co… (Closed) Base URL: https://github.com/dart-lang/js-interop.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | lib/src/js_list.dart » ('j') | lib/src/js_list.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 * This library contains semi-private APIs for implementing typed interfaces and 6 * This library contains semi-private APIs for implementing typed interfaces and
7 * exports. 7 * exports.
8 */ 8 */
9 library js.impl; 9 library js.impl;
10 10
11 import 'dart:js'; 11 import 'dart:js';
12 import 'package:js/src/js_object_map.dart';
13 import 'package:js/src/js_list.dart';
14 import 'dart:collection';
12 export 'dart:js' show context, JsObject; 15 export 'dart:js' show context, JsObject;
13 16
14 const DART_OBJECT_PROPERTY = '__dart_object__'; 17 const DART_OBJECT_PROPERTY = '__dart_object__';
15 18
16 /** 19 /**
17 * The base class of Dart interfaces for JavaScript objects. 20 * The base class of Dart interfaces for JavaScript objects.
18 */ 21 */
19 abstract class JsInterface { 22 abstract class JsInterface {
20 23
21 final JsObject _jsObject; 24 final JsObject _jsObject;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 } 66 }
64 return proxy; 67 return proxy;
65 } 68 }
66 // TODO: check that `o` is transferrable? 69 // TODO: check that `o` is transferrable?
67 return o; 70 return o;
68 } 71 }
69 72
70 // Exported Dart Object -> JsObject 73 // Exported Dart Object -> JsObject
71 final Expando<JsObject> _exportedProxies = new Expando<JsObject>(); 74 final Expando<JsObject> _exportedProxies = new Expando<JsObject>();
72 75
73 dynamic toDart(dynamic o) { 76 /**
77 * Converts a JS value (primitive or [JsObject]) to Dart.
78 *
79 * If [o] is a JS object with a associated Dart proxy class, an instance of that
80 * proxy class is returned. If [o] is an exported Dart object, the original
81 * Dart object is returned. The Dart object is stored as a reference on the
82 * JS object so that the same Dart object is returned from subsequent calls
83 * to [toDart].
84 *
85 * If [o] is a JS object with no associated proxy class, the [fallbackType] is
86 * used to create a transient wrapper of the correct type. Currently [Map] is
87 * the only supported fallback type. [Future] and [Stream] are planned fallback
88 * types.
89 */
90 dynamic toDart(dynamic o, [Symbol fallbackType]) {
74 if (o == null) return o; 91 if (o == null) return o;
75 if (o is num || o is String || o is bool || o is DateTime) return o; 92 if (o is num || o is String || o is bool || o is DateTime) return o;
76 93
77 var wrapper = o[DART_OBJECT_PROPERTY]; 94 if (o is JsObject) {
78 if (wrapper == null) { 95 var wrapper = o[DART_OBJECT_PROPERTY];
79 // look up JsInterface factory 96 if (wrapper == null) {
80 var jsConstructor = o['constructor'] as JsObject; 97 if (o is JsArray) {
81 var dartConstructor = _interfaceConstructors[jsConstructor]; 98 wrapper = new JsList.fromJsObject(o);
82 if (dartConstructor == null) { 99 } else {
83 throw new ArgumentError("Could not convert ${o.runtimeType}($o) to Dart"); 100 // look up JsInterface factory
101 var jsConstructor = o['constructor'] as JsObject;
102 var dartConstructor = _interfaceConstructors[jsConstructor];
103 if (dartConstructor != null) {
104 wrapper = dartConstructor(o);
105 }
106 }
107 if (wrapper != null) {
108 o[DART_OBJECT_PROPERTY] = wrapper;
109 }
84 } 110 }
85 wrapper = dartConstructor(o); 111 if (wrapper != null) return wrapper;
86 o[DART_OBJECT_PROPERTY] = wrapper; 112
113 // no wrapper, handle fallback cases
114 if (fallbackType == #Map) {
115 return new JsObjectMap.fromJsObject(o);
116 }
87 } 117 }
88 return wrapper; 118 throw new ArgumentError("Could not convert ${o.runtimeType}($o) to Dart");
119 }
120
121 JsObject _obj = context['Object'];
122
123 dynamic jsify(data) {
124 if ((data is! Map) && (data is! Iterable)) {
125 throw new ArgumentError("object must be a Map or Iterable");
126 }
127
128 if (data is JsObject || data is JsObjectMap || data is JsList) return data;
129
130 var _convertedObjects = new HashMap.identity();
131
132 _convert(o) {
133 if (_convertedObjects.containsKey(o)) {
134 return _convertedObjects[o];
135 }
136 if (o is Map) {
137 final convertedMap = new JsObject(_obj);
138 _convertedObjects[o] = convertedMap;
139 for (var key in o.keys) {
140 convertedMap[key] = _convert(o[key]);
141 }
142 return convertedMap;
143 } else if (o is Iterable) {
144 var convertedList = new JsArray();
145 _convertedObjects[o] = convertedList;
146 convertedList.addAll(o.map(_convert));
147 return convertedList;
148 } else {
149 return toJs(o);
150 }
151 }
152
153 return _convert(data);
89 } 154 }
90 155
91 // Dart Type -> JS constructorfor proxy 156 // Dart Type -> JS constructorfor proxy
92 final Map<Type, JsObject> _exportedConstructors = <Type, JsObject>{}; 157 final Map<Type, JsObject> _exportedConstructors = <Type, JsObject>{};
93 158
94 registerJsConstructorForType(Type type, JsObject constructor) { 159 registerJsConstructorForType(Type type, JsObject constructor) {
95 _exportedConstructors[type] = constructor; 160 _exportedConstructors[type] = constructor;
96 } 161 }
97 162
98 // Dart Type -> JS constructorfor proxy 163 // Dart Type -> JS constructorfor proxy
99 final Map<JsFunction, InterfaceFactory> _interfaceConstructors = 164 final Map<JsFunction, InterfaceFactory> _interfaceConstructors =
100 <JsFunction, InterfaceFactory>{}; 165 <JsFunction, InterfaceFactory>{};
101 166
102 typedef JsInterface InterfaceFactory(JsObject o); 167 typedef JsInterface InterfaceFactory(JsObject o);
103 168
104 registerFactoryForJsConstructor(JsObject constructor, 169 registerFactoryForJsConstructor(JsObject constructor,
105 InterfaceFactory factory) { 170 InterfaceFactory factory) {
106 _interfaceConstructors[constructor] = factory; 171 _interfaceConstructors[constructor] = factory;
107 } 172 }
108 173
109 dynamic getOptionalArg(JsObject args, String name) { 174 dynamic getOptionalArg(JsObject args, String name) {
110 if (args == null) return null; 175 if (args == null) return null;
111 return args[name]; 176 return args[name];
112 } 177 }
113 178
114 JsObject getPath(String path) => 179 JsObject getPath(String path) =>
115 path.split('.').fold(context, (JsObject o, p) => o[p]); 180 path.split('.').fold(context, (JsObject o, p) => o[p]);
OLDNEW
« no previous file with comments | « no previous file | lib/src/js_list.dart » ('j') | lib/src/js_list.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698