| 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");
|
|
|