Skip to content

Commit

Permalink
More updates based on code review.
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinpschaaf committed Jul 24, 2018
1 parent 3672737 commit 376f44c
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 24 deletions.
7 changes: 1 addition & 6 deletions lib/legacy/class.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,10 +345,5 @@ export const Class = function(info) {
LegacyElementMixin(HTMLElement));
// decorate klass with registration info
klass.is = info.is;
// if user provided template on info, make sure the static _template
// is set so the static template getter uses it
if (info._template !== undefined) {
klass._template = info._template;
}
return klass;
return klass;
};
8 changes: 4 additions & 4 deletions lib/mixins/element-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,14 +403,14 @@ export const ElementMixin = dedupingMixin(base => {
static get template() {
if (!this.hasOwnProperty(JSCompiler_renameProperty('_template', this))) {
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
getTemplateFromDomModule(/** @type {PolymerElementConstructor}*/ (this).is) ||
// Next look for superclass template (call the super impl this
// way so that `this` points to the superclass)
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;
Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.template;
}
return this._template;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/templatize.js
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ export function templatize(template, owner, options) {
// Under strictTemplatePolicy, the templatized element must be owned
// by a (trusted) Polymer element, indicated by existence of _methodHost;
// 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');
}
options = /** @type {!TemplatizeOptions} */(options || {});
Expand Down
105 changes: 104 additions & 1 deletion test/unit/behaviors.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,14 @@
</template>
</dom-module>

<dom-module id="template-from-behavior">
<template>
<div id="from-base">should not be used</div>
</template>
</dom-module>

<script type="module">
import { Polymer } from '../../polymer-legacy.js';
import { Polymer, html } from '../../polymer-legacy.js';
window.BehaviorA = {
properties: {

Expand Down Expand Up @@ -284,6 +290,50 @@

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>

<test-fixture id="single">
Expand All @@ -309,6 +359,31 @@
<behavior-registered></behavior-registered>
</template>
</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">
import { Polymer } from '../../polymer-legacy.js';

Expand Down Expand Up @@ -505,6 +580,34 @@
});

});

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>

</body>
Expand Down
118 changes: 106 additions & 12 deletions test/unit/strict-template-policy.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
<div id="target"></div>

<script type="module">
import {PolymerElement} from '../../polymer-element.js';
import {PolymerElement, html} from '../../polymer-element.js';
import {Polymer} from '../../polymer-legacy.js';
import {flush} from '../../lib/utils/flush.js';
import {setAllowTemplateFromDomModule} from '../../lib/utils/settings.js';
Expand All @@ -94,10 +94,10 @@
// the call stack to the dom methods that provoked them, so this
// wraps Chai's assert.throws to re-throw uncaught errors
function assertThrows(fn, re) {
let uncaughtError = null;
// Catch uncaught errors; note when running in iframe sometimes
// Safari errors are thrown on the top window, sometimes not, so
// catch in both places
let uncaughtError = null;
window.uncaughtErrorFilter = window.top.uncaughtErrorFilter = function(err) {
if (!uncaughtError) {
uncaughtError = err;
Expand Down Expand Up @@ -179,11 +179,27 @@
' <template>' +
' <div id="injected"></div>'+
' </template>`' +
'</dom-module>' +
'<trusted-element></trusted-element>';
'</dom-module>';
}, /trusted-element re-registered/);
const el = document.querySelector('trusted-element');
assert.notOk(el && el.shadowRoot && el.shadowRoot.querySelector('#injected'));
const el = document.createElement('trusted-element');
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() {
Expand All @@ -201,6 +217,7 @@
let el = document.createElement('has-no-template');
document.getElementById('target').appendChild(el);
assert.notOk(el.shadowRoot);
assert.notOk(document.getElementById('injected'));
});

test('dom-module after registration (legacy)', function() {
Expand All @@ -210,13 +227,29 @@
' <template>' +
' <div id="injected"></div>'+
' </template>`' +
'</dom-module>' +
'<trusted-element-legacy></trusted-element-legacy>';
'</dom-module>';
}, /trusted-element-legacy re-registered/);
const el = document.querySelector('trusted-element-legacy');
assert.notOk(el && el.shadowRoot && el.shadowRoot.querySelector('#injected'));
const el = document.createElement('trusted-element-legacy');
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() {
document.getElementById('target').innerHTML =
'<dom-module id="has-no-template-legacy">' +
Expand All @@ -230,7 +263,8 @@
});
let el = document.createElement('has-no-template-legacy');
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() {
Expand All @@ -253,8 +287,68 @@
document.getElementById('target').appendChild(el);
}, /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>

</body>
Expand Down

0 comments on commit 376f44c

Please sign in to comment.