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);