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

Side by Side Diff: sdk/lib/html/html_common/conversions_dartium.dart

Issue 1409743003: Hide internal methods like wrap_jso from the dart:html public interface (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Review fixes Created 5 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
OLDNEW
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"]);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 } 68 }
69 69
70 /// Creates a Dart Rectangle from a Javascript object with properties 70 /// Creates a Dart Rectangle from a Javascript object with properties
71 /// left, top, width and height. Used internally in Dartium. 71 /// left, top, width and height. Used internally in Dartium.
72 Rectangle make_dart_rectangle(r) => 72 Rectangle make_dart_rectangle(r) =>
73 r == null ? null : new Rectangle( 73 r == null ? null : new Rectangle(
74 js.JsNative.getProperty(r, 'left'), 74 js.JsNative.getProperty(r, 'left'),
75 js.JsNative.getProperty(r, 'top'), 75 js.JsNative.getProperty(r, 'top'),
76 js.JsNative.getProperty(r, 'width'), 76 js.JsNative.getProperty(r, 'width'),
77 js.JsNative.getProperty(r, 'height')); 77 js.JsNative.getProperty(r, 'height'));
78
79 // Converts a flat Dart map into a JavaScript object with properties this is
80 // is the Dartium only version it uses dart:js.
81 // TODO(alanknight): This could probably be unified with the dart2js conversions
82 // code in html_common and be more general.
83 convertDartToNative_Dictionary(Map dict) {
84 if (dict == null) return null;
85 var jsObject = new js.JsObject(js.JsNative.getProperty(js.context, 'Object'));
86 dict.forEach((String key, value) {
87 if (value is List) {
88 var jsArray = new js.JsArray();
89 value.forEach((elem) {
90 jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem);
91 });
92 jsObject[key] = jsArray;
93 } else {
94 jsObject[key] = value;
95 }
96 });
97 return jsObject;
98 }
99
100 // Conversion function place holder (currently not used in dart2js or dartium).
101 List convertDartToNative_StringArray(List<String> input) => input;
102
103 // Converts a Dart list into a JsArray. For the Dartium version only.
104 convertDartToNative_List(List input) => new js.JsArray()..addAll(input);
105
106 /// Find the underlying JS object for a dart:html Dart object.
107 unwrap_jso(dartClass_instance) => js.unwrap_jso(dartClass_instance);
108
109 // Flag to disable JS interop asserts. Setting to false will speed up the
110 // wrap_jso calls.
111 bool interop_checks = false;
112
113 /// Wrap a JS object with an instance of the matching dart:html class. Used only in Dartium.
114 wrap_jso(jsObject) {
115 try {
116 if (jsObject is! js.JsObject || jsObject == null) {
117 // JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
118 // or it's a simple type.
119 return jsObject;
120 }
121
122 var wrapper = js.getDartHtmlWrapperFor(jsObject);
123 // if we have a wrapper return the Dart instance.
124 if (wrapper != null) {
125 var customElementClass = getCustomElementType(wrapper.blink_jsObject);
126 if (wrapper.runtimeType != customElementClass && customElementClass != nul l) {
127 if (wrapper.runtimeType == HtmlElement && !wrapper.isBadUpgrade) {
128 // We're a Dart instance if it's HtmlElement and we have a customEleme nt
129 // class then we need to upgrade.
130 if (customElementClass != null) {
131 var dartClass_instance;
132 try {
133 dartClass_instance = _blink.Blink_Utils.constructElement(customEle mentClass, jsObject);
134 } finally {
135 dartClass_instance.blink_jsObject = jsObject;
136 return dartClass_instance;
137 }
138 }
139 }
140 }
141
142 return wrapper;
143 }
144
145 if (jsObject is js.JsArray) {
146 var wrappingList = new DartHtmlWrappingList(jsObject);
147 js.setDartHtmlWrapperFor(jsObject, wrappingList);
148 return wrappingList;
149 }
150
151 // Try the most general type conversions on it.
152 // TODO(alanknight): We may be able to do better. This maintains identity,
153 // which is useful, but expensive. And if we nest something that only
154 // this conversion handles, how does that work? e.g. a list of maps of eleme nts.
155 var converted = convertNativeToDart_SerializedScriptValue(jsObject);
156 if (!identical(converted, jsObject)) {
157 return converted;
158 }
159
160 var constructor = js.JsNative.getProperty(jsObject, 'constructor');
161 if (constructor == null) {
162 // Perfectly valid case for JavaScript objects where __proto__ has
163 // intentionally been set to null.
164 js.setDartHtmlWrapperFor(jsObject, jsObject);
165 return jsObject;
166 }
167 var jsTypeName = js.JsNative.getProperty(constructor, 'name');
168 if (jsTypeName is! String || jsTypeName.length == 0) {
169 // Not an html type.
170 js.setDartHtmlWrapperFor(jsObject, jsObject);
171 return jsObject;
172 }
173
174 var dartClass_instance;
175 var customElementClass = null;
176 var extendsTag = "";
177 var custom = getCustomElementEntry(jsObject);
178 if (custom != null) {
179 customElementClass = custom['type'];
180 extendsTag = custom['extends'];
181 }
182
183 // Custom Element to upgrade.
184 // Only allow custome elements to be created in the html or svg default
185 // namespace.
186 var defaultNS = jsObject['namespaceURI'] == 'http://www.w3.org/1999/xhtml' | |
187 jsObject['namespaceURI'] == 'http://www.w3.org/2000/svg';
188 if (customElementClass != null && extendsTag == "" && defaultNS) {
189 try {
190 dartClass_instance = _blink.Blink_Utils.constructElement(customElementCl ass, jsObject);
191 } finally {
192 dartClass_instance.blink_jsObject = jsObject;
193 js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
194 }
195 } else {
196 var func = getHtmlCreateFunction(jsTypeName);
197 if (func == null) {
198 if (jsTypeName == 'auto-binding') {
199 func = getHtmlCreateFunction("HTMLTemplateElement");
200 } else if (jsObject.toString() == "[object HTMLElement]") {
201 // One last ditch effort could be a JS custom element.
202 func = getHtmlCreateFunction("HTMLElement");
203 }
204 }
205 if (func != null) {
206 dartClass_instance = func();
207 dartClass_instance.blink_jsObject = jsObject;
208 js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
209 }
210 }
211
212 // TODO(jacobr): cache that this is not a dart:html JS class.
213 return dartClass_instance;
214 } catch(e, stacktrace){
215 if (interop_checks) {
216 if (e is DebugAssertException)
217 window.console.log("${e.message}\n ${stacktrace}");
218 else
219 window.console.log("${stacktrace}");
220 }
221 }
222
223 return null;
224 }
225
226 /**
227 * Create Dart class that maps to the JS Type, add the JsObject as an expando
228 * on the Dart class and return the created Dart class.
229 */
230 wrap_jso_no_SerializedScriptvalue(jsObject) {
231 try {
232 if (jsObject is! js.JsObject || jsObject == null) {
233 // JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
234 // or it's a simple type.
235 return jsObject;
236 }
237
238 // TODO(alanknight): With upgraded custom elements this causes a failure bec ause
239 // we need a new wrapper after the type changes. We could possibly invalidat e this
240 // if the constructor name didn't match?
241 var wrapper = js.getDartHtmlWrapperFor(jsObject);
242 if (wrapper != null) {
243 return wrapper;
244 }
245
246 if (jsObject is js.JsArray) {
247 var wrappingList = new DartHtmlWrappingList(jsObject);
248 js.setDartHtmlWrapperFor(jsObject, wrappingList);
249 return wrappingList;
250 }
251
252 var constructor = js.JsNative.getProperty(jsObject, 'constructor');
253 if (constructor == null) {
254 // Perfectly valid case for JavaScript objects where __proto__ has
255 // intentionally been set to null.
256 js.setDartHtmlWrapperFor(jsObject, jsObject);
257 return jsObject;
258 }
259 var jsTypeName = js.JsNative.getProperty(constructor, 'name');
260 if (jsTypeName is! String || jsTypeName.length == 0) {
261 // Not an html type.
262 js.setDartHtmlWrapperFor(jsObject, jsObject);
263 return jsObject;
264 }
265
266 var func = getHtmlCreateFunction(jsTypeName);
267 if (func != null) {
268 var dartClass_instance = func();
269 dartClass_instance.blink_jsObject = jsObject;
270 js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
271 return dartClass_instance;
272 }
273 return jsObject;
274 } catch(e, stacktrace){
275 if (interop_checks) {
276 if (e is DebugAssertException)
277 window.console.log("${e.message}\n ${stacktrace}");
278 else
279 window.console.log("${stacktrace}");
280 }
281 }
282
283 return null;
284 }
285
286 /**
287 * Create Dart class that maps to the JS Type that is the JS type being
288 * extended using JS interop createCallback (we need the base type of the
289 * custom element) not the Dart created constructor.
290 */
291 wrap_jso_custom_element(jsObject) {
292 try {
293 if (jsObject is! js.JsObject) {
294 // JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
295 return jsObject;
296 }
297
298 // Find out what object we're extending.
299 var objectName = jsObject.toString();
300 // Expect to see something like '[object HTMLElement]'.
301 if (!objectName.startsWith('[object ')) {
302 return jsObject;
303 }
304
305 var extendsClass = objectName.substring(8, objectName.length - 1);
306 var func = getHtmlCreateFunction(extendsClass);
307 if (interop_checks)
308 debug_or_assert("func != null name = ${extendsClass}", func != null);
309 var dartClass_instance = func();
310 dartClass_instance.blink_jsObject = jsObject;
311 return dartClass_instance;
312 } catch(e, stacktrace){
313 if (interop_checks) {
314 if (e is DebugAssertException)
315 window.console.log("${e.message}\n ${stacktrace}");
316 else
317 window.console.log("${stacktrace}");
318 }
319
320 // Problem?
321 return null;
322 }
323 }
324
325 getCustomElementEntry(element) {
326 var hasAttribute = false;
327
328 var jsObject;
329 var tag = "";
330 var runtimeType = element.runtimeType;
331 if (runtimeType == HtmlElement) {
332 tag = element.localName;
333 } else if (runtimeType == TemplateElement) {
334 // Data binding with a Dart class.
335 tag = element.attributes['is'];
336 } else if (runtimeType == js.JsObjectImpl) {
337 // It's a Polymer core element (written in JS).
338 // Make sure it's an element anything else we can ignore.
339 if (element.hasProperty('nodeType') && element['nodeType'] == 1) {
340 if (js.JsNative.callMethod(element, 'hasAttribute', ['is'])) {
341 hasAttribute = true;
342 // It's data binding use the is attribute.
343 tag = js.JsNative.callMethod(element, 'getAttribute', ['is']);
344 } else {
345 // It's a custom element we want the local name.
346 tag = element['localName'];
347 }
348 }
349 } else {
350 throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, e xpected HtmlElement/HtmlTemplate/JsObjectImpl.');
351 }
352
353 var entry = _knownCustomElements[tag];
354 if (entry != null) {
355 // If there's an 'is' attribute then check if the extends tag registered
356 // matches the tag if so then return the entry that's registered for this
357 // extendsTag or if there's no 'is' tag then return the entry found.
358 if ((hasAttribute && entry['extends'] == tag) || !hasAttribute) {
359 return entry;
360 }
361 }
362
363 return null;
364 }
365
366 // List of known tagName to DartClass for custom elements, used for upgrade.
367 var _knownCustomElements = new Map<String, Map<Type, String>>();
368
369 void addCustomElementType(String tagName, Type dartClass, [String extendTag]) {
370 _knownCustomElements[tagName] =
371 {'type': dartClass, 'extends': extendTag != null ? extendTag : "" };
372 }
373
374 Type getCustomElementType(object) {
375 var entry = getCustomElementEntry(object);
376 if (entry != null) {
377 return entry['type'];
378 }
379 return null;
380 }
381
382 /**
383 * Wraps a JsArray and will call wrap_jso on its entries.
384 */
385 class DartHtmlWrappingList extends ListBase implements NativeFieldWrapperClass2 {
386 DartHtmlWrappingList(this.blink_jsObject);
387
388 final js.JsArray blink_jsObject;
389
390 operator [](int index) => wrap_jso(js.JsNative.getArrayIndex(blink_jsObject, i ndex));
391
392 operator []=(int index, value) => blink_jsObject[index] = value;
393
394 int get length => blink_jsObject.length;
395 int set length(int newLength) => blink_jsObject.length = newLength;
396 }
OLDNEW
« no previous file with comments | « sdk/lib/html/html_common/conversions_dart2js.dart ('k') | sdk/lib/html/html_common/html_common.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698