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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/html/html_common/conversions_dartium.dart
diff --git a/sdk/lib/html/html_common/conversions_dartium.dart b/sdk/lib/html/html_common/conversions_dartium.dart
index 28225f089f67d3c50b89df6cf00a9db5a88c8778..1ed1e1348bc7e99415693b7b4965eae05555d696 100644
--- a/sdk/lib/html/html_common/conversions_dartium.dart
+++ b/sdk/lib/html/html_common/conversions_dartium.dart
@@ -75,3 +75,322 @@ Rectangle make_dart_rectangle(r) =>
js.JsNative.getProperty(r, 'top'),
js.JsNative.getProperty(r, 'width'),
js.JsNative.getProperty(r, 'height'));
+
+// Converts a flat Dart map into a JavaScript object with properties this is
+// is the Dartium only version it uses dart:js.
+// TODO(alanknight): This could probably be unified with the dart2js conversions
+// code in html_common and be more general.
+convertDartToNative_Dictionary(Map dict) {
+ if (dict == null) return null;
+ var jsObject = new js.JsObject(js.JsNative.getProperty(js.context, 'Object'));
+ dict.forEach((String key, value) {
+ if (value is List) {
+ var jsArray = new js.JsArray();
+ value.forEach((elem) {
+ jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem);
+ });
+ jsObject[key] = jsArray;
+ } else {
+ jsObject[key] = value;
+ }
+ });
+ return jsObject;
+}
+
+// Conversion function place holder (currently not used in dart2js or dartium).
+List convertDartToNative_StringArray(List<String> input) => input;
+
+// Converts a Dart list into a JsArray. For the Dartium version only.
+convertDartToNative_List(List input) => new js.JsArray()..addAll(input);
+
+/// Find the underlying JS object for a dart:html Dart object.
+unwrap_jso(dartClass_instance) => js.unwrap_jso(dartClass_instance);
+
+// Flag to disable JS interop asserts. Setting to false will speed up the
+// wrap_jso calls.
+bool interop_checks = false;
+
+/// Wrap a JS object with an instance of the matching dart:html class. Used only in Dartium.
+wrap_jso(jsObject) {
+ try {
+ if (jsObject is! js.JsObject || jsObject == null) {
+ // JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
+ // or it's a simple type.
+ return jsObject;
+ }
+
+ var wrapper = js.getDartHtmlWrapperFor(jsObject);
+ // if we have a wrapper return the Dart instance.
+ if (wrapper != null) {
+ var customElementClass = getCustomElementType(wrapper.blink_jsObject);
+ if (wrapper.runtimeType != customElementClass && customElementClass != null) {
+ if (wrapper.runtimeType == HtmlElement && !wrapper.isBadUpgrade) {
+ // We're a Dart instance if it's HtmlElement and we have a customElement
+ // class then we need to upgrade.
+ if (customElementClass != null) {
+ var dartClass_instance;
+ try {
+ dartClass_instance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
+ } finally {
+ dartClass_instance.blink_jsObject = jsObject;
+ return dartClass_instance;
+ }
+ }
+ }
+ }
+
+ return wrapper;
+ }
+
+ if (jsObject is js.JsArray) {
+ var wrappingList = new DartHtmlWrappingList(jsObject);
+ js.setDartHtmlWrapperFor(jsObject, wrappingList);
+ return wrappingList;
+ }
+
+ // Try the most general type conversions on it.
+ // TODO(alanknight): We may be able to do better. This maintains identity,
+ // which is useful, but expensive. And if we nest something that only
+ // this conversion handles, how does that work? e.g. a list of maps of elements.
+ var converted = convertNativeToDart_SerializedScriptValue(jsObject);
+ if (!identical(converted, jsObject)) {
+ return converted;
+ }
+
+ var constructor = js.JsNative.getProperty(jsObject, 'constructor');
+ if (constructor == null) {
+ // Perfectly valid case for JavaScript objects where __proto__ has
+ // intentionally been set to null.
+ js.setDartHtmlWrapperFor(jsObject, jsObject);
+ return jsObject;
+ }
+ var jsTypeName = js.JsNative.getProperty(constructor, 'name');
+ if (jsTypeName is! String || jsTypeName.length == 0) {
+ // Not an html type.
+ js.setDartHtmlWrapperFor(jsObject, jsObject);
+ return jsObject;
+ }
+
+ var dartClass_instance;
+ var customElementClass = null;
+ var extendsTag = "";
+ var custom = getCustomElementEntry(jsObject);
+ if (custom != null) {
+ customElementClass = custom['type'];
+ extendsTag = custom['extends'];
+ }
+
+ // Custom Element to upgrade.
+ // Only allow custome elements to be created in the html or svg default
+ // namespace.
+ var defaultNS = jsObject['namespaceURI'] == 'http://www.w3.org/1999/xhtml' ||
+ jsObject['namespaceURI'] == 'http://www.w3.org/2000/svg';
+ if (customElementClass != null && extendsTag == "" && defaultNS) {
+ try {
+ dartClass_instance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
+ } finally {
+ dartClass_instance.blink_jsObject = jsObject;
+ js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
+ }
+ } else {
+ var func = getHtmlCreateFunction(jsTypeName);
+ if (func == null) {
+ if (jsTypeName == 'auto-binding') {
+ func = getHtmlCreateFunction("HTMLTemplateElement");
+ } else if (jsObject.toString() == "[object HTMLElement]") {
+ // One last ditch effort could be a JS custom element.
+ func = getHtmlCreateFunction("HTMLElement");
+ }
+ }
+ if (func != null) {
+ dartClass_instance = func();
+ dartClass_instance.blink_jsObject = jsObject;
+ js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
+ }
+ }
+
+ // TODO(jacobr): cache that this is not a dart:html JS class.
+ return dartClass_instance;
+ } catch(e, stacktrace){
+ if (interop_checks) {
+ if (e is DebugAssertException)
+ window.console.log("${e.message}\n ${stacktrace}");
+ else
+ window.console.log("${stacktrace}");
+ }
+ }
+
+ return null;
+}
+
+/**
+ * Create Dart class that maps to the JS Type, add the JsObject as an expando
+ * on the Dart class and return the created Dart class.
+ */
+wrap_jso_no_SerializedScriptvalue(jsObject) {
+ try {
+ if (jsObject is! js.JsObject || jsObject == null) {
+ // JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
+ // or it's a simple type.
+ return jsObject;
+ }
+
+ // TODO(alanknight): With upgraded custom elements this causes a failure because
+ // we need a new wrapper after the type changes. We could possibly invalidate this
+ // if the constructor name didn't match?
+ var wrapper = js.getDartHtmlWrapperFor(jsObject);
+ if (wrapper != null) {
+ return wrapper;
+ }
+
+ if (jsObject is js.JsArray) {
+ var wrappingList = new DartHtmlWrappingList(jsObject);
+ js.setDartHtmlWrapperFor(jsObject, wrappingList);
+ return wrappingList;
+ }
+
+ var constructor = js.JsNative.getProperty(jsObject, 'constructor');
+ if (constructor == null) {
+ // Perfectly valid case for JavaScript objects where __proto__ has
+ // intentionally been set to null.
+ js.setDartHtmlWrapperFor(jsObject, jsObject);
+ return jsObject;
+ }
+ var jsTypeName = js.JsNative.getProperty(constructor, 'name');
+ if (jsTypeName is! String || jsTypeName.length == 0) {
+ // Not an html type.
+ js.setDartHtmlWrapperFor(jsObject, jsObject);
+ return jsObject;
+ }
+
+ var func = getHtmlCreateFunction(jsTypeName);
+ if (func != null) {
+ var dartClass_instance = func();
+ dartClass_instance.blink_jsObject = jsObject;
+ js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
+ return dartClass_instance;
+ }
+ return jsObject;
+ } catch(e, stacktrace){
+ if (interop_checks) {
+ if (e is DebugAssertException)
+ window.console.log("${e.message}\n ${stacktrace}");
+ else
+ window.console.log("${stacktrace}");
+ }
+ }
+
+ return null;
+}
+
+/**
+ * Create Dart class that maps to the JS Type that is the JS type being
+ * extended using JS interop createCallback (we need the base type of the
+ * custom element) not the Dart created constructor.
+ */
+wrap_jso_custom_element(jsObject) {
+ try {
+ if (jsObject is! js.JsObject) {
+ // JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
+ return jsObject;
+ }
+
+ // Find out what object we're extending.
+ var objectName = jsObject.toString();
+ // Expect to see something like '[object HTMLElement]'.
+ if (!objectName.startsWith('[object ')) {
+ return jsObject;
+ }
+
+ var extendsClass = objectName.substring(8, objectName.length - 1);
+ var func = getHtmlCreateFunction(extendsClass);
+ if (interop_checks)
+ debug_or_assert("func != null name = ${extendsClass}", func != null);
+ var dartClass_instance = func();
+ dartClass_instance.blink_jsObject = jsObject;
+ return dartClass_instance;
+ } catch(e, stacktrace){
+ if (interop_checks) {
+ if (e is DebugAssertException)
+ window.console.log("${e.message}\n ${stacktrace}");
+ else
+ window.console.log("${stacktrace}");
+ }
+
+ // Problem?
+ return null;
+ }
+}
+
+getCustomElementEntry(element) {
+ var hasAttribute = false;
+
+ var jsObject;
+ var tag = "";
+ var runtimeType = element.runtimeType;
+ if (runtimeType == HtmlElement) {
+ tag = element.localName;
+ } else if (runtimeType == TemplateElement) {
+ // Data binding with a Dart class.
+ tag = element.attributes['is'];
+ } else if (runtimeType == js.JsObjectImpl) {
+ // It's a Polymer core element (written in JS).
+ // Make sure it's an element anything else we can ignore.
+ if (element.hasProperty('nodeType') && element['nodeType'] == 1) {
+ if (js.JsNative.callMethod(element, 'hasAttribute', ['is'])) {
+ hasAttribute = true;
+ // It's data binding use the is attribute.
+ tag = js.JsNative.callMethod(element, 'getAttribute', ['is']);
+ } else {
+ // It's a custom element we want the local name.
+ tag = element['localName'];
+ }
+ }
+ } else {
+ throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObjectImpl.');
+ }
+
+ var entry = _knownCustomElements[tag];
+ if (entry != null) {
+ // If there's an 'is' attribute then check if the extends tag registered
+ // matches the tag if so then return the entry that's registered for this
+ // extendsTag or if there's no 'is' tag then return the entry found.
+ if ((hasAttribute && entry['extends'] == tag) || !hasAttribute) {
+ return entry;
+ }
+ }
+
+ return null;
+}
+
+// List of known tagName to DartClass for custom elements, used for upgrade.
+var _knownCustomElements = new Map<String, Map<Type, String>>();
+
+void addCustomElementType(String tagName, Type dartClass, [String extendTag]) {
+ _knownCustomElements[tagName] =
+ {'type': dartClass, 'extends': extendTag != null ? extendTag : "" };
+}
+
+Type getCustomElementType(object) {
+ var entry = getCustomElementEntry(object);
+ if (entry != null) {
+ return entry['type'];
+ }
+ return null;
+}
+
+/**
+ * Wraps a JsArray and will call wrap_jso on its entries.
+ */
+class DartHtmlWrappingList extends ListBase implements NativeFieldWrapperClass2 {
+ DartHtmlWrappingList(this.blink_jsObject);
+
+ final js.JsArray blink_jsObject;
+
+ operator [](int index) => wrap_jso(js.JsNative.getArrayIndex(blink_jsObject, index));
+
+ operator []=(int index, value) => blink_jsObject[index] = value;
+
+ int get length => blink_jsObject.length;
+ int set length(int newLength) => blink_jsObject.length = newLength;
+}
« 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