Skip to content

Commit

Permalink
Introduce opt-out per class for legacyNoObservedAttributes
Browse files Browse the repository at this point in the history
This is necessary when a native property that sets an attribute should be observeable via attributeChangedCallback or Polymer property reflection (e.g. element.tabIndex = 5 setting the `tabindex` attribute).
  • Loading branch information
Steven Orvell committed Jan 30, 2020
1 parent 63addd3 commit eaca195
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
11 changes: 7 additions & 4 deletions lib/legacy/legacy-element-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ export const LegacyElementMixin = dedupingMixin((base) => {
this.__isUpgradeDisabled;
/** @type {boolean|undefined} */
this.__needsAttributesAtConnected;
/** @type {boolean|undefined} */
this._legacyForceObservedAttributes;
}

/**
Expand Down Expand Up @@ -143,7 +145,7 @@ export const LegacyElementMixin = dedupingMixin((base) => {

/** @override */
setAttribute(name, value) {
if (legacyNoObservedAttributes) {
if (legacyNoObservedAttributes && !this._legacyForceObservedAttributes) {
const oldValue = this.getAttribute(name);
super.setAttribute(name, value);
// value coerced to String for closure's benefit
Expand All @@ -155,7 +157,7 @@ export const LegacyElementMixin = dedupingMixin((base) => {

/** @override */
removeAttribute(name) {
if (legacyNoObservedAttributes) {
if (legacyNoObservedAttributes && !this._legacyForceObservedAttributes) {
const oldValue = this.getAttribute(name);
super.removeAttribute(name);
this.__attributeReaction(name, oldValue, null);
Expand All @@ -166,7 +168,8 @@ export const LegacyElementMixin = dedupingMixin((base) => {

// NOTE: Inlined for perf from version of DisableUpgradeMixin.
static get observedAttributes() {
if (legacyNoObservedAttributes) {
if (legacyNoObservedAttributes && !this._legacyForceObservedAttributes) {
this.prototype._legacyForceObservedAttributes = this._legacyForceObservedAttributes;
// Ensure this element is property registered with the telemetry system.
if (!this.hasOwnProperty(JSCompiler_renameProperty('__observedAttributes', this))) {
this.__observedAttributes = [];
Expand Down Expand Up @@ -315,7 +318,7 @@ export const LegacyElementMixin = dedupingMixin((base) => {
this.root = /** @type {HTMLElement} */(this);
this.created();
// Pull all attribute values 1x if `legacyNoObservedAttributes` is set.
if (legacyNoObservedAttributes) {
if (legacyNoObservedAttributes && !this._legacyForceObservedAttributes) {
if (this.hasAttributes()) {
this._takeAttributes();
// Element created from scratch or parser generated
Expand Down
4 changes: 4 additions & 0 deletions lib/legacy/polymer-fn.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ const Polymer = function(info) {
} else {
klass = Polymer.Class(info);
}
// Copy opt out for `legacyNoObservedAttributes` from info object to class.
if (info._legacyForceObservedAttributes) {
klass._legacyForceObservedAttributes = info._legacyForceObservedAttributes;
}
customElements.define(klass.is, /** @type {!HTMLElement} */(klass));
return klass;
};
Expand Down
22 changes: 21 additions & 1 deletion test/unit/legacy-noattributes.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
zot: Boolean,
shouldIf: Boolean,
camelCase: String,
disabled: {type: Boolean, value: 'true'}
disabled: {type: Boolean, value: 'true'},
},
created() {
this.wasCreated = true;
Expand All @@ -74,6 +74,17 @@
this.attrInfo = {name, old, value};
}
});

Polymer({
is: 'x-native-attrs-force',
_legacyForceObservedAttributes: true,
properties: {
tabindex: {reflectToAttribute: true, type: Number}
},
attributeChanged(name, old, value) {
this.attributeChangedCalled = true;
}
});
</script>
</dom-module>

Expand Down Expand Up @@ -106,6 +117,15 @@
assert.ok(def);
});

test('native property observeable via `attributeChanged` and reflected to property when `_forceObservedAttributes` is used', () => {
el = document.createElement('x-native-attrs-force');
document.body.appendChild(el);
el.tabIndex = 5;
assert.ok(el.attributeChangedCalled);
assert.equal(el.tabindex, 5);
document.body.removeChild(el);
});

test('static attributes', () => {
assert.equal(el.foo, 'foo');
assert.equal(el.$.child1.getAttribute('foo'), 'x-attrs.foo');
Expand Down

0 comments on commit eaca195

Please sign in to comment.