mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Behavior property copying fixes
* 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
This commit is contained in:
@@ -30,7 +30,8 @@ const excludeOnInfo = {
|
|||||||
beforeRegister: true,
|
beforeRegister: true,
|
||||||
registered: true,
|
registered: true,
|
||||||
attributeChanged: true,
|
attributeChanged: true,
|
||||||
behaviors: true
|
behaviors: true,
|
||||||
|
_noAccessors: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const excludeOnBehaviors = Object.assign({
|
const excludeOnBehaviors = Object.assign({
|
||||||
@@ -41,13 +42,19 @@ const excludeOnBehaviors = Object.assign({
|
|||||||
}, excludeOnInfo);
|
}, excludeOnInfo);
|
||||||
|
|
||||||
function copyProperties(source, target, excludeProps) {
|
function copyProperties(source, target, excludeProps) {
|
||||||
|
const noAccessors = source._noAccessors;
|
||||||
for (let p in source) {
|
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)) {
|
if (!(p in excludeProps)) {
|
||||||
let pd = Object.getOwnPropertyDescriptor(source, p);
|
if (noAccessors) {
|
||||||
if (pd) {
|
target[p] = source[p];
|
||||||
Object.defineProperty(target, p, pd);
|
} 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,6 +505,6 @@ export const Class = function(info, mixin) {
|
|||||||
LegacyElementMixin(HTMLElement);
|
LegacyElementMixin(HTMLElement);
|
||||||
klass = GenerateClassFromInfo(info, klass, info.behaviors);
|
klass = GenerateClassFromInfo(info, klass, info.behaviors);
|
||||||
// decorate klass with registration info
|
// decorate klass with registration info
|
||||||
klass.is = info.is;
|
klass.is = klass.prototype.is = info.is;
|
||||||
return klass;
|
return klass;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -379,6 +379,20 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
behaviors: [window.BehaviorA]
|
behaviors: [window.BehaviorA]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
is: 'no-accessors-behavior',
|
||||||
|
behaviors: [{
|
||||||
|
_noAccessors: true,
|
||||||
|
properties: {
|
||||||
|
nug: String
|
||||||
|
},
|
||||||
|
foo: function() {},
|
||||||
|
bar: true
|
||||||
|
}],
|
||||||
|
_noAccessors: true,
|
||||||
|
zot: 'zot'
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<test-fixture id="single">
|
<test-fixture id="single">
|
||||||
@@ -447,6 +461,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</template>
|
</template>
|
||||||
</test-fixture>
|
</test-fixture>
|
||||||
|
|
||||||
|
<test-fixture id="no-accessors-behavior">
|
||||||
|
<template>
|
||||||
|
<no-accessors-behavior></no-accessors-behavior>
|
||||||
|
</template>
|
||||||
|
</test-fixture>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { Polymer } from '../../polymer-legacy.js';
|
import { Polymer } from '../../polymer-legacy.js';
|
||||||
|
|
||||||
@@ -501,6 +521,15 @@ suite('single behavior element', function() {
|
|||||||
assert.notOk(el.listeners);
|
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() {
|
suite('behavior.registered', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user