From 27ed93aff1ae8cc05d99d25975970c19721a4446 Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Thu, 6 Jun 2019 12:59:48 -0700 Subject: [PATCH] dom-if/dom-repeat bind-to-parent --- lib/elements/dom-if.js | 2 +- lib/elements/dom-repeat.js | 2 +- lib/mixins/property-effects.js | 12 +++++++++++- lib/utils/settings.js | 2 +- lib/utils/templatize.js | 29 +++++++++++++++++++---------- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/lib/elements/dom-if.js b/lib/elements/dom-if.js index 2b4f23c70d..70289708dd 100644 --- a/lib/elements/dom-if.js +++ b/lib/elements/dom-if.js @@ -182,7 +182,7 @@ export class DomIf extends PolymerElement { // Guard against element being detached while render was queued if (parentNode) { if (!this.__ctor) { - let template = /** @type {HTMLTemplateElement} */(wrap(this).querySelector('template')); + let template = this._templateInfo ? this : /** @type {HTMLTemplateElement} */(wrap(this).querySelector('template')); if (!template) { // Wait until childList changes and template should be there by then let observer = new MutationObserver(() => { diff --git a/lib/elements/dom-repeat.js b/lib/elements/dom-repeat.js index 7b0407d2e0..e330dce954 100644 --- a/lib/elements/dom-repeat.js +++ b/lib/elements/dom-repeat.js @@ -339,7 +339,7 @@ export class DomRepeat extends domRepeatBase { // until ready, since won't have its template content handed back to // it until then if (!this.__ctor) { - let template = this.template = /** @type {HTMLTemplateElement} */(this.querySelector('template')); + let template = this.template = this._templateInfo ? this : /** @type {HTMLTemplateElement} */(this.querySelector('template')); if (!template) { // // Wait until childList changes and template should be there by then let observer = new MutationObserver(() => { diff --git a/lib/mixins/property-effects.js b/lib/mixins/property-effects.js index 1770585ac8..802586e937 100644 --- a/lib/mixins/property-effects.js +++ b/lib/mixins/property-effects.js @@ -21,6 +21,8 @@ import { PropertyAccessors } from './property-accessors.js'; import { TemplateStamp } from './template-stamp.js'; import { sanitizeDOMValue, legacyUndefined, legacyNoBatch, legacyNotifyOrder, orderedComputed } from '../utils/settings.js'; +const btp = window.location.search.match(/btp/); + // Monotonically increasing unique ID used for de-duping effects triggered // from multiple properties in the same turn let dedupeId = 0; @@ -2919,8 +2921,16 @@ export const PropertyEffects = dedupingMixin(superClass => { // Change back to just super.methodCall() let noted = propertyEffectsBase._parseTemplateNestedTemplate.call( this, node, templateInfo, nodeInfo); + const parent = node.parentNode; + const nestedTemplateInfo = nodeInfo.templateInfo; + if (btp && parent.localName.match(/(dom-repeat|dom-if)/)) { + parent.removeChild(node); + nodeInfo.parentInfo.templateInfo = nestedTemplateInfo; + nodeInfo = nodeInfo.parentInfo; + noted = false; + } // Merge host props into outer template and add bindings - let hostProps = nodeInfo.templateInfo.hostProps; + let hostProps = nestedTemplateInfo.hostProps; let mode = '{'; for (let source in hostProps) { let parts = [{ mode, source, dependencies: [source], hostProp: true }]; diff --git a/lib/utils/settings.js b/lib/utils/settings.js index 84812d24f6..bc81c7bdf4 100644 --- a/lib/utils/settings.js +++ b/lib/utils/settings.js @@ -127,7 +127,7 @@ export const setAllowTemplateFromDomModule = function(allowDomModule) { * If no includes or relative urls are used in styles, these steps can be * skipped as an optimization. */ -export let legacyOptimizations = false; +export let legacyOptimizations = window.Polymer && window.Polymer.legacyOptimizations || false; /** * Sets `legacyOptimizations` globally for all elements to enable optimizations diff --git a/lib/utils/templatize.js b/lib/utils/templatize.js index c29d96e012..e4f5ba4211 100644 --- a/lib/utils/templatize.js +++ b/lib/utils/templatize.js @@ -368,6 +368,7 @@ function createTemplatizerClass(template, templateInfo, options) { function addPropagateEffects(template, templateInfo, options, methodHost) { let userForwardHostProp = options.forwardHostProp; if (userForwardHostProp && templateInfo.hasHostProps) { + const isTemplate = template.localName == 'template'; // Provide data API and property effects on memoized template class let klass = templateInfo.templatizeTemplateClass; if (!klass) { @@ -375,10 +376,14 @@ function addPropagateEffects(template, templateInfo, options, methodHost) { * @constructor * @extends {DataTemplate} */ - let templatizedBase = options.mutableData ? MutableDataTemplate : DataTemplate; - /** @private */ - klass = templateInfo.templatizeTemplateClass = - class TemplatizedTemplate extends templatizedBase {}; + if (isTemplate) { + let templatizedBase = options.mutableData ? MutableDataTemplate : DataTemplate; + /** @private */ + klass = templateInfo.templatizeTemplateClass = + class TemplatizedTemplate extends templatizedBase {}; + } else { + klass = class TemplatizedTemplateExtension extends template.constructor {}; + } // Add template - >instances effects // and host <- template effects let hostProps = templateInfo.hostProps; @@ -392,7 +397,16 @@ function addPropagateEffects(template, templateInfo, options, methodHost) { warnOnUndeclaredProperties(templateInfo, options, methodHost); } } - upgradeTemplate(template, klass); + if (isTemplate) { + upgradeTemplate(template, klass); + // Clear any pending data for performance + template.__dataTemp = {}; + template.__dataPending = null; + template.__dataOld = null; + template._enableProperties(); + } else { + Object.setPrototypeOf(template, klass.prototype); + } // Mix any pre-bound data into __data; no need to flush this to // instances since they pull from the template at instance-time if (template.__dataProto) { @@ -400,11 +414,6 @@ function addPropagateEffects(template, templateInfo, options, methodHost) { // to not be since this is a vanilla template we just added effects to Object.assign(template.__data, template.__dataProto); } - // Clear any pending data for performance - template.__dataTemp = {}; - template.__dataPending = null; - template.__dataOld = null; - template._enableProperties(); } } /* eslint-enable valid-jsdoc */