diff --git a/lib/legacy/class.html b/lib/legacy/class.html
index e416c58314..ce3ff47214 100644
--- a/lib/legacy/class.html
+++ b/lib/legacy/class.html
@@ -155,58 +155,6 @@
return list;
}
- function mergePropertyInfo(a, b) {
- if ('value' in b) {
- a.value = b.value;
- // ensure property value is always overridden.
- } else if ('value' in a) {
- delete a.value;
- }
- if (typeof b === 'function') {
- a.type = b;
- return;
- }
- if ('type' in b) {
- a.type = b.type;
- }
- // readOnly: cannot become false and takes on `computed` value
- a.readOnly = a.readOnly || Boolean(a.computed) || b.readOnly || Boolean(b.computed);
- // computed: first in wins
- if ('computed' in b) {
- a.computed = a.computed || b.computed;
- }
- // reflectToAttribute: cannot become false
- if ('reflectToAttribute' in b) {
- a.reflectToAttribute = a.reflectToAttribute || b.reflectToAttribute;
- }
- // notify: cannot become false (only install 1x)
- if ('notify' in b) {
- a.notify = a.notify || b.notify;
- }
- // make this an array
- if ('observer' in b) {
- if (!a.observer) {
- a.observer = b.observer;
- // we have both: make array and push onto
- } else {
- if (!Array.isArray(a.observer)) {
- a.observer = [a.observer];
- }
- a.observer.push(b.observer);
- }
- }
- }
-
- // Note, the properties in `b` are normalized before being merged
- // into `a`. This means that given `a == {}` and `b == {foo: String}`,
- // the result is `a == {foo: {type: String}}`.
- function mergeElementProperties(a, b) {
- for (let p in b) {
- a[p] = a[p] || {};
- mergePropertyInfo(a[p], b[p]);
- }
- }
-
/* Note about construction and extension of legacy classes.
[Changed in Q4 2018 to optimize performance.]
@@ -245,15 +193,43 @@
/** @private */
class PolymerGenerated extends Base {
+ // explicitly not calling super._finalizeClass
+ static _finalizeClass() {
+ // if calling via a subclass that hasn't been generated, pass through to super
+ if (!this.hasOwnProperty('generatedFrom')) {
+ super._finalizeClass();
+ } else {
+ // interleave properties and observers per behavior and `info`
+ if (behaviorList) {
+ for (let i=0, b; i < behaviorList.length; i++) {
+ b = behaviorList[i];
+ if (b.properties) {
+ this.createProperties(b.properties);
+ }
+ if (b.observers) {
+ this.createObservers(b.observers, b.properties);
+ }
+ }
+ }
+ if (info.properties) {
+ this.createProperties(info.properties);
+ }
+ if (info.observers) {
+ this.createObservers(info.observers, info.properties);
+ }
+ // make sure to prepare the element template
+ this._prepareTemplate();
+ }
+ }
+
static get properties() {
const properties = {};
if (behaviorList) {
- for (let i=0, b; i < behaviorList.length; i++) {
- b = behaviorList[i];
- mergeElementProperties(properties, b.properties);
+ for (let i=0; i < behaviorList.length; i++) {
+ Object.assign(properties, behaviorList[i].properties);
}
}
- mergeElementProperties(properties, info.properties);
+ Object.assign(properties, info.properties);
return properties;
}
@@ -289,7 +265,6 @@
/**
* @return {void}
*/
- // Called on element prototype
_registered() {
/* NOTE: `beforeRegister` is called here for bc, but the behavior
is different than in 1.x. In 1.0, the method was called *after*
diff --git a/lib/mixins/element-mixin.html b/lib/mixins/element-mixin.html
index c9b5e189c8..ae7db9423d 100644
--- a/lib/mixins/element-mixin.html
+++ b/lib/mixins/element-mixin.html
@@ -230,14 +230,7 @@
}
// always add observer
if (info.observer) {
- if (Array.isArray(info.observer)) {
- for (let i=0; i < info.observer.length; i++) {
- const o = info.observer[i];
- proto._createPropertyObserver(name, o, allProps[o]);
- }
- } else {
- proto._createPropertyObserver(name, info.observer, allProps[info.observer]);
- }
+ proto._createPropertyObserver(name, info.observer, allProps[info.observer]);
}
// always create the mapping from attribute back to property for deserialization.
proto._addPropertyToAttributeMap(name);
@@ -324,12 +317,16 @@
* @override
* @suppress {missingProperties} Interfaces in closure do not inherit statics, but classes do
*/
- static _finalizeClass() {
+ static _finalizeClass() {
super._finalizeClass();
const observers = ownObservers(this);
if (observers) {
this.createObservers(observers, this._properties);
}
+ this._prepareTemplate();
+ }
+
+ static _prepareTemplate() {
// note: create "working" template that is finalized at instance time
let template = /** @type {PolymerElementConstructor} */ (this).template;
if (template) {
@@ -352,7 +349,7 @@
* @protected
* @override
*/
- static createProperties(props) {
+ static createProperties(props) {
for (let p in props) {
createPropertyFromConfig(this.prototype, p, props[p], props);
}