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

Unified Diff: tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate

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, 3 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 | « tests/html/html.status ('k') | tools/dom/templates/html/impl/impl_Node.darttemplate » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
diff --git a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
index 1feee18a678b0d8758e11800a10676e5ad2b1200..25a632da63d862ff321b4bd21ef0108775ad365c 100644
--- a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
@@ -221,6 +221,39 @@ $if DARTIUM
// If we're an element then everything is okay.
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;
+ }
$endif
@Experimental()
@@ -281,68 +314,71 @@ $else
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]);
+ }
$endif
}
« no previous file with comments | « tests/html/html.status ('k') | tools/dom/templates/html/impl/impl_Node.darttemplate » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698