From 36c4dfa99f7de9e296f675d836cd113eadca1c79 Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Fri, 20 Jul 2018 20:33:02 -0700 Subject: [PATCH] Updates based on code review. --- lib/elements/dom-if.js | 4 +- lib/elements/dom-module.js | 20 +++-- lib/legacy/class.js | 23 ++--- lib/mixins/element-mixin.js | 42 +++++++-- lib/utils/settings.js | 23 ++++- lib/utils/templatize.js | 3 + test/unit/strict-template-policy.html | 123 +++++++++++++++++++++++--- 7 files changed, 190 insertions(+), 48 deletions(-) diff --git a/lib/elements/dom-if.js b/lib/elements/dom-if.js index f6b928f9ad..d130425556 100644 --- a/lib/elements/dom-if.js +++ b/lib/elements/dom-if.js @@ -251,7 +251,9 @@ export class DomIf extends PolymerElement { if (c$ && c$.length) { // use first child parent, for case when dom-if may have been detached let parent = c$[0].parentNode; - if (parent) { + // Instance children may be disconnected from parents when dom-if + // detaches if a tree was innerHTML'ed + if (parent) { for (let i=0, n; (i { } } + /** + * Look up template from dom-module for element + * + * @param {!string} is Element name to look up + * @return {!HTMLTemplateElement} Template found in dom module, or + * undefined if not found + * @private + */ + function getTemplateFromDomModule(is) { + let template = null; + if (is && allowTemplateFromDomModule) { + template = DomModule.import(is, 'template') + // Under strictTemplatePolicy, require any element with an `is` + // specified to have a dom-module + if (strictTemplatePolicy && !template) { + throw new Error(`strictTemplatePolicy: expecting dom-module or null template for ${is}`); + } + } + return template; + } + /** * @polymer * @mixinClass @@ -379,15 +400,18 @@ export const ElementMixin = dedupingMixin(base => { */ static get template() { if (!this.hasOwnProperty(JSCompiler_renameProperty('_template', this))) { - this._template = (!strictTemplatePolicy && DomModule && DomModule.import( - /** @type {PolymerElementConstructor}*/ (this).is, 'template')) || - // note: implemented so a subclass can retrieve the super - // template; call the super impl this way so that `this` points - // to the superclass. - Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.template; + this._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; } return this._template; - } + } /** * Path matching the url from which the element was imported. @@ -414,7 +438,7 @@ export const ElementMixin = dedupingMixin(base => { if (meta) { this._importPath = pathFromUrl(meta.url); } else { - const module = DomModule && DomModule.import(/** @type {PolymerElementConstructor} */ (this).is); + const module = DomModule.import(/** @type {PolymerElementConstructor} */ (this).is); this._importPath = (module && module.assetpath) || Object.getPrototypeOf(/** @type {PolymerElementConstructor}*/ (this).prototype).constructor.importPath; } diff --git a/lib/utils/settings.js b/lib/utils/settings.js index 52c4ec2ba2..a179f87c55 100644 --- a/lib/utils/settings.js +++ b/lib/utils/settings.js @@ -86,8 +86,8 @@ export const setPassiveTouchGestures = function(usePassive) { /** * Setting to ensure Polymer template evaluation only occurs based on tempates - * defined in trusted script. When true, `` based template lookup - * is disabled, `` is disabled, and ``/`` + * defined in trusted script. When true, `` re-registration is + * disallowed, `` is disabled, and ``/`` * templates will only evaluate in the context of a trusted element template. */ export let strictTemplatePolicy = false; @@ -102,3 +102,22 @@ export let strictTemplatePolicy = false; export const setStrictTemplatePolicy = function(useStrictPolicy) { strictTemplatePolicy = useStrictPolicy; }; + +/** + * Setting to enable dom-module lookup from Polymer.Element. By default, + * templates must be defined in script using the `static get template()` + * getter and the `html` tag function. To enable legacy loading of templates + * via dom-module, set this flag to true. + */ +export let allowTemplateFromDomModule = false; + +/** + * Sets `lookupTemplateFromDomModule` globally for all elements + * + * @param {boolean} allowDomModule enable or disable template lookup + * globally + * @return {void} + */ +export const setAllowTemplateFromDomModule = function(allowDomModule) { + allowTemplateFromDomModule = allowDomModule; +}; diff --git a/lib/utils/templatize.js b/lib/utils/templatize.js index be09cb0c21..36d531fd4b 100644 --- a/lib/utils/templatize.js +++ b/lib/utils/templatize.js @@ -496,6 +496,9 @@ and this string can then be deleted`; * @suppress {invalidCasts} */ 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) { throw new Error('strictTemplatePolicy: template owner not trusted'); } diff --git a/test/unit/strict-template-policy.html b/test/unit/strict-template-policy.html index f62745a93b..cc49b721a6 100644 --- a/test/unit/strict-template-policy.html +++ b/test/unit/strict-template-policy.html @@ -37,34 +37,57 @@ - + - + + + + + + + + + + +
- +