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

Unified Diff: sdk/lib/html/dartium/html_dartium.dart

Side-by-side diff isn't available for this file because of its large size.
Issue 1373563004: Fixed a bunch of failure cases for custom elements (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Merged 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:
Download patch
« no previous file with comments | « no previous file | tests/html/html.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/html/dartium/html_dartium.dart
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index e3fd55935e258c7468af046e97643c3861f11a27..f262bece629db2d77d216fdc6b13a69d4fbc8834 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -20171,6 +20171,39 @@ class HtmlDocument extends Document {
return isElement ? jsClassName : null;
}
+ /**
+ * Does this CustomElement class have:
+ *
+ * - a created constructor with no arguments?
+ * - a created constructor with a super.created() initializer?
+ *
+ * e.g., MyCustomClass.created() : super.created();
+ */
+ bool _hasCreatedConstructor(ClassMirror classMirror) {
+ var createdParametersValid = false;
+ var superCreatedCalled = false;
+ var className = MirrorSystem.getName(classMirror.simpleName);
+ var methodMirror = classMirror.declarations[new Symbol("$className.created")];
+ if (methodMirror != null) {
+ createdParametersValid = methodMirror.parameters.length == 0;
+
+ // Get the created constructor source and look at the initializer;
+ // Must call super.created() if not its as an error.
+ var createdSource = methodMirror.source;
+ RegExp regExp = new RegExp(r":(.*?)(;|}|\n)");
+ var match = regExp.firstMatch(createdSource);
+ superCreatedCalled = match.input.substring(match.start,match.end).contains("super.created()");
+ }
+
+ if (!superCreatedCalled) {
+ throw new DomException.jsInterop('created constructor initializer must call super.created()');
+ } else if (!createdParametersValid) {
+ throw new DomException.jsInterop('created constructor must have no parameters');
+ }
+
+ return true;
+ }
+
@Experimental()
/**
* Register a custom subclass of Element to be instantiatable by the DOM.
@@ -20225,68 +20258,71 @@ class HtmlDocument extends Document {
throw new DomException.jsInterop("HierarchyRequestError: Only HTML elements can be customized.");
}
- // Start the hookup the JS way create an <x-foo> element that extends the
- // <x-base> custom element. Inherit its prototype and signal what tag is
- // inherited:
- //
- // var myProto = Object.create(HTMLElement.prototype);
- // var myElement = document.registerElement('x-foo', {prototype: myProto});
- var baseElement = js.context[jsClassName];
- if (baseElement == null) {
- // Couldn't find the HTML element so use a generic one.
- baseElement = js.context['HTMLElement'];
- }
- var elemProto = js.context['Object'].callMethod("create", [baseElement['prototype']]);
-
- // TODO(terry): Hack to stop recursion re-creating custom element when the
- // created() constructor of the custom element does e.g.,
- //
- // MyElement.created() : super.created() {
- // this.innerHtml = "<b>I'm an x-foo-with-markup!</b>";
- // }
- //
- // sanitizing causes custom element to created recursively
- // until stack overflow.
- //
- // See https://github.com/dart-lang/sdk/issues/23666
- int creating = 0;
- elemProto['createdCallback'] = new js.JsFunction.withThis(($this) {
- if (_getJSClassName(reflectClass(customElementClass).superclass) != null && creating < 2) {
- creating++;
-
- var dartClass;
- try {
- dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
- } catch (e) {
- dartClass = null;
- } finally {
- // Need to remember the Dart class that was created for this custom so
- // return it and setup the blink_jsObject to the $this that we'll be working
- // with as we talk to blink.
- $this['dart_class'] = dartClass;
-
- creating--;
- }
- }
- });
- elemProto['attributeChangedCallback'] = new js.JsFunction.withThis(($this, attrName, oldVal, newVal) {
- if ($this["dart_class"] != null && $this['dart_class'].attributeChanged != null) {
- $this['dart_class'].attributeChanged(attrName, oldVal, newVal);
- }
- });
- elemProto['attachedCallback'] = new js.JsFunction.withThis(($this) {
- if ($this["dart_class"] != null && $this['dart_class'].attached != null) {
- $this['dart_class'].attached();
+ if (_hasCreatedConstructor(classMirror)) {
+ // Start the hookup the JS way create an <x-foo> element that extends the
+ // <x-base> custom element. Inherit its prototype and signal what tag is
+ // inherited:
+ //
+ // var myProto = Object.create(HTMLElement.prototype);
+ // var myElement = document.registerElement('x-foo', {prototype: myProto});
+ var baseElement = js.context[jsClassName];
+ if (baseElement == null) {
+ // Couldn't find the HTML element so use a generic one.
+ baseElement = js.context['HTMLElement'];
}
- });
- elemProto['detachedCallback'] = new js.JsFunction.withThis(($this) {
- if ($this["dart_class"] != null && $this['dart_class'].detached != null) {
- $this['dart_class'].detached();
- }
- });
- // document.registerElement('x-foo', {prototype: elemProto, extends: extendsTag});
- var jsMap = new js.JsObject.jsify({'prototype': elemProto, 'extends': extendsTag});
- js.context['document'].callMethod('registerElement', [tag, jsMap]);
+ var elemProto = js.context['Object'].callMethod("create", [baseElement['prototype']]);
+
+ // TODO(terry): Hack to stop recursion re-creating custom element when the
+ // created() constructor of the custom element does e.g.,
+ //
+ // MyElement.created() : super.created() {
+ // this.innerHtml = "<b>I'm an x-foo-with-markup!</b>";
+ // }
+ //
+ // sanitizing causes custom element to created recursively
+ // until stack overflow.
+ //
+ // See https://github.com/dart-lang/sdk/issues/23666
+ int creating = 0;
+ elemProto['createdCallback'] = new js.JsFunction.withThis(($this) {
+ if (_getJSClassName(reflectClass(customElementClass).superclass) != null && creating < 2) {
+ creating++;
+
+ var dartClass;
+ try {
+ dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
+ } catch (e) {
+ dartClass = HtmlElement.internalCreateHtmlElement();
+ throw e;
+ } finally {
+ // Need to remember the Dart class that was created for this custom so
+ // return it and setup the blink_jsObject to the $this that we'll be working
+ // with as we talk to blink.
+ $this['dart_class'] = dartClass;
+
+ creating--;
+ }
+ }
+ });
+ elemProto['attributeChangedCallback'] = new js.JsFunction.withThis(($this, attrName, oldVal, newVal) {
+ if ($this["dart_class"] != null && $this['dart_class'].attributeChanged != null) {
+ $this['dart_class'].attributeChanged(attrName, oldVal, newVal);
+ }
+ });
+ elemProto['attachedCallback'] = new js.JsFunction.withThis(($this) {
+ if ($this["dart_class"] != null && $this['dart_class'].attached != null) {
+ $this['dart_class'].attached();
+ }
+ });
+ elemProto['detachedCallback'] = new js.JsFunction.withThis(($this) {
+ if ($this["dart_class"] != null && $this['dart_class'].detached != null) {
+ $this['dart_class'].detached();
+ }
+ });
+ // document.registerElement('x-foo', {prototype: elemProto, extends: extendsTag});
+ var jsMap = new js.JsObject.jsify({'prototype': elemProto, 'extends': extendsTag});
+ js.context['document'].callMethod('registerElement', [tag, jsMap]);
+ }
}
/** *Deprecated*: use [registerElement] instead. */
@@ -27928,7 +27964,14 @@ class _ChildNodeListLazy extends ListBase<Node> implements NodeListWrapper {
class Node extends EventTarget {
// Custom element created callback.
- Node._created() : super._created();
+ Node._created() : super._created() {
+ // By this point blink_jsObject should be setup if it's not then we weren't
+ // called by the registerElement createdCallback - probably created() was
+ // called directly which is verboten.
+ if (this.blink_jsObject == null) {
+ throw new DomException.jsInterop("the created constructor cannot be called directly");
+ }
+ }
/**
* A modifiable list of this node's children.
@@ -37076,10 +37119,10 @@ class Url extends NativeFieldWrapperClass2 implements UrlUtils {
if ((blob_OR_source_OR_stream is Blob || blob_OR_source_OR_stream == null)) {
return _blink.BlinkURL.instance.createObjectURL_Callback_1_(unwrap_jso(blob_OR_source_OR_stream));
}
- if ((blob_OR_source_OR_stream is MediaSource)) {
+ if ((blob_OR_source_OR_stream is MediaStream)) {
return _blink.BlinkURL.instance.createObjectURL_Callback_1_(unwrap_jso(blob_OR_source_OR_stream));
}
- if ((blob_OR_source_OR_stream is MediaStream)) {
+ if ((blob_OR_source_OR_stream is MediaSource)) {
return _blink.BlinkURL.instance.createObjectURL_Callback_1_(unwrap_jso(blob_OR_source_OR_stream));
}
throw new ArgumentError("Incorrect number or type of arguments");
« no previous file with comments | « no previous file | tests/html/html.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698