mirror of
https://github.com/Polymer/polymer.git
synced 2026-08-19 01:14:44 -05:00
Ensure properties and observers are interleaved per behavior
This commit is contained in:
+32
-57
@@ -155,58 +155,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
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 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
/** @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 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
/**
|
||||
* @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*
|
||||
|
||||
@@ -230,14 +230,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
}
|
||||
// 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 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
* @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 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
static createProperties(props) {
|
||||
static createProperties(props) {
|
||||
for (let p in props) {
|
||||
createPropertyFromConfig(this.prototype, p, props[p], props);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user