diff --git a/lib/elements/dom-bind.html b/lib/elements/dom-bind.html index b91438c364..8cd4487f8d 100644 --- a/lib/elements/dom-bind.html +++ b/lib/elements/dom-bind.html @@ -86,6 +86,7 @@ return; } this.root = this._stampBoundTemplate(template); + this.$ = this.root.$; this.__children = []; for (let n=this.root.firstChild; n; n=n.nextSibling) { this.__children[this.__children.length] = n; diff --git a/lib/mixins/element-mixin.html b/lib/mixins/element-mixin.html index 0e48f7897d..b0b402cc16 100644 --- a/lib/mixins/element-mixin.html +++ b/lib/mixins/element-mixin.html @@ -624,6 +624,7 @@ hostStack.beginHosting(this); this.root = this._stampBoundTemplate(this._template); hostStack.endHosting(this); + this.$ = this.root.$; } super.ready(); } @@ -747,6 +748,14 @@ return Polymer.ResolveUrl.resolveUrl(url, base); } + /** + * Overrides `PropertyAccessors` to add map of dynamic functions on + * template info, for consumption by `PropertyEffects` template binding + * code. This map determines which method templates should have accessors + * created for them. + * + * @override + */ static _parseTemplateContent(template, templateInfo, nodeInfo) { templateInfo.dynamicFns = templateInfo.dynamicFns || propertiesForClass(this); return super._parseTemplateContent(template, templateInfo, nodeInfo); diff --git a/lib/mixins/property-effects.html b/lib/mixins/property-effects.html index 2e5f1d85c4..822cef13ca 100644 --- a/lib/mixins/property-effects.html +++ b/lib/mixins/property-effects.html @@ -1130,7 +1130,7 @@ * its prototype, the property effect lists will be cloned and added as * own properties of the caller. * - * @param {string} path Property that should trigger the effect + * @param {string} property Property that should trigger the effect * @param {string} type Effect type, from this.PROPERTY_EFFECT_TYPES * @param {Object=} effect Effect metadata object * @protected @@ -2015,12 +2015,23 @@ return this.__templateInfo = templateInfo; } - static _addTemplatePropertyEffect(templateInfo, prop, info) { + /** + * Adds a property effect to the given template metadata, which is run + * at the "propagate" stage of `_propertiesChanged` when the template + * has been bound to the element via `_bindTemplate`. + * + * The `effect` object should match the format in `_addPropertyEffect`. + * + * @param {string} prop Property that should trigger the effect + * @param {Object=} effect Effect metadata object + * @protected + */ + static _addTemplatePropertyEffect(templateInfo, prop, effect) { let hostProps = templateInfo.hostProps = templateInfo.hostProps || {}; hostProps[prop] = true; let effects = templateInfo.propertyEffects = templateInfo.propertyEffects || {}; let propEffects = effects[prop] = effects[prop] || []; - propEffects.push(info); + propEffects.push(effect); } /** @@ -2030,6 +2041,14 @@ * is returned containing the stamped DOM, ready for insertion into the * DOM. * + * This method may be called more than once; however note that due to + * `shadycss` polyfill limitations, only styles from templates prepared + * using `ShadyCSS.prepareTemplate` will be correctly polyfilled (scoped + * to the shadow root and support CSS custom properties), and note that + * `ShadyCSS.prepareTemplate` may only be called once per element. As such, + * any styles required by in runtime-stamped templates must be included + * in the main element template. + * * @param {HTMLTemplateElement} template Template to stamp * @return {DocumentFragment} Cloned template content * @protected diff --git a/lib/mixins/template-stamp.html b/lib/mixins/template-stamp.html index 290b0ed793..7123f156c4 100644 --- a/lib/mixins/template-stamp.html +++ b/lib/mixins/template-stamp.html @@ -381,8 +381,9 @@ * The template is parsed (once and memoized) using this library's * template parsing features, and provides the following value-added * features: - * * Adds declarative event listners for `on-event="handler"` attributes - * * Generates an "id map" for all nodes with id's under `this.$` + * * Adds declarative event listeners for `on-event="handler"` attributes + * * Generates an "id map" for all nodes with id's under `$` on returned + * document fragment * * Passes template info including `content` back to templates as * `_templateInfo` (a performance optimization to avoid deep template * cloning) @@ -408,10 +409,10 @@ // NOTE: ShadyDom optimization indicating there is an insertion point dom.__noInsertionPoint = !templateInfo.hasInsertionPoint; let nodes = dom.nodeList = new Array(nodeInfo.length); - this.$ = {}; + dom.$ = {}; for (let i=0, l=nodeInfo.length, info; (i can only be templatized once'); } template.__templatizeOwner = owner; - let templateInfo = template._templateInfo; + let templateInfo = owner.constructor._parseTemplate(template); // Get memoized base class for the prototypical template, which // includes property effects for binding template & forwarding - let baseClass = templateInfo && templateInfo.templatizeInstanceClass; + let baseClass = templateInfo.templatizeInstanceClass; if (!baseClass) { - baseClass = createTemplatizerClass(template, options); - templateInfo = template._templateInfo; + baseClass = createTemplatizerClass(template, templateInfo, options); templateInfo.templatizeInstanceClass = baseClass; } // Host property forwarding must be installed onto template instance - addPropagateEffects(template, options); + addPropagateEffects(template, templateInfo, options); // Subclass base class and add reference for this specific template let klass = class TemplateInstance extends baseClass {}; klass.prototype._methodHost = findMethodHost(template);