Skip to content

Commit

Permalink
Ensure properties and observers are interleaved per behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Orvell committed Nov 14, 2018
1 parent 6f3057e commit bbf1acc
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 67 deletions.
89 changes: 32 additions & 57 deletions lib/legacy/class.html
Original file line number Diff line number Diff line change
Expand Up @@ -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.]
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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*
Expand Down
17 changes: 7 additions & 10 deletions lib/mixins/element-mixin.html
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -352,7 +349,7 @@
* @protected
* @override
*/
static createProperties(props) {
static createProperties(props) {
for (let p in props) {
createPropertyFromConfig(this.prototype, p, props[p], props);
}
Expand Down

0 comments on commit bbf1acc

Please sign in to comment.