Skip to content

Commit

Permalink
Behavior property copying fixes
Browse files Browse the repository at this point in the history
* ensure element has `is` on prototype early as this is sometimes checked in user code.
* ensure properties copied onto elements from info/behaviors are forced to configurable so they can be re-configured by later behaviors.
* add `_noAccessors` optimization for faster property copying
  • Loading branch information
Steven Orvell committed Nov 10, 2018
1 parent 65a3149 commit 310c7ea
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
21 changes: 14 additions & 7 deletions lib/legacy/class.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ const excludeOnInfo = {
beforeRegister: true,
registered: true,
attributeChanged: true,
behaviors: true
behaviors: true,
_noAccessors: true
};

const excludeOnBehaviors = Object.assign({
Expand All @@ -41,13 +42,19 @@ const excludeOnBehaviors = Object.assign({
}, excludeOnInfo);

function copyProperties(source, target, excludeProps) {
const noAccessors = source._noAccessors;
for (let p in source) {
// NOTE: cannot copy `excludeProps` methods onto prototype at least because
// `super.ready` must be called and is not included in the user fn.
if (!(p in excludeProps)) {
let pd = Object.getOwnPropertyDescriptor(source, p);
if (pd) {
Object.defineProperty(target, p, pd);
if (noAccessors) {
target[p] = source[p];
} else {
let pd = Object.getOwnPropertyDescriptor(source, p);
if (pd) {
// ensure property is configurable so that a later behavior can
// re-configure it.
pd.configurable = true;
Object.defineProperty(target, p, pd);
}
}
}
}
Expand Down Expand Up @@ -498,6 +505,6 @@ export const Class = function(info, mixin) {
LegacyElementMixin(HTMLElement);
klass = GenerateClassFromInfo(info, klass, info.behaviors);
// decorate klass with registration info
klass.is = info.is;
klass.is = klass.prototype.is = info.is;
return klass;
};
29 changes: 29 additions & 0 deletions test/unit/behaviors.html
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,20 @@
behaviors: [window.BehaviorA]
});

Polymer({
is: 'no-accessors-behavior',
behaviors: [{
_noAccessors: true,
properties: {
nug: String
},
foo: function() {},
bar: true
}],
_noAccessors: true,
zot: 'zot'
});

</script>

<test-fixture id="single">
Expand Down Expand Up @@ -447,6 +461,12 @@
</template>
</test-fixture>

<test-fixture id="no-accessors-behavior">
<template>
<no-accessors-behavior></no-accessors-behavior>
</template>
</test-fixture>

<script type="module">
import { Polymer } from '../../polymer-legacy.js';

Expand Down Expand Up @@ -501,6 +521,15 @@
assert.notOk(el.listeners);
});

test('properties on objects marked with `_noAccessors` are copied to class', function() {
const el = fixture('no-accessors-behavior');
assert.ok(el.foo);
assert.isTrue(el.bar);
assert.equal(el.zot, 'zot');
el.setAttribute('nug', 'nug');
assert.equal(el.nug, 'nug');
});

});

suite('behavior.registered', function() {
Expand Down

0 comments on commit 310c7ea

Please sign in to comment.