From 13f44179bcf033feeebd21914b96fade18dde0d8 Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Thu, 30 Apr 2015 03:42:59 -0700 Subject: [PATCH] First-pass, lexical template scoping. --- src/lib/annotations/annotations.html | 38 +- src/lib/bind/effects.html | 6 +- src/lib/template/templatizer.html | 66 +- src/lib/template/x-if.html | 5 +- src/lib/template/x-repeat.html | 59 +- test/smoke/x-repeat.html | 68 +- test/unit/x-repeat-elements.html | 147 ++-- test/unit/x-repeat.html | 1137 +++++++++++++------------- 8 files changed, 775 insertions(+), 751 deletions(-) diff --git a/src/lib/annotations/annotations.html b/src/lib/annotations/annotations.html index 6a608e45..a6900712 100644 --- a/src/lib/annotations/annotations.html +++ b/src/lib/annotations/annotations.html @@ -205,40 +205,26 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN }); }, - // Finds all parent.* properties in template content and stores - // the path members in content._parentPropChain, which is an array - // of maps listing the properties of parent templates required at - // each level. Each outer template merges inner _parentPropChains to - // propagate inner parent property needs to outer templates. - // The top-level parent props from the chain (corresponding to this - // template) are stored in content._parentProps. + // Finds all bindings in template content and stores the path roots in + // the path members in content._parentProps. Each outer template merges + // inner _parentProps to propagate inner parent property needs to outer + // templates. _discoverTemplateParentProps: function(content) { - var chain = content._parentPropChain = []; + var pp = content._parentProps = {}; content._notes.forEach(function(n) { // Find all bindings to parent.* and spread them into _parentPropChain n.bindings.forEach(function(b) { - var m; - if (m = b.value.match(/parent\.((parent\.)*[^.]*)/)) { - var parts = m[1].split('.'); - for (var i=0; i path change on instance _forwardParentProp: function(prop, value) { if (this._instance) { - this._instance.parent[prop] = value; - this._instance.notifyPath('parent.' + prop, value, true); + this._instance[prop] = value; } }, @@ -144,7 +143,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN // notifying parent. path change on each row _forwardParentPath: function(path, value) { if (this._instance) { - this._instance.notifyPath('parent.' + path, value, true); + this._instance.notifyPath(path, value, true); } } diff --git a/src/lib/template/x-repeat.html b/src/lib/template/x-repeat.html index a810fac8..d0393e1d 100644 --- a/src/lib/template/x-repeat.html +++ b/src/lib/template/x-repeat.html @@ -105,6 +105,23 @@ Then the `observe` property should be configured as follows: observer: '_itemsChanged' }, + /** + * The name of the variable to add to the binding scope for the array + * element associated with a given template instance. + */ + as: { + type: String, + value: 'item' + }, + + /** + * The name of an inner scope variable for storing data specific to this + * instance. + */ + innerAs: { + type: String + }, + /** * A function that should determine the sort order of the items. This * property should either be provided as a string, indicating a method @@ -169,6 +186,15 @@ Then the `observe` property should be configured as follows: }, ready: function() { + // Template instance props that should be excluded from forwarding + this._instanceProps = { + index: true, + key: true + }; + this._instanceProps[this.as] = true; + if (this.innerAs) { + this._instanceProps[this.innerAs] = true; + } // Templatizing (generating the instance constructor) needs to wait // until ready, since won't have its template content handed back to // it until then @@ -214,7 +240,7 @@ Then the `observe` property should be configured as follows: this._splices = this._splices.concat(change.value.keySplices); this._debounceTemplate(this._render); } else if (change.path != 'items') { - // 'items.'.length == 6 + // slice off 'items.' ('items.'.length == 6) var subpath = change.path.slice(6); this._forwardItemPath(subpath, change.value); this._checkObservedPaths(subpath); @@ -274,7 +300,7 @@ Then the `observe` property should be configured as follows: if (!row) { this.rows.push(row = this._insertRow(i, null, item)); } - row.item = item; + row[this.as] = item; row.key = key; row.index = i; } @@ -441,11 +467,15 @@ Then the `observe` property should be configured as follows: }, _generateRow: function(idx, item) { - var row = this.stamp({ + var model = { index: idx, - key: this.collection.getKey(item), - item: item - }); + key: this.collection.getKey(item) + }; + model[this.as] = item; + if (this.innerAs) { + model[this.innerAs] = {}; + } + var row = this.stamp(model); return row; }, @@ -468,9 +498,11 @@ Then the `observe` property should be configured as follows: // Implements extension point from Templatizer // Called as a side effect of a template instance path change, responsible // for notifying items.. change up to host - _forwardInstancePath: function(row, root, subPath, value) { - if (root == 'item') { - this.notifyPath('items.' + row.key + '.' + subPath, value); + _forwardInstancePath: function(row, path, value) { + if (path.indexOf(this.as + '.') === 0) { + this.notifyPath('items.' + row.key + '.' + + path.slice(this.as.length + 1), value); + return true; } }, @@ -480,8 +512,7 @@ Then the `observe` property should be configured as follows: _forwardParentProp: function(prop, value) { if (this.rows) { this.rows.forEach(function(row) { - row.parent[prop] = value; - row.notifyPath('parent.' + prop, value, true); + row[prop] = value; }, this); } }, @@ -492,7 +523,7 @@ Then the `observe` property should be configured as follows: _forwardParentPath: function(path, value) { if (this.rows) { this.rows.forEach(function(row) { - row.notifyPath('parent.' + path, value, true); + row.notifyPath(path, value, true); }, this); } }, @@ -507,10 +538,10 @@ Then the `observe` property should be configured as follows: var row = this.rows[idx]; if (row) { if (dot >= 0) { - path = 'item.' + path.substring(dot+1); + path = this.as + '.' + path.substring(dot+1); row.notifyPath(path, value, true); } else { - row.item = value; + row[this.as] = value; } } } diff --git a/test/smoke/x-repeat.html b/test/smoke/x-repeat.html index cfbc007f..98ae752a 100644 --- a/test/smoke/x-repeat.html +++ b/test/smoke/x-repeat.html @@ -96,40 +96,37 @@
-