web_components: fix extending another custom element
R=sigmund@google.com
Review URL: https://codereview.chromium.org//341003002
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/web_components@37472 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/lib/interop.dart b/lib/interop.dart
index 415c7fe..de1ef2f 100644
--- a/lib/interop.dart
+++ b/lib/interop.dart
@@ -29,7 +29,17 @@
var upgrader = document.createElementUpgrader(
dartType, extendsTag: extendsTag);
- _doc.callMethod('_registerDartTypeUpgrader', [tagName, upgrader.upgrade]);
+
+ // Unfortunately the dart:html upgrader will throw on an already-upgraded
+ // element, so we need to duplicate the type check to prevent that.
+ // An element can be upgraded twice if it extends another element and calls
+ // createdCallback on the superclass. Since that's a valid use case we must
+ // wrap at both levels, and guard against it here.
+ upgradeElement(e) {
+ if (e.runtimeType != dartType) upgrader.upgrade(e);
+ }
+
+ _doc.callMethod('_registerDartTypeUpgrader', [tagName, upgradeElement]);
}
/// This function is mainly used to save resources. By default, we save a log of
diff --git a/pubspec.yaml b/pubspec.yaml
index b8f0bc5..223d136 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: web_components
-version: 0.3.5-dev.2
+version: 0.3.5-dev.3
author: Polymer.dart Authors <web-ui-dev@dartlang.org>
homepage: https://www.dartlang.org/polymer-dart/
description: >
diff --git a/test/interop_test.dart b/test/interop_test.dart
index cbad6e1..20cce29 100644
--- a/test/interop_test.dart
+++ b/test/interop_test.dart
@@ -120,6 +120,16 @@
expect(c.x, 7);
expect(c.wrapperCount, 6);
});
+
+ test('element can extend another element', () {
+ registerDartType('x-e', XEWrapper);
+ context.callMethod('addE');
+
+ var e = document.querySelector('x-e');
+ expect(e is XEWrapper, isTrue);
+ expect(e.x, 8);
+ expect(e.y, 9);
+ });
}
int _count = 0;
@@ -145,3 +155,9 @@
class XDWrapper extends HtmlElement with Wrapper {
XDWrapper.created() : super.created();
}
+
+class XEWrapper extends HtmlElement with Wrapper {
+ XEWrapper.created() : super.created();
+
+ int get y => new JsObject.fromBrowserObject(this)['y'];
+}
diff --git a/test/interop_test.html b/test/interop_test.html
index 036c7ef..d49dcb9 100644
--- a/test/interop_test.html
+++ b/test/interop_test.html
@@ -32,13 +32,23 @@
D.prototype.inc = function() { this.x = counter++; };
D.prototype.createdCallback = function() { this.inc(); };
+ var E = { prototype: Object.create(D.prototype) };
+ E.prototype.inc2 = function() {
+ this.y = counter++;
+ };
+ E.prototype.createdCallback = function() {
+ D.prototype.createdCallback.call(this);
+ this.inc2();
+ };
+
document.registerElement('x-a', A);
document.registerElement('x-b', B);
document.registerElement('x-d', D);
+ document.registerElement('x-e', E);
function registerC() {
var proto = Object.create(HTMLElement.prototype, {
- inc: { value: function() { this.x = counter++; } },
+ inc: { value: function() { this.x = counter++; } },
createdCallback: {
value: function() { this.inc(); },
configurable: true},
@@ -57,6 +67,9 @@
function addD() {
document.body.appendChild(document.createElement('x-d'));
}
+ function addE() {
+ document.body.appendChild(document.createElement('x-e'));
+ }
</script>
<x-a id="i1"></x-a>
<div is="x-b" id="i2"></div>