| OLD | NEW |
| (Empty) |
| 1 | |
| 2 | |
| 3 /** @polymerBehavior */ | |
| 4 Polymer.IronSelectableBehavior = { | |
| 5 | |
| 6 properties: { | |
| 7 | |
| 8 /** | |
| 9 * If you want to use the attribute value of an element for `selected` ins
tead of the index, | |
| 10 * set this to the name of the attribute. | |
| 11 * | |
| 12 * @attribute attrForSelected | |
| 13 * @type {string} | |
| 14 */ | |
| 15 attrForSelected: { | |
| 16 type: String, | |
| 17 value: null | |
| 18 }, | |
| 19 | |
| 20 /** | |
| 21 * Gets or sets the selected element. The default is to use the index of t
he item. | |
| 22 * | |
| 23 * @attribute selected | |
| 24 * @type {string} | |
| 25 */ | |
| 26 selected: { | |
| 27 type: String, | |
| 28 notify: true | |
| 29 }, | |
| 30 | |
| 31 /** | |
| 32 * Returns the currently selected item. | |
| 33 * | |
| 34 * @attribute selectedItem | |
| 35 * @type {Object} | |
| 36 */ | |
| 37 selectedItem: { | |
| 38 type: Object, | |
| 39 readOnly: true, | |
| 40 notify: true | |
| 41 }, | |
| 42 | |
| 43 /** | |
| 44 * The event that fires from items when they are selected. Selectable | |
| 45 * will listen for this event from items and update the selection state. | |
| 46 * Set to empty string to listen to no events. | |
| 47 * | |
| 48 * @attribute activateEvent | |
| 49 * @type {string} | |
| 50 * @default 'tap' | |
| 51 */ | |
| 52 activateEvent: { | |
| 53 type: String, | |
| 54 value: 'tap', | |
| 55 observer: '_activateEventChanged' | |
| 56 }, | |
| 57 | |
| 58 /** | |
| 59 * This is a CSS selector sting. If this is set, only items that matches
the CSS selector | |
| 60 * are selectable. | |
| 61 * | |
| 62 * @attribute selectable | |
| 63 * @type {string} | |
| 64 */ | |
| 65 selectable: String, | |
| 66 | |
| 67 /** | |
| 68 * The class to set on elements when selected. | |
| 69 * | |
| 70 * @attribute selectedClass | |
| 71 * @type {string} | |
| 72 */ | |
| 73 selectedClass: { | |
| 74 type: String, | |
| 75 value: 'iron-selected' | |
| 76 }, | |
| 77 | |
| 78 /** | |
| 79 * The attribute to set on elements when selected. | |
| 80 * | |
| 81 * @attribute selectedAttribute | |
| 82 * @type {string} | |
| 83 */ | |
| 84 selectedAttribute: { | |
| 85 type: String, | |
| 86 value: null | |
| 87 } | |
| 88 | |
| 89 }, | |
| 90 | |
| 91 observers: [ | |
| 92 '_updateSelected(attrForSelected, selected)' | |
| 93 ], | |
| 94 | |
| 95 excludedLocalNames: { | |
| 96 'template': 1 | |
| 97 }, | |
| 98 | |
| 99 created: function() { | |
| 100 this._bindFilterItem = this._filterItem.bind(this); | |
| 101 this._selection = new Polymer.IronSelection(this._applySelection.bind(this
)); | |
| 102 }, | |
| 103 | |
| 104 attached: function() { | |
| 105 this._observer = this._observeItems(this); | |
| 106 this._contentObserver = this._observeContent(this); | |
| 107 }, | |
| 108 | |
| 109 detached: function() { | |
| 110 if (this._observer) { | |
| 111 this._observer.disconnect(); | |
| 112 } | |
| 113 if (this._contentObserver) { | |
| 114 this._contentObserver.disconnect(); | |
| 115 } | |
| 116 this._removeListener(this.activateEvent); | |
| 117 }, | |
| 118 | |
| 119 /** | |
| 120 * Returns an array of selectable items. | |
| 121 * | |
| 122 * @property items | |
| 123 * @type Array | |
| 124 */ | |
| 125 get items() { | |
| 126 var nodes = Polymer.dom(this).queryDistributedElements(this.selectable ||
'*'); | |
| 127 return Array.prototype.filter.call(nodes, this._bindFilterItem); | |
| 128 }, | |
| 129 | |
| 130 /** | |
| 131 * Returns the index of the given item. | |
| 132 * | |
| 133 * @method indexOf | |
| 134 * @param {Object} item | |
| 135 * @returns Returns the index of the item | |
| 136 */ | |
| 137 indexOf: function(item) { | |
| 138 return this.items.indexOf(item); | |
| 139 }, | |
| 140 | |
| 141 /** | |
| 142 * Selects the given value. | |
| 143 * | |
| 144 * @method select | |
| 145 * @param {string} value the value to select. | |
| 146 */ | |
| 147 select: function(value) { | |
| 148 this.selected = value; | |
| 149 }, | |
| 150 | |
| 151 /** | |
| 152 * Selects the previous item. | |
| 153 * | |
| 154 * @method selectPrevious | |
| 155 */ | |
| 156 selectPrevious: function() { | |
| 157 var length = this.items.length; | |
| 158 var index = (Number(this._valueToIndex(this.selected)) - 1 + length) % len
gth; | |
| 159 this.selected = this._indexToValue(index); | |
| 160 }, | |
| 161 | |
| 162 /** | |
| 163 * Selects the next item. | |
| 164 * | |
| 165 * @method selectNext | |
| 166 */ | |
| 167 selectNext: function() { | |
| 168 var index = (Number(this._valueToIndex(this.selected)) + 1) % this.items.l
ength; | |
| 169 this.selected = this._indexToValue(index); | |
| 170 }, | |
| 171 | |
| 172 _addListener: function(eventName) { | |
| 173 this.listen(this, eventName, '_activateHandler'); | |
| 174 }, | |
| 175 | |
| 176 _removeListener: function(eventName) { | |
| 177 // There is no unlisten yet... | |
| 178 // https://github.com/Polymer/polymer/issues/1639 | |
| 179 //this.removeEventListener(eventName, this._bindActivateHandler); | |
| 180 }, | |
| 181 | |
| 182 _activateEventChanged: function(eventName, old) { | |
| 183 this._removeListener(old); | |
| 184 this._addListener(eventName); | |
| 185 }, | |
| 186 | |
| 187 _updateSelected: function() { | |
| 188 this._selectSelected(this.selected); | |
| 189 }, | |
| 190 | |
| 191 _selectSelected: function(selected) { | |
| 192 this._selection.select(this._valueToItem(this.selected)); | |
| 193 }, | |
| 194 | |
| 195 _filterItem: function(node) { | |
| 196 return !this.excludedLocalNames[node.localName]; | |
| 197 }, | |
| 198 | |
| 199 _valueToItem: function(value) { | |
| 200 return (value == null) ? null : this.items[this._valueToIndex(value)]; | |
| 201 }, | |
| 202 | |
| 203 _valueToIndex: function(value) { | |
| 204 if (this.attrForSelected) { | |
| 205 for (var i = 0, item; item = this.items[i]; i++) { | |
| 206 if (this._valueForItem(item) == value) { | |
| 207 return i; | |
| 208 } | |
| 209 } | |
| 210 } else { | |
| 211 return Number(value); | |
| 212 } | |
| 213 }, | |
| 214 | |
| 215 _indexToValue: function(index) { | |
| 216 if (this.attrForSelected) { | |
| 217 var item = this.items[index]; | |
| 218 if (item) { | |
| 219 return this._valueForItem(item); | |
| 220 } | |
| 221 } else { | |
| 222 return index; | |
| 223 } | |
| 224 }, | |
| 225 | |
| 226 _valueForItem: function(item) { | |
| 227 return item[this.attrForSelected] || item.getAttribute(this.attrForSelecte
d); | |
| 228 }, | |
| 229 | |
| 230 _applySelection: function(item, isSelected) { | |
| 231 if (this.selectedClass) { | |
| 232 this.toggleClass(this.selectedClass, isSelected, item); | |
| 233 } | |
| 234 if (this.selectedAttribute) { | |
| 235 this.toggleAttribute(this.selectedAttribute, isSelected, item); | |
| 236 } | |
| 237 this._selectionChange(); | |
| 238 this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {item: item}); | |
| 239 }, | |
| 240 | |
| 241 _selectionChange: function() { | |
| 242 this._setSelectedItem(this._selection.get()); | |
| 243 }, | |
| 244 | |
| 245 // observe content changes under the given node. | |
| 246 _observeContent: function(node) { | |
| 247 var content = node.querySelector('content'); | |
| 248 if (content && content.parentElement === node) { | |
| 249 return this._observeItems(node.domHost); | |
| 250 } | |
| 251 }, | |
| 252 | |
| 253 // observe items change under the given node. | |
| 254 _observeItems: function(node) { | |
| 255 var observer = new MutationObserver(function() { | |
| 256 if (this.selected != null) { | |
| 257 this._updateSelected(); | |
| 258 } | |
| 259 }.bind(this)); | |
| 260 observer.observe(node, { | |
| 261 childList: true, | |
| 262 subtree: true | |
| 263 }); | |
| 264 return observer; | |
| 265 }, | |
| 266 | |
| 267 _activateHandler: function(e) { | |
| 268 // TODO: remove this when https://github.com/Polymer/polymer/issues/1639 i
s fixed so we | |
| 269 // can just remove the old event listener. | |
| 270 if (e.type !== this.activateEvent) { | |
| 271 return; | |
| 272 } | |
| 273 var t = e.target; | |
| 274 var items = this.items; | |
| 275 while (t && t != this) { | |
| 276 var i = items.indexOf(t); | |
| 277 if (i >= 0) { | |
| 278 var value = this._indexToValue(i); | |
| 279 this._itemActivate(value, t); | |
| 280 return; | |
| 281 } | |
| 282 t = t.parentNode; | |
| 283 } | |
| 284 }, | |
| 285 | |
| 286 _itemActivate: function(value, item) { | |
| 287 if (!this.fire('iron-activate', | |
| 288 {selected: value, item: item}, {cancelable: true}).defaultPrevented) { | |
| 289 this.select(value); | |
| 290 } | |
| 291 } | |
| 292 | |
| 293 }; | |
| 294 | |
| OLD | NEW |