mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
More updates based on code review.
This commit is contained in:
@@ -345,10 +345,5 @@ export const Class = function(info) {
|
|||||||
LegacyElementMixin(HTMLElement));
|
LegacyElementMixin(HTMLElement));
|
||||||
// decorate klass with registration info
|
// decorate klass with registration info
|
||||||
klass.is = info.is;
|
klass.is = info.is;
|
||||||
// if user provided template on info, make sure the static _template
|
return klass;
|
||||||
// is set so the static template getter uses it
|
|
||||||
if (info._template !== undefined) {
|
|
||||||
klass._template = info._template;
|
|
||||||
}
|
|
||||||
return klass;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -403,14 +403,14 @@ export const ElementMixin = dedupingMixin(base => {
|
|||||||
static get template() {
|
static get template() {
|
||||||
if (!this.hasOwnProperty(JSCompiler_renameProperty('_template', this))) {
|
if (!this.hasOwnProperty(JSCompiler_renameProperty('_template', this))) {
|
||||||
this._template =
|
this._template =
|
||||||
|
// Take any template set on the prototype, including null (for legacy
|
||||||
|
// support, setting in registered callback, etc.)
|
||||||
|
this.prototype._template !== undefined ? this.prototype._template :
|
||||||
// Look in dom-module associated with this element's is
|
// Look in dom-module associated with this element's is
|
||||||
getTemplateFromDomModule(/** @type {PolymerElementConstructor}*/ (this).is) ||
|
getTemplateFromDomModule(/** @type {PolymerElementConstructor}*/ (this).is) ||
|
||||||
// Next look for superclass template (call the super impl this
|
// Next look for superclass template (call the super impl this
|
||||||
// way so that `this` points to the superclass)
|
// way so that `this` points to the superclass)
|
||||||
Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.template ||
|
Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.template;
|
||||||
// Finally, fall back to any _template set on prototype, e.g.
|
|
||||||
// via registered callback
|
|
||||||
this.prototype._template;
|
|
||||||
}
|
}
|
||||||
return this._template;
|
return this._template;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -499,7 +499,7 @@ export function templatize(template, owner, options) {
|
|||||||
// Under strictTemplatePolicy, the templatized element must be owned
|
// Under strictTemplatePolicy, the templatized element must be owned
|
||||||
// by a (trusted) Polymer element, indicated by existence of _methodHost;
|
// by a (trusted) Polymer element, indicated by existence of _methodHost;
|
||||||
// e.g. for dom-if & dom-repeat in main document, _methodHost is null
|
// e.g. for dom-if & dom-repeat in main document, _methodHost is null
|
||||||
if (strictTemplatePolicy && !owner._methodHost) {
|
if (strictTemplatePolicy && !findMethodHost(template)) {
|
||||||
throw new Error('strictTemplatePolicy: template owner not trusted');
|
throw new Error('strictTemplatePolicy: template owner not trusted');
|
||||||
}
|
}
|
||||||
options = /** @type {!TemplatizeOptions} */(options || {});
|
options = /** @type {!TemplatizeOptions} */(options || {});
|
||||||
|
|||||||
@@ -23,8 +23,14 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
|
<dom-module id="template-from-behavior">
|
||||||
|
<template>
|
||||||
|
<div id="from-base">should not be used</div>
|
||||||
|
</template>
|
||||||
|
</dom-module>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { Polymer } from '../../polymer-legacy.js';
|
import { Polymer, html } from '../../polymer-legacy.js';
|
||||||
window.BehaviorA = {
|
window.BehaviorA = {
|
||||||
properties: {
|
properties: {
|
||||||
|
|
||||||
@@ -284,6 +290,50 @@ Polymer({
|
|||||||
|
|
||||||
is: 'behavior-registered'
|
is: 'behavior-registered'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.templateBehavior1 = {
|
||||||
|
_template: html`<div id="from-behavior1"></div>`
|
||||||
|
};
|
||||||
|
|
||||||
|
window.templateBehavior2 = {
|
||||||
|
_template: html`<div id="from-behavior2"></div>`
|
||||||
|
};
|
||||||
|
|
||||||
|
window.templateBehaviorFromRegister = {
|
||||||
|
registered: function() {
|
||||||
|
this._template = html`<div id="behavior-from-register"></div>`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
is: 'template-from-registered',
|
||||||
|
registered: function() {
|
||||||
|
this._template = html`<div id="from-registered"></div>`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
is: 'template-from-behavior',
|
||||||
|
behaviors: [
|
||||||
|
window.templateBehavior1
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
is: 'template-from-behavior-overridden',
|
||||||
|
behaviors: [
|
||||||
|
window.templateBehavior1,
|
||||||
|
window.templateBehavior2
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
is: 'template-from-behavior-registered',
|
||||||
|
behaviors: [
|
||||||
|
window.templateBehavior1,
|
||||||
|
window.templateBehaviorFromRegister
|
||||||
|
]
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<test-fixture id="single">
|
<test-fixture id="single">
|
||||||
@@ -309,6 +359,31 @@ Polymer({
|
|||||||
<behavior-registered></behavior-registered>
|
<behavior-registered></behavior-registered>
|
||||||
</template>
|
</template>
|
||||||
</test-fixture>
|
</test-fixture>
|
||||||
|
|
||||||
|
<test-fixture id="from-registered">
|
||||||
|
<template>
|
||||||
|
<template-from-registered></template-from-registered>
|
||||||
|
</template>
|
||||||
|
</test-fixture>
|
||||||
|
|
||||||
|
<test-fixture id="from-behavior">
|
||||||
|
<template>
|
||||||
|
<template-from-behavior></template-from-behavior>
|
||||||
|
</template>
|
||||||
|
</test-fixture>
|
||||||
|
|
||||||
|
<test-fixture id="from-behavior-overridden">
|
||||||
|
<template>
|
||||||
|
<template-from-behavior-overridden></template-from-behavior-overridden>
|
||||||
|
</template>
|
||||||
|
</test-fixture>
|
||||||
|
|
||||||
|
<test-fixture id="from-behavior-registered">
|
||||||
|
<template>
|
||||||
|
<template-from-behavior-registered></template-from-behavior-registered>
|
||||||
|
</template>
|
||||||
|
</test-fixture>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { Polymer } from '../../polymer-legacy.js';
|
import { Polymer } from '../../polymer-legacy.js';
|
||||||
|
|
||||||
@@ -505,6 +580,34 @@ suite('nested-behaviors element', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
suite('templates from behaviors', function() {
|
||||||
|
|
||||||
|
test('template from registered callback', function() {
|
||||||
|
var el = fixture('from-registered');
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#from-registered'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('template from behavior', function() {
|
||||||
|
var el = fixture('from-behavior');
|
||||||
|
assert.notOk(el.shadowRoot.querySelector('#from-base'));
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#from-behavior1'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('template from overriding behavior', function() {
|
||||||
|
var el = fixture('from-behavior-overridden');
|
||||||
|
assert.notOk(el.shadowRoot.querySelector('#from-behavior1'));
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#from-behavior2'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('template from behavior registered callback', function() {
|
||||||
|
var el = fixture('from-behavior-registered');
|
||||||
|
assert.notOk(el.shadowRoot.querySelector('#from-behavior1'));
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#behavior-from-register'));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
<div id="target"></div>
|
<div id="target"></div>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import {PolymerElement} from '../../polymer-element.js';
|
import {PolymerElement, html} from '../../polymer-element.js';
|
||||||
import {Polymer} from '../../polymer-legacy.js';
|
import {Polymer} from '../../polymer-legacy.js';
|
||||||
import {flush} from '../../lib/utils/flush.js';
|
import {flush} from '../../lib/utils/flush.js';
|
||||||
import {setAllowTemplateFromDomModule} from '../../lib/utils/settings.js';
|
import {setAllowTemplateFromDomModule} from '../../lib/utils/settings.js';
|
||||||
@@ -94,10 +94,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
// the call stack to the dom methods that provoked them, so this
|
// the call stack to the dom methods that provoked them, so this
|
||||||
// wraps Chai's assert.throws to re-throw uncaught errors
|
// wraps Chai's assert.throws to re-throw uncaught errors
|
||||||
function assertThrows(fn, re) {
|
function assertThrows(fn, re) {
|
||||||
let uncaughtError = null;
|
|
||||||
// Catch uncaught errors; note when running in iframe sometimes
|
// Catch uncaught errors; note when running in iframe sometimes
|
||||||
// Safari errors are thrown on the top window, sometimes not, so
|
// Safari errors are thrown on the top window, sometimes not, so
|
||||||
// catch in both places
|
// catch in both places
|
||||||
|
let uncaughtError = null;
|
||||||
window.uncaughtErrorFilter = window.top.uncaughtErrorFilter = function(err) {
|
window.uncaughtErrorFilter = window.top.uncaughtErrorFilter = function(err) {
|
||||||
if (!uncaughtError) {
|
if (!uncaughtError) {
|
||||||
uncaughtError = err;
|
uncaughtError = err;
|
||||||
@@ -179,11 +179,27 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
' <template>' +
|
' <template>' +
|
||||||
' <div id="injected"></div>'+
|
' <div id="injected"></div>'+
|
||||||
' </template>`' +
|
' </template>`' +
|
||||||
'</dom-module>' +
|
'</dom-module>';
|
||||||
'<trusted-element></trusted-element>';
|
|
||||||
}, /trusted-element re-registered/);
|
}, /trusted-element re-registered/);
|
||||||
const el = document.querySelector('trusted-element');
|
const el = document.createElement('trusted-element');
|
||||||
assert.notOk(el && el.shadowRoot && el.shadowRoot.querySelector('#injected'));
|
document.getElementById('target').appendChild(el);
|
||||||
|
assert.notOk(el.shadowRoot);
|
||||||
|
assert.notOk(document.getElementById('injected'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dom-module after registration, again', function() {
|
||||||
|
assertThrows(function() {
|
||||||
|
document.getElementById('target').innerHTML =
|
||||||
|
'<dom-module id="trusted-element">' +
|
||||||
|
' <template>' +
|
||||||
|
' <div id="injected"></div>'+
|
||||||
|
' </template>`' +
|
||||||
|
'</dom-module>';
|
||||||
|
}, /trusted-element re-registered/);
|
||||||
|
const el = document.createElement('trusted-element');
|
||||||
|
document.getElementById('target').appendChild(el);
|
||||||
|
assert.notOk(el.shadowRoot);
|
||||||
|
assert.notOk(document.getElementById('injected'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dom-module before registration', function() {
|
test('dom-module before registration', function() {
|
||||||
@@ -201,6 +217,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
let el = document.createElement('has-no-template');
|
let el = document.createElement('has-no-template');
|
||||||
document.getElementById('target').appendChild(el);
|
document.getElementById('target').appendChild(el);
|
||||||
assert.notOk(el.shadowRoot);
|
assert.notOk(el.shadowRoot);
|
||||||
|
assert.notOk(document.getElementById('injected'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dom-module after registration (legacy)', function() {
|
test('dom-module after registration (legacy)', function() {
|
||||||
@@ -210,13 +227,29 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
' <template>' +
|
' <template>' +
|
||||||
' <div id="injected"></div>'+
|
' <div id="injected"></div>'+
|
||||||
' </template>`' +
|
' </template>`' +
|
||||||
'</dom-module>' +
|
'</dom-module>';
|
||||||
'<trusted-element-legacy></trusted-element-legacy>';
|
|
||||||
}, /trusted-element-legacy re-registered/);
|
}, /trusted-element-legacy re-registered/);
|
||||||
const el = document.querySelector('trusted-element-legacy');
|
const el = document.createElement('trusted-element-legacy');
|
||||||
assert.notOk(el && el.shadowRoot && el.shadowRoot.querySelector('#injected'));
|
document.getElementById('target').appendChild(el);
|
||||||
|
assert.notOk(el.shadowRoot);
|
||||||
|
assert.notOk(document.getElementById('injected'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('dom-module after registration, again (legacy)', function() {
|
||||||
|
assertThrows(function() {
|
||||||
|
document.getElementById('target').innerHTML =
|
||||||
|
'<dom-module id="trusted-element-legacy">' +
|
||||||
|
' <template>' +
|
||||||
|
' <div id="injected"></div>'+
|
||||||
|
' </template>`' +
|
||||||
|
'</dom-module>';
|
||||||
|
}, /trusted-element-legacy re-registered/);
|
||||||
|
const el = document.createElement('trusted-element-legacy');
|
||||||
|
document.getElementById('target').appendChild(el);
|
||||||
|
assert.notOk(el.shadowRoot);
|
||||||
|
assert.notOk(document.getElementById('injected'));
|
||||||
|
});
|
||||||
|
|
||||||
test('dom-module before registration (legacy)', function() {
|
test('dom-module before registration (legacy)', function() {
|
||||||
document.getElementById('target').innerHTML =
|
document.getElementById('target').innerHTML =
|
||||||
'<dom-module id="has-no-template-legacy">' +
|
'<dom-module id="has-no-template-legacy">' +
|
||||||
@@ -230,7 +263,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
});
|
});
|
||||||
let el = document.createElement('has-no-template-legacy');
|
let el = document.createElement('has-no-template-legacy');
|
||||||
document.getElementById('target').appendChild(el);
|
document.getElementById('target').appendChild(el);
|
||||||
assert.notOk(document.querySelector('has-no-template-legacy').shadowRoot);
|
assert.notOk(el.shadowRoot);
|
||||||
|
assert.notOk(document.getElementById('injected'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('element without explicit template throws', function() {
|
test('element without explicit template throws', function() {
|
||||||
@@ -253,8 +287,68 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
document.getElementById('target').appendChild(el);
|
document.getElementById('target').appendChild(el);
|
||||||
}, /expecting dom-module or null template/);
|
}, /expecting dom-module or null template/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('template helpers in trusted templates work', function() {
|
||||||
|
|
||||||
|
class TrustedTemplates extends PolymerElement {
|
||||||
|
static get template() { return html`
|
||||||
|
<dom-repeat items="[0]">
|
||||||
|
<template>
|
||||||
|
<div id="dom-repeat-ok"></div>
|
||||||
|
<dom-if if>
|
||||||
|
<template><div id="nested-dom-if-ok"></div></template>
|
||||||
|
</dom-if>
|
||||||
|
</template>
|
||||||
|
</dom-repeat>
|
||||||
|
<dom-if if>
|
||||||
|
<template>
|
||||||
|
<div id="dom-if-ok"></div>
|
||||||
|
<dom-repeat items="[0]">
|
||||||
|
<template>
|
||||||
|
<div id="nested-dom-repeat-ok"></div>
|
||||||
|
</template>
|
||||||
|
</dom-repeat>
|
||||||
|
</template>
|
||||||
|
</dom-if>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('trusted-templates', TrustedTemplates);
|
||||||
|
|
||||||
|
var el = document.createElement('trusted-templates');
|
||||||
|
document.getElementById('target').appendChild(el);
|
||||||
|
flush();
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#dom-repeat-ok'));
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#dom-if-ok'));
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#nested-dom-repeat-ok'));
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#nested-dom-if-ok'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('template helpers in trusted templates work (legacy)', function() {
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
is: 'trusted-templates-legacy',
|
||||||
|
_template: html`
|
||||||
|
<template is="dom-repeat" items="[0]">
|
||||||
|
<div id="dom-repeat-ok"></div>
|
||||||
|
<template is="dom-if" if><div id="nested-dom-if-ok"></div></template>
|
||||||
|
</template>
|
||||||
|
<template is="dom-if" if>
|
||||||
|
<div id="dom-if-ok"></div>
|
||||||
|
<template is="dom-repeat" items="[0]"><div id="nested-dom-repeat-ok"></div></template>
|
||||||
|
</template>`
|
||||||
|
});
|
||||||
|
|
||||||
|
var el = document.createElement('trusted-templates-legacy');
|
||||||
|
document.getElementById('target').appendChild(el);
|
||||||
|
flush();
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#dom-repeat-ok'));
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#dom-if-ok'));
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#nested-dom-repeat-ok'));
|
||||||
|
assert.ok(el.shadowRoot.querySelector('#nested-dom-if-ok'));
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user