polymer-rails 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/polymer/polymer-micro.html +528 -21
  3. data/app/assets/javascripts/polymer/polymer-mini.html +1304 -27
  4. data/app/assets/javascripts/polymer/polymer.html +3771 -51
  5. data/app/assets/javascripts/webcomponentsjs/webcomponents-lite.js +44 -14
  6. data/app/assets/javascripts/webcomponentsjs/webcomponents.js +7106 -0
  7. data/lib/polymer-rails/version.rb +1 -1
  8. metadata +4 -64
  9. data/app/assets/javascripts/polymer/src/lib/annotations/annotations.html +0 -262
  10. data/app/assets/javascripts/polymer/src/lib/annotations/demo/app-chrome.html +0 -60
  11. data/app/assets/javascripts/polymer/src/lib/array-observe.html +0 -118
  12. data/app/assets/javascripts/polymer/src/lib/array-splice.html +0 -262
  13. data/app/assets/javascripts/polymer/src/lib/async.html +0 -68
  14. data/app/assets/javascripts/polymer/src/lib/base.html +0 -117
  15. data/app/assets/javascripts/polymer/src/lib/bind/accessors.html +0 -223
  16. data/app/assets/javascripts/polymer/src/lib/bind/demo/app-chrome.html +0 -28
  17. data/app/assets/javascripts/polymer/src/lib/bind/demo/app.html +0 -29
  18. data/app/assets/javascripts/polymer/src/lib/bind/demo/src/annotations-bind-demo.html +0 -76
  19. data/app/assets/javascripts/polymer/src/lib/bind/demo/src/bind-demo.html +0 -83
  20. data/app/assets/javascripts/polymer/src/lib/bind/effects.html +0 -80
  21. data/app/assets/javascripts/polymer/src/lib/case-map.html +0 -46
  22. data/app/assets/javascripts/polymer/src/lib/collection.html +0 -179
  23. data/app/assets/javascripts/polymer/src/lib/css-parse.html +0 -131
  24. data/app/assets/javascripts/polymer/src/lib/debounce.html +0 -69
  25. data/app/assets/javascripts/polymer/src/lib/dom-api.html +0 -467
  26. data/app/assets/javascripts/polymer/src/lib/dom-module.html +0 -68
  27. data/app/assets/javascripts/polymer/src/lib/event-api.html +0 -92
  28. data/app/assets/javascripts/polymer/src/lib/expr/focus.html +0 -22
  29. data/app/assets/javascripts/polymer/src/lib/expr/gestures.html +0 -1
  30. data/app/assets/javascripts/polymer/src/lib/expr/log.html +0 -21
  31. data/app/assets/javascripts/polymer/src/lib/expr/sinspect.html +0 -235
  32. data/app/assets/javascripts/polymer/src/lib/expr/style-auditor.html +0 -123
  33. data/app/assets/javascripts/polymer/src/lib/expr/style-protector.html +0 -52
  34. data/app/assets/javascripts/polymer/src/lib/gestures.html +0 -284
  35. data/app/assets/javascripts/polymer/src/lib/lang.html +0 -21
  36. data/app/assets/javascripts/polymer/src/lib/module.html +0 -56
  37. data/app/assets/javascripts/polymer/src/lib/polymer-bootstrap.html +0 -78
  38. data/app/assets/javascripts/polymer/src/lib/resolve-url.html +0 -82
  39. data/app/assets/javascripts/polymer/src/lib/settings.html +0 -52
  40. data/app/assets/javascripts/polymer/src/lib/style-defaults.html +0 -32
  41. data/app/assets/javascripts/polymer/src/lib/style-transformer.html +0 -185
  42. data/app/assets/javascripts/polymer/src/lib/style-util.html +0 -77
  43. data/app/assets/javascripts/polymer/src/lib/template/templatizer.html +0 -132
  44. data/app/assets/javascripts/polymer/src/lib/template/x-array-selector.html +0 -178
  45. data/app/assets/javascripts/polymer/src/lib/template/x-autobind.html +0 -80
  46. data/app/assets/javascripts/polymer/src/lib/template/x-if.html +0 -115
  47. data/app/assets/javascripts/polymer/src/lib/template/x-repeat.html +0 -510
  48. data/app/assets/javascripts/polymer/src/lib/template/x-template.html +0 -39
  49. data/app/assets/javascripts/polymer/src/lib/x-style.html +0 -115
  50. data/app/assets/javascripts/polymer/src/micro/attributes.html +0 -180
  51. data/app/assets/javascripts/polymer/src/micro/constructor.html +0 -74
  52. data/app/assets/javascripts/polymer/src/micro/extends.html +0 -79
  53. data/app/assets/javascripts/polymer/src/micro/mixins.html +0 -40
  54. data/app/assets/javascripts/polymer/src/micro/properties.html +0 -96
  55. data/app/assets/javascripts/polymer/src/micro/tag.html +0 -28
  56. data/app/assets/javascripts/polymer/src/mini/ready.html +0 -180
  57. data/app/assets/javascripts/polymer/src/mini/shadow.html +0 -41
  58. data/app/assets/javascripts/polymer/src/mini/shady.html +0 -365
  59. data/app/assets/javascripts/polymer/src/mini/template.html +0 -56
  60. data/app/assets/javascripts/polymer/src/polymer-lib.html +0 -15
  61. data/app/assets/javascripts/polymer/src/standard/annotations.html +0 -198
  62. data/app/assets/javascripts/polymer/src/standard/configure.html +0 -160
  63. data/app/assets/javascripts/polymer/src/standard/effects.html +0 -215
  64. data/app/assets/javascripts/polymer/src/standard/events.html +0 -127
  65. data/app/assets/javascripts/polymer/src/standard/notify-path.html +0 -260
  66. data/app/assets/javascripts/polymer/src/standard/resolveUrl.html +0 -27
  67. data/app/assets/javascripts/polymer/src/standard/styling.html +0 -157
  68. data/app/assets/javascripts/polymer/src/standard/utils.html +0 -158
  69. data/app/assets/javascripts/polymer/src/standard/x-styling.html +0 -300
@@ -1,178 +0,0 @@
1
- <!--
2
- @license
3
- Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
4
- This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5
- The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6
- The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7
- Code distributed by Google as part of the polymer project is also
8
- subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9
- -->
10
-
11
- <!--
12
- Keeping structured data in sync requires that Polymer understand the path
13
- associations of data being bound. The `x-array-selector` element ensures path
14
- linkage when selecting specific items from an array (either single or multiple).
15
- The `items` property accepts an array of user data, and via the `select(item)`
16
- and `deselect(item)` API, updates the `selected` property which may be bound to
17
- other parts of the application, and any changes to sub-fields of `selected`
18
- item(s) will be kept in sync with items in the `items` array. When `multi`
19
- is false, `selected` is a property representing the last selected item. When
20
- `multi` is true, `selected` is an array of multiply selected items.
21
-
22
- ```html
23
- <dom-module id="employee-list">
24
-
25
- <template>
26
-
27
- <div> Employee list: </div>
28
- <template is="x-repeat" id="employeeList" items="{{employees}}">
29
- <div>First name: <span>{{item.first}}</span></div>
30
- <div>Last name: <span>{{item.last}}</span></div>
31
- <button on-click="toggleSelection">Select</button>
32
- </template>
33
-
34
- <x-array-selector id="selector" items="{{employees}}" selected="{{selected}}" multi toggle></x-array-selector>
35
-
36
- <div> Selected employees: </div>
37
- <template is="x-repeat" items="{{selected}}">
38
- <div>First name: <span>{{item.first}}</span></div>
39
- <div>Last name: <span>{{item.last}}</span></div>
40
- </template>
41
-
42
- </template>
43
-
44
- <script>
45
- Polymer({
46
- is: 'employee-list',
47
- ready: function() {
48
- this.employees = [
49
- {first: 'Bob', last: 'Smith'},
50
- {first: 'Sally', last: 'Johnson'},
51
- ...
52
- ];
53
- },
54
- toggleSelection: function(e) {
55
- var item = this.$.employeeList.itemForElement(e.target);
56
- this.$.selector.select(item);
57
- }
58
- });
59
- </script>
60
-
61
- </dom-module>
62
- ```
63
- -->
64
-
65
- <script>
66
-
67
- Polymer({
68
- is: 'x-array-selector',
69
-
70
- properties: {
71
-
72
- /**
73
- * An array containing items from which selection will be made.
74
- */
75
- items: {
76
- type: Array,
77
- observer: '_itemsChanged'
78
- },
79
-
80
- /**
81
- * When `multi` is true, this is an array that contains any selected.
82
- * When `multi` is false, this is the currently selected item, or `null`
83
- * if no item is selected.
84
- */
85
- selected: {
86
- type: Object,
87
- notify: true
88
- },
89
-
90
- /**
91
- * When `true`, calling `select` on an item that is already selected
92
- * will deselect the item.
93
- */
94
- toggle: Boolean,
95
-
96
- /**
97
- * When `true`, multiple items may be selected at once (in this case,
98
- * `selected` is an array of currently selected items). When `false`,
99
- * only one item may be selected at a time.
100
- */
101
- multi: Boolean
102
- },
103
-
104
- _itemsChanged: function() {
105
- // Unbind previous selection
106
- if (Array.isArray(this.selected)) {
107
- for (var i=0; i<this.selected.length; i++) {
108
- this.unbindPaths('selected.' + i);
109
- }
110
- } else {
111
- this.unbindPaths('selected');
112
- }
113
- // Initialize selection
114
- if (this.multi) {
115
- this.selected = [];
116
- } else {
117
- this.selected = null;
118
- }
119
- },
120
-
121
- /**
122
- * Deselects the given item if it is already selected.
123
- */
124
- deselect: function(item) {
125
- if (this.multi) {
126
- var scol = Polymer.Collection.get(this.selected);
127
- // var skey = scol.getKey(item);
128
- // if (skey >= 0) {
129
- var sidx = this.selected.indexOf(item);
130
- if (sidx >= 0) {
131
- var skey = scol.getKey(item);
132
- this.selected.splice(sidx, 1);
133
- // scol.remove(item);
134
- this.unbindPaths('selected.' + skey);
135
- return true;
136
- }
137
- } else {
138
- this.selected = null;
139
- this.unbindPaths('selected');
140
- }
141
- },
142
-
143
- /**
144
- * Selects the given item. When `toggle` is true, this will automatically
145
- * deselect the item if already selected.
146
- */
147
- select: function(item) {
148
- var icol = Polymer.Collection.get(this.items);
149
- var key = icol.getKey(item);
150
- if (this.multi) {
151
- // var sidx = this.selected.indexOf(item);
152
- // if (sidx < 0) {
153
- var scol = Polymer.Collection.get(this.selected);
154
- var skey = scol.getKey(item);
155
- if (skey >= 0) {
156
- this.deselect(item);
157
- } else if (this.toggle) {
158
- this.selected.push(item);
159
- // this.bindPaths('selected.' + sidx, 'items.' + skey);
160
- // skey = Polymer.Collection.get(this.selected).add(item);
161
- this.async(function() {
162
- skey = scol.getKey(item);
163
- this.bindPaths('selected.' + skey, 'items.' + key);
164
- });
165
- }
166
- } else {
167
- if (this.toggle && item == this.selected) {
168
- this.deselect();
169
- } else {
170
- this.bindPaths('selected', 'items.' + key);
171
- this.selected = item;
172
- }
173
- }
174
- }
175
-
176
- });
177
-
178
- </script>
@@ -1,80 +0,0 @@
1
- <!--
2
- @license
3
- Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
4
- This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5
- The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6
- The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7
- Code distributed by Google as part of the polymer project is also
8
- subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9
- -->
10
-
11
- <!--
12
-
13
- **THIS ELEMENT IS EXPERIMENTAL. API AND NAME SUBJECT TO CHANGE.**
14
-
15
- Polymer's binding features are only available within templates that are managed
16
- by Polymer. As such, these features are available in templates used to define
17
- Polymer elements, for example, but not for elements placed directly in the main
18
- document.
19
-
20
- In order to use Polymer bindings without defining a new custom element, elements
21
- utilizing bindings may be wrapped with the `x-autobind` template extension.
22
- This template will immediately stamp itself into the main document and bind
23
- elements to the template itself as the binding scope.
24
-
25
- ```html
26
- <!doctype html>
27
- <html>
28
- <head>
29
- <meta charset="utf-8">
30
- <script src="components/webcomponentsjs/webcomponents-lite.js"></script>
31
- <link rel="import" href="components/polymer/polymer.html">
32
- <link rel="import" href="components/core-ajax/core-ajax.html">
33
-
34
- </head>
35
- <body>
36
-
37
- <template is="x-autobind">
38
-
39
- <core-ajax url="http://..." lastresponse="{{data}}"></core-ajax>
40
-
41
- <template is="x-repeat" items="{{data}}">
42
- <div><span>{{item.first}}</span> <span>{{item.last}}</span></div>
43
- </template>
44
-
45
- </template>
46
-
47
- </body>
48
- </html>
49
- ```
50
-
51
- -->
52
-
53
- <script>
54
-
55
- Polymer({
56
-
57
- is: 'x-autobind',
58
-
59
- extends: 'template',
60
-
61
- registerFeatures: function() {
62
- this._prepExtends();
63
- this._prepConstructor();
64
- },
65
-
66
- _finishDistribute: function() {
67
- var parentDom = Polymer.dom(Polymer.dom(this).parentNode);
68
- parentDom.insertBefore(this.root, this);
69
- },
70
-
71
- initFeatures: function() {
72
- this._template = this;
73
- this._prepAnnotations();
74
- this._prepEffects();
75
- Polymer.Base.initFeatures.call(this);
76
- }
77
-
78
- });
79
-
80
- </script>
@@ -1,115 +0,0 @@
1
- <!--
2
- @license
3
- Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
4
- This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5
- The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6
- The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7
- Code distributed by Google as part of the polymer project is also
8
- subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9
- -->
10
-
11
- <link rel="import" href="templatizer.html">
12
-
13
- <script>
14
-
15
- /**
16
- * Stamps the template iff the `if` property is truthy.
17
- *
18
- * When `if` becomes falsey, the stamped content is hidden but not
19
- * removed from dom. When `if` subsequently becomes truthy again, the content
20
- * is simply re-shown. This approach is used due to its favorable performance
21
- * characteristics: the expense of creating template content is paid only
22
- * once and lazily.
23
- *
24
- * Set the `restamp` property to true to force the stamped content to be
25
- * created / destroyed when the `if` condition changes.
26
- */
27
- Polymer({
28
-
29
- is: 'x-if',
30
- extends: 'template',
31
-
32
- properties: {
33
-
34
- 'if': {
35
- type: Boolean
36
- },
37
-
38
- item: {
39
- type: Object
40
- },
41
-
42
- restamp: {
43
- type: Boolean
44
- }
45
-
46
- },
47
-
48
- mixins: [
49
- Polymer.Templatizer
50
- ],
51
-
52
- observers: {
53
- 'if item restamp': 'render'
54
- },
55
-
56
- render: function() {
57
- if (!this.ctor) {
58
- this._wrapTextNodes(this._content);
59
- this.templatize(this);
60
- }
61
- if (this.if) {
62
- this._ensureInstance();
63
- } else if (this.restamp) {
64
- this._teardownInstance();
65
- }
66
- if (!this.restamp && this._instance) {
67
- this._showHideInstance(this.if);
68
- }
69
- },
70
-
71
- _ensureInstance: function() {
72
- if (!this._instance) {
73
- // TODO(sorvell): pickup stamping logic from x-repeat
74
- this._instance = this.stamp(this.item);
75
- var root = this._instance.root;
76
- this._instance._children = Array.prototype.slice.call(root.childNodes);
77
- // TODO(sorvell): this incantation needs to be simpler.
78
- var parent = Polymer.dom(Polymer.dom(this).parentNode);
79
- parent.insertBefore(root, this);
80
- }
81
- },
82
-
83
- _teardownInstance: function() {
84
- if (this._instance) {
85
- var parent = Polymer.dom(Polymer.dom(this).parentNode);
86
- this._instance._children.forEach(function(n) {
87
- parent.removeChild(n);
88
- });
89
- this._instance = null;
90
- }
91
- },
92
-
93
- _wrapTextNodes: function(root) {
94
- // wrap text nodes in span so they can be hidden.
95
- for (var n = root.firstChild; n; n=n.nextSibling) {
96
- if (n.nodeType === Node.TEXT_NODE) {
97
- var s = document.createElement('span');
98
- root.insertBefore(s, n);
99
- s.appendChild(n);
100
- n = s;
101
- }
102
- }
103
- },
104
-
105
- _showHideInstance: function(showing) {
106
- this._instance._children.forEach(function(n) {
107
- if (n.setAttribute) {
108
- this.serializeValueToAttribute(!showing, 'hidden', n);
109
- }
110
- }, this);
111
- }
112
-
113
- });
114
-
115
- </script>
@@ -1,510 +0,0 @@
1
- <!--
2
- @license
3
- Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
4
- This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5
- The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6
- The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7
- Code distributed by Google as part of the polymer project is also
8
- subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9
- -->
10
-
11
- <!--
12
-
13
- **THIS ELEMENT IS EXPERIMENTAL. API AND NAME SUBJECT TO CHANGE.**
14
-
15
- The `x-repeat` element is a custom `HTMLTemplateElement` type extension that
16
- automatically stamps and binds one instance of template content to each object
17
- in a user-provided array. `x-repeat` accepts an `items` property, and one
18
- instance of the template is stamped for each item into the DOM at the location
19
- of the `x-repeat` element. The `item` property will be set on each instance's
20
- binding scope, thus templates should bind to sub-properties of `item`.
21
-
22
- Example:
23
-
24
- ```html
25
- <dom-module id="employee-list">
26
-
27
- <template>
28
-
29
- <div> Employee list: </div>
30
- <template is="x-repeat" items="{{employees}}">
31
- <div>First name: <span>{{item.first}}</span></div>
32
- <div>Last name: <span>{{item.last}}</span></div>
33
- </template>
34
-
35
- </template>
36
-
37
- <script>
38
- Polymer({
39
- is: 'employee-list',
40
- ready: function() {
41
- this.employees = [
42
- {first: 'Bob', last: 'Smith'},
43
- {first: 'Sally', last: 'Johnson'},
44
- ...
45
- ];
46
- }
47
- });
48
- </script>
49
-
50
- </dom-module>
51
- ```
52
-
53
- Notifications for changes to items sub-properties will be forwarded to template
54
- instances, which will update via the normal structured data notification system.
55
-
56
- Mutations to the `items` array itself (`push`, `pop`, `splice`, `shift`,
57
- `unshift`) are observed via `Array.observe` (where supported, or an
58
- shim of this API on unsupported browsers), and template instances are kept in
59
- sync with the data in the array.
60
-
61
- A view-specific filter/sort may be applied to each `x-repeat` by supplying a
62
- `filter` and/or `sort` property. This may be a string that names a function on
63
- the host, or a function may be assigned to the property directly. The functions
64
- should implemented following the standard `Array` filter/sort API.
65
-
66
- In order to re-run the filter or sort functions based on changes to sub-fields
67
- of `items`, the `observe` property may be set as a space-separated list of
68
- `item` sub-fields that should cause a re-filter/sort when modified.
69
-
70
- For example, for an `x-repeat` with a filter of the following:
71
-
72
- ```js
73
- isEngineer: function(item) {
74
- return item.type == 'engineer' || item.manager.type == 'engineer';
75
- }
76
- ```
77
-
78
- Then the `observe` property should be configured as follows:
79
-
80
- ```html
81
- <template is="x-repeat" items="{{employees}}"
82
- filter="isEngineer" observe="type manager.type">
83
- ```
84
-
85
- -->
86
-
87
- <link rel="import" href="templatizer.html">
88
- <link rel="import" href="../array-observe.html">
89
- <link rel="import" href="../collection.html">
90
-
91
- <script>
92
-
93
- Polymer({
94
-
95
- is: 'x-repeat',
96
- extends: 'template',
97
-
98
- properties: {
99
-
100
- /**
101
- * An array containing items determining how many instances of the template
102
- * to stamp and that that each template instance should bind to.
103
- */
104
- items: {
105
- type: Array
106
- },
107
-
108
- /**
109
- * A function that should determine the sort order of the items. This
110
- * property should either be provided as a string, indicating a method
111
- * name on the element's host, or else be an actual function. The
112
- * function should match the sort function passed to `Array.sort`.
113
- * Using a sort function has no effect on the underlying `items` array.
114
- */
115
- sort: {
116
- type: Function,
117
- observer: '_sortChanged'
118
- },
119
-
120
- /**
121
- * A function that can be used to filter items out of the view. This
122
- * property should either be provided as a string, indicating a method
123
- * name on the element's host, or else be an actual function. The
124
- * function should match the sort function passed to `Array.filter`.
125
- * Using a filter function has no effect on the underlying `items` array.
126
- */
127
- filter: {
128
- type: Function,
129
- observer: '_filterChanged'
130
- },
131
-
132
- /**
133
- * When using a `filter` or `sort` function, the `observe` property
134
- * should be set to a space-separated list of the names of item
135
- * sub-fields that should trigger a re-sort or re-filter when changed.
136
- * These should generally be fields of `item` that the sort or filter
137
- * function depends on.
138
- */
139
- observe: {
140
- type: String,
141
- observer: '_observeChanged'
142
- },
143
-
144
- /**
145
- * When using a `filter` or `sort` function, the `delay` property
146
- * determines a debounce time after a change to observed item
147
- * properties that must pass before the filter or sort is re-run.
148
- * This is useful in rate-limiting shuffing of the view when
149
- * item changes may be frequent.
150
- */
151
- delay: Number
152
- },
153
-
154
- mixins: [
155
- Polymer.Templatizer
156
- ],
157
-
158
- observers: {
159
- 'items.*': '_itemsChanged'
160
- },
161
-
162
- created: function() {
163
- this.boundCollectionObserver = this.render.bind(this);
164
- },
165
-
166
- ready: function() {
167
- // Templatizing (generating the instance constructor) needs to wait
168
- // until attached, since it may not have its template content handed
169
- // back to it until then, following its host template stamping
170
- if (!this.ctor) {
171
- this.templatize(this);
172
- }
173
- if (this._renderPendingAttach) {
174
- this._renderPendingAttach = false;
175
- this.render();
176
- }
177
- },
178
-
179
- _sortChanged: function() {
180
- this._sortFn = this.sort && (typeof this.sort == 'function' ?
181
- this.sort : this.host[this.sort].bind(this.host));
182
- this.debounce('render', this.render);
183
- },
184
-
185
- _filterChanged: function() {
186
- this._filterFn = this.filter && (typeof this.filter == 'function' ?
187
- this.filter : this.host[this.filter].bind(this.host));
188
- this.debounce('render', this.render);
189
- },
190
-
191
- _observeChanged: function() {
192
- this._observePaths = this.observe &&
193
- this.observe.replace('.*', '.').split(' ');
194
- },
195
-
196
- _itemsChanged: function(items, old, path) {
197
- if (path) {
198
- this._notifyElement(path, items);
199
- this._checkObservedPaths(path);
200
- } else {
201
- if (old) {
202
- this._unobserveCollection(old);
203
- }
204
- if (items) {
205
- this._observeCollection(items);
206
- this.debounce('render', this.render);
207
- }
208
- }
209
- },
210
-
211
- _checkObservedPaths: function(path) {
212
- if (this._observePaths && path.indexOf('items.') === 0) {
213
- path = path.substring(path.indexOf('.', 6) + 1);
214
- var paths = this._observePaths;
215
- for (var i=0; i<paths.length; i++) {
216
- if (path.indexOf(paths[i]) === 0) {
217
- this.debounce('render', this.render, this.delay);
218
- return;
219
- }
220
- }
221
- }
222
- },
223
-
224
- _observeCollection: function(items) {
225
- this.collection = Array.isArray(items) ? Polymer.Collection.get(items) : items;
226
- this.collection.observe(this.boundCollectionObserver);
227
- },
228
-
229
- _unobserveCollection: function(items) {
230
- var collection = Polymer.Collection.get(items);
231
- collection.unobserve(this.boundCollectionObserver);
232
- },
233
-
234
- render: function(splices) {
235
- // TODO(kschaaf): should actually queue splices also
236
- if (!this.isAttached) {
237
- // Render must follow attachment
238
- this._renderPendingAttach = true;
239
- return;
240
- }
241
- this._render(splices);
242
- },
243
-
244
- _render: function(splices) {
245
- var c = this.collection;
246
- if (splices) {
247
- if (this._sortFn || splices[0].index == null) {
248
- this._applySplicesViewSort(splices);
249
- } else {
250
- this._applySplicesArraySort(splices);
251
- }
252
- } else {
253
- this._sortAndFilter();
254
- }
255
- var rowForKey = this._rowForKey = {};
256
- var keys = this._orderedKeys;
257
- // Assign items and keys
258
- this.rows = this.rows || [];
259
- for (var i=0; i<keys.length; i++) {
260
- var key = keys[i];
261
- var item = c.getItem(key);
262
- var row = this.rows[i];
263
- if (!row) {
264
- this.rows.push(row = this._insertRow(i, null, item));
265
- }
266
- row.item = item;
267
- row.key = key;
268
- rowForKey[key] = i;
269
- }
270
- // Remove extra
271
- for (; i<this.rows.length; i++) {
272
- this._detachRow(i);
273
- }
274
- this.rows.splice(keys.length, this.rows.length-keys.length);
275
- },
276
-
277
- _sortAndFilter: function() {
278
- var c = this.collection;
279
- this._orderedKeys = c.getKeys();
280
- // Filter
281
- if (this._filterFn) {
282
- this._orderedKeys = this._orderedKeys.filter(function(a) {
283
- return this._filterFn(c.getItem(a));
284
- }, this);
285
- }
286
- // Sort
287
- if (this._sortFn) {
288
- this._orderedKeys.sort(function(a, b) {
289
- return this._sortFn(c.getItem(a), c.getItem(b));
290
- }.bind(this));
291
- }
292
- },
293
-
294
- _keySort: function(a, b) {
295
- return this.collection.getKey(a) - this.collection.getKey(b);
296
- },
297
-
298
- _applySplicesViewSort: function(splices) {
299
- var c = this.collection;
300
- var keys = this._orderedKeys;
301
- var rows = this.rows;
302
- var removedRows = [];
303
- var addedKeys = [];
304
- var pool = [];
305
- var sortFn = this._sortFn || this._keySort.bind(this);
306
- splices.forEach(function(s) {
307
- // Collect all removed row idx's
308
- for (var i=0; i<s.removed.length; i++) {
309
- var idx = this._rowForKey[s.removed[i]];
310
- if (idx != null) {
311
- removedRows.push(idx);
312
- }
313
- }
314
- // Collect all added keys
315
- for (i=0; i<s.added.length; i++) {
316
- addedKeys.push(s.added[i]);
317
- }
318
- }, this);
319
- if (removedRows.length) {
320
- // Sort removed rows idx's
321
- removedRows.sort();
322
- // Remove keys and pool rows (backwards, so we don't invalidate rowForKey)
323
- for (i=removedRows.length-1; i>=0 ; i--) {
324
- var idx = removedRows[i];
325
- pool.push(this._detachRow(idx));
326
- rows.splice(idx, 1);
327
- keys.splice(idx, 1);
328
- }
329
- }
330
- if (addedKeys.length) {
331
- // Filter added keys
332
- if (this._filterFn) {
333
- addedKeys = addedKeys.filter(function(a) {
334
- return this._filterFn(c.getItem(a));
335
- }, this);
336
- }
337
- // Sort added keys
338
- addedKeys.sort(function(a, b) {
339
- return this.sortFn(c.getItem(a), c.getItem(b));
340
- }, this);
341
- // Insert new rows using sort (from pool or newly created)
342
- var start = 0;
343
- for (i=0; i<addedKeys.length; i++) {
344
- start = this._insertRowIntoViewSort(start, addedKeys[i], pool);
345
- }
346
- }
347
- },
348
-
349
- _insertRowIntoViewSort: function(start, key, pool) {
350
- var c = this.collection;
351
- var item = c.getItem(key);
352
- var end = this.rows.length - 1;
353
- var idx = -1;
354
- var sortFn = this._sortFn || this._keySort.bind(this);
355
- // Binary search for insertion point
356
- while (start <= end) {
357
- var mid = (start + end) >> 1;
358
- var midKey = this._orderedKeys[mid];
359
- var cmp = sortFn(c.getItem(midKey), item);
360
- if (cmp < 0) {
361
- start = mid + 1;
362
- } else if (cmp > 0) {
363
- end = mid - 1;
364
- } else {
365
- idx = mid;
366
- break;
367
- }
368
- }
369
- if (idx < 0) {
370
- idx = end + 1;
371
- }
372
- // Insert key & row at insertion point
373
- this._orderedKeys.splice(idx, 0, key);
374
- this.rows.splice(idx, 0, this._insertRow(idx, pool));
375
- return idx;
376
- },
377
-
378
- _applySplicesArraySort: function(splices) {
379
- var keys = this._orderedKeys;
380
- var pool = [];
381
- splices.forEach(function(s) {
382
- // Remove & pool rows first, to ensure we can fully reuse removed rows
383
- for (var i=0; i<s.removed.length; i++) {
384
- pool.push(this._detachRow(s.index + i));
385
- }
386
- this.rows.splice(s.index, s.removed.length);
387
- }, this);
388
- var c = this.collection;
389
- var filterDelta = 0;
390
- splices.forEach(function(s) {
391
- // Filter added keys
392
- var addedKeys = s.added;
393
- if (this._filterFn) {
394
- addedKeys = addedKeys.filter(function(a) {
395
- return this._filterFn(c.getItem(a));
396
- }, this);
397
- filterDelta += (s.added.length - addedKeys.length);
398
- }
399
- var idx = s.index - filterDelta;
400
- // Apply splices to keys
401
- var args = [idx, s.removed.length].concat(addedKeys);
402
- keys.splice.apply(keys, args);
403
- // Insert new rows (from pool or newly created)
404
- var addedRows = [];
405
- for (i=0; i<s.added.length; i++) {
406
- addedRows.push(this._insertRow(idx + i, pool));
407
- }
408
- args = [s.index, 0].concat(addedRows);
409
- this.rows.splice.apply(this.rows, args);
410
- }, this);
411
- },
412
-
413
- _detachRow: function(idx) {
414
- var row = this.rows[idx];
415
- var parentNode = Polymer.dom(this).parentNode;
416
- for (var i=0; i<row._children.length; i++) {
417
- var el = row._children[i];
418
- Polymer.dom(row.root).appendChild(el);
419
- }
420
- return row;
421
- },
422
-
423
- _insertRow: function(idx, pool, item) {
424
- var row = (pool && pool.pop()) || this._generateRow(idx, item);
425
- var beforeRow = this.rows[idx];
426
- var beforeNode = beforeRow ? beforeRow._children[0] : this;
427
- var parentNode = Polymer.dom(this).parentNode;
428
- row.root.__styleScoped = true;
429
- Polymer.dom(parentNode).insertBefore(row.root, beforeNode);
430
- return row;
431
- },
432
-
433
- _generateRow: function(idx, item) {
434
- var row = this.stamp({
435
- item: item,
436
- pathDelegate: this
437
- });
438
- // each row is a document fragment which is lost when we appendChild,
439
- // so we have to track each child individually
440
- var children = [];
441
- for (var n = row.root.firstChild; n; n=n.nextSibling) {
442
- children.push(n);
443
- n._templateInstance = row;
444
- }
445
- // Since archetype overrides Base/HTMLElement, Safari complains
446
- // when accessing `children`
447
- row._children = children;
448
- return row;
449
- },
450
-
451
- _notifyDelegatePath: function(row, path, value) {
452
- this.notifyPath(path.replace('item', 'items.' + row.key), value);
453
- },
454
-
455
- _notifyElement: function(path, value) {
456
- if (this._rowForKey) {
457
- // 'items.'.length == 6
458
- var dot = path.indexOf('.', 6);
459
- var key = path.substring(6, dot < 0 ? path.length : dot);
460
- var idx = this._rowForKey[key];
461
- var row = this.rows[idx];
462
- if (row) {
463
- if (dot >= 0) {
464
- path = 'item.' + path.substring(dot+1);
465
- row.notifyPath(path, value, true);
466
- } else {
467
- row.item = value;
468
- }
469
- }
470
- }
471
- },
472
-
473
- _instanceForElement: function(el) {
474
- while (el && !el._templateInstance) {
475
- el = el.parentNode;
476
- }
477
- return el._templateInstance;
478
- },
479
-
480
- /**
481
- * Returns the item associated with a given element stamped by
482
- * this `x-repeat`.
483
- */
484
- itemForElement: function(el) {
485
- var instance = this._instanceForElement(el);
486
- return instance && instance.item;
487
- },
488
-
489
- /**
490
- * Returns the `Polymer.Collection` key associated with a given
491
- * element stamped by this `x-repeat`.
492
- */
493
- keyForElement: function(el) {
494
- var instance = this._instanceForElement(el);
495
- return instance && instance.key;
496
- },
497
-
498
- /**
499
- * Returns the index in `items` associated with a given element
500
- * stamped by this `x-repeat`.
501
- */
502
- indexForElement: function(el) {
503
- var instance = this._instanceForElement(el);
504
- return this.rows.indexOf(instance);
505
- }
506
-
507
- });
508
-
509
-
510
- </script>