Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components / iron-selector / iron-selectable.html
blobf0506d58d9b5fab5a1701e5c4437f7e10f1b4f91
1 <!--
2 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
3 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
6 Code distributed by Google as part of the polymer project is also
7 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
8 -->
10 <link rel="import" href="../polymer/polymer.html">
11 <link rel="import" href="iron-selection.html">
13 <script>
15 /** @polymerBehavior */
16 Polymer.IronSelectableBehavior = {
18 properties: {
20 /**
21 * If you want to use the attribute value of an element for `selected` instead of the index,
22 * set this to the name of the attribute.
24 * @attribute attrForSelected
25 * @type {string}
27 attrForSelected: {
28 type: String,
29 value: null
32 /**
33 * Gets or sets the selected element. The default is to use the index of the item.
35 * @attribute selected
36 * @type {string}
38 selected: {
39 type: String,
40 notify: true
43 /**
44 * Returns the currently selected item.
46 * @attribute selectedItem
47 * @type {Object}
49 selectedItem: {
50 type: Object,
51 readOnly: true,
52 notify: true
55 /**
56 * The event that fires from items when they are selected. Selectable
57 * will listen for this event from items and update the selection state.
58 * Set to empty string to listen to no events.
60 * @attribute activateEvent
61 * @type {string}
62 * @default 'tap'
64 activateEvent: {
65 type: String,
66 value: 'tap',
67 observer: '_activateEventChanged'
70 /**
71 * This is a CSS selector sting. If this is set, only items that matches the CSS selector
72 * are selectable.
74 * @attribute selectable
75 * @type {string}
77 selectable: String,
79 /**
80 * The class to set on elements when selected.
82 * @attribute selectedClass
83 * @type {string}
85 selectedClass: {
86 type: String,
87 value: 'iron-selected'
90 /**
91 * The attribute to set on elements when selected.
93 * @attribute selectedAttribute
94 * @type {string}
96 selectedAttribute: {
97 type: String,
98 value: null
103 observers: [
104 '_updateSelected(attrForSelected, selected)'
107 excludedLocalNames: {
108 'template': 1
111 created: function() {
112 this._bindFilterItem = this._filterItem.bind(this);
113 this._selection = new Polymer.IronSelection(this._applySelection.bind(this));
116 attached: function() {
117 this._observer = this._observeItems(this);
118 this._contentObserver = this._observeContent(this);
121 detached: function() {
122 if (this._observer) {
123 this._observer.disconnect();
125 if (this._contentObserver) {
126 this._contentObserver.disconnect();
128 this._removeListener(this.activateEvent);
132 * Returns an array of selectable items.
134 * @property items
135 * @type Array
137 get items() {
138 var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
139 return Array.prototype.filter.call(nodes, this._bindFilterItem);
143 * Returns the index of the given item.
145 * @method indexOf
146 * @param {Object} item
147 * @returns Returns the index of the item
149 indexOf: function(item) {
150 return this.items.indexOf(item);
154 * Selects the given value.
156 * @method select
157 * @param {string} value the value to select.
159 select: function(value) {
160 this.selected = value;
164 * Selects the previous item.
166 * @method selectPrevious
168 selectPrevious: function() {
169 var length = this.items.length;
170 var index = (Number(this._valueToIndex(this.selected)) - 1 + length) % length;
171 this.selected = this._indexToValue(index);
175 * Selects the next item.
177 * @method selectNext
179 selectNext: function() {
180 var index = (Number(this._valueToIndex(this.selected)) + 1) % this.items.length;
181 this.selected = this._indexToValue(index);
184 _addListener: function(eventName) {
185 this.listen(this, eventName, '_activateHandler');
188 _removeListener: function(eventName) {
189 // There is no unlisten yet...
190 // https://github.com/Polymer/polymer/issues/1639
191 //this.removeEventListener(eventName, this._bindActivateHandler);
194 _activateEventChanged: function(eventName, old) {
195 this._removeListener(old);
196 this._addListener(eventName);
199 _updateSelected: function() {
200 this._selectSelected(this.selected);
203 _selectSelected: function(selected) {
204 this._selection.select(this._valueToItem(this.selected));
207 _filterItem: function(node) {
208 return !this.excludedLocalNames[node.localName];
211 _valueToItem: function(value) {
212 return (value == null) ? null : this.items[this._valueToIndex(value)];
215 _valueToIndex: function(value) {
216 if (this.attrForSelected) {
217 for (var i = 0, item; item = this.items[i]; i++) {
218 if (this._valueForItem(item) == value) {
219 return i;
222 } else {
223 return Number(value);
227 _indexToValue: function(index) {
228 if (this.attrForSelected) {
229 var item = this.items[index];
230 if (item) {
231 return this._valueForItem(item);
233 } else {
234 return index;
238 _valueForItem: function(item) {
239 return item[this.attrForSelected] || item.getAttribute(this.attrForSelected);
242 _applySelection: function(item, isSelected) {
243 if (this.selectedClass) {
244 this.toggleClass(this.selectedClass, isSelected, item);
246 if (this.selectedAttribute) {
247 this.toggleAttribute(this.selectedAttribute, isSelected, item);
249 this._selectionChange();
250 this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {item: item});
253 _selectionChange: function() {
254 this._setSelectedItem(this._selection.get());
257 // observe content changes under the given node.
258 _observeContent: function(node) {
259 var content = node.querySelector('content');
260 if (content && content.parentElement === node) {
261 return this._observeItems(node.domHost);
265 // observe items change under the given node.
266 _observeItems: function(node) {
267 var observer = new MutationObserver(function() {
268 if (this.selected != null) {
269 this._updateSelected();
271 }.bind(this));
272 observer.observe(node, {
273 childList: true,
274 subtree: true
276 return observer;
279 _activateHandler: function(e) {
280 // TODO: remove this when https://github.com/Polymer/polymer/issues/1639 is fixed so we
281 // can just remove the old event listener.
282 if (e.type !== this.activateEvent) {
283 return;
285 var t = e.target;
286 var items = this.items;
287 while (t && t != this) {
288 var i = items.indexOf(t);
289 if (i >= 0) {
290 var value = this._indexToValue(i);
291 this._itemActivate(value, t);
292 return;
294 t = t.parentNode;
298 _itemActivate: function(value, item) {
299 if (!this.fire('iron-activate',
300 {selected: value, item: item}, {cancelable: true}).defaultPrevented) {
301 this.select(value);
307 </script>