Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Side by Side Diff: bower_components/core-selector/core-selector.html

Issue 786953007: npm_modules: Fork bower_components into Polymer 0.4.0 and 0.5.0 versions (Closed) Base URL: https://chromium.googlesource.com/infra/third_party/npm_modules.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « bower_components/core-selector/bower.json ('k') | bower_components/core-selector/demo.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 <!--
2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3 This code may only be used under the BSD style license found at http://polymer.g ithub.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/CONTRI BUTORS.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/PATEN TS.txt
8 -->
9
10 <!--
11 @group Polymer Core Elements
12
13 `<core-selector>` is used to manage a list of elements that can be selected.
14
15 The attribute `selected` indicates which item element is being selected.
16 The attribute `multi` indicates if multiple items can be selected at once.
17 Tapping on the item element would fire `core-activate` event. Use
18 `core-select` event to listen for selection changes.
19
20 Example:
21
22 <core-selector selected="0">
23 <div>Item 1</div>
24 <div>Item 2</div>
25 <div>Item 3</div>
26 </core-selector>
27
28 `<core-selector>` is not styled. Use the `core-selected` CSS class to style the selected element.
29
30 <style>
31 .item.core-selected {
32 background: #eee;
33 }
34 </style>
35 ...
36 <core-selector>
37 <div class="item">Item 1</div>
38 <div class="item">Item 2</div>
39 <div class="item">Item 3</div>
40 </core-selector>
41
42 @element core-selector
43 @status stable
44 @homepage github.io
45 -->
46
47 <!--
48 Fired when an item's selection state is changed. This event is fired both
49 when an item is selected or deselected. The `isSelected` detail property
50 contains the selection state.
51
52 @event core-select
53 @param {Object} detail
54 @param {boolean} detail.isSelected true for selection and false for deselectio n
55 @param {Object} detail.item the item element
56 -->
57 <!--
58 Fired when an item element is tapped.
59
60 @event core-activate
61 @param {Object} detail
62 @param {Object} detail.item the item element
63 -->
64
65 <link rel="import" href="../polymer/polymer.html">
66 <link rel="import" href="../core-selection/core-selection.html">
67
68 <polymer-element name="core-selector"
69 attributes="selected multi valueattr selectedClass selectedProperty selected Attribute selectedItem selectedModel selectedIndex notap excludedLocalNames targ et itemsSelector activateEvent">
70
71 <template>
72 <core-selection id="selection" multi="{{multi}}" on-core-select="{{selection Select}}"></core-selection>
73 <content id="items" select="*"></content>
74 </template>
75
76 <script>
77
78 Polymer('core-selector', {
79
80 /**
81 * Gets or sets the selected element. Default to use the index
82 * of the item element.
83 *
84 * If you want a specific attribute value of the element to be
85 * used instead of index, set "valueattr" to that attribute name.
86 *
87 * Example:
88 *
89 * <core-selector valueattr="label" selected="foo">
90 * <div label="foo"></div>
91 * <div label="bar"></div>
92 * <div label="zot"></div>
93 * </core-selector>
94 *
95 * In multi-selection this should be an array of values.
96 *
97 * Example:
98 *
99 * <core-selector id="selector" valueattr="label" multi>
100 * <div label="foo"></div>
101 * <div label="bar"></div>
102 * <div label="zot"></div>
103 * </core-selector>
104 *
105 * this.$.selector.selected = ['foo', 'zot'];
106 *
107 * @attribute selected
108 * @type Object
109 * @default null
110 */
111 selected: null,
112
113 /**
114 * If true, multiple selections are allowed.
115 *
116 * @attribute multi
117 * @type boolean
118 * @default false
119 */
120 multi: false,
121
122 /**
123 * Specifies the attribute to be used for "selected" attribute.
124 *
125 * @attribute valueattr
126 * @type string
127 * @default 'name'
128 */
129 valueattr: 'name',
130
131 /**
132 * Specifies the CSS class to be used to add to the selected element.
133 *
134 * @attribute selectedClass
135 * @type string
136 * @default 'core-selected'
137 */
138 selectedClass: 'core-selected',
139
140 /**
141 * Specifies the property to be used to set on the selected element
142 * to indicate its active state.
143 *
144 * @attribute selectedProperty
145 * @type string
146 * @default ''
147 */
148 selectedProperty: '',
149
150 /**
151 * Specifies the attribute to set on the selected element to indicate
152 * its active state.
153 *
154 * @attribute selectedAttribute
155 * @type string
156 * @default 'active'
157 */
158 selectedAttribute: 'active',
159
160 /**
161 * Returns the currently selected element. In multi-selection this returns
162 * an array of selected elements.
163 * Note that you should not use this to set the selection. Instead use
164 * `selected`.
165 *
166 * @attribute selectedItem
167 * @type Object
168 * @default null
169 */
170 selectedItem: null,
171
172 /**
173 * In single selection, this returns the model associated with the
174 * selected element.
175 * Note that you should not use this to set the selection. Instead use
176 * `selected`.
177 *
178 * @attribute selectedModel
179 * @type Object
180 * @default null
181 */
182 selectedModel: null,
183
184 /**
185 * In single selection, this returns the selected index.
186 * Note that you should not use this to set the selection. Instead use
187 * `selected`.
188 *
189 * @attribute selectedIndex
190 * @type number
191 * @default -1
192 */
193 selectedIndex: -1,
194
195 /**
196 * Nodes with local name that are in the list will not be included
197 * in the selection items. In the following example, `items` returns four
198 * `core-item`'s and doesn't include `h3` and `hr`.
199 *
200 * <core-selector excludedLocalNames="h3 hr">
201 * <h3>Header</h3>
202 * <core-item>Item1</core-item>
203 * <core-item>Item2</core-item>
204 * <hr>
205 * <core-item>Item3</core-item>
206 * <core-item>Item4</core-item>
207 * </core-selector>
208 *
209 * @attribute excludedLocalNames
210 * @type string
211 * @default ''
212 */
213 excludedLocalNames: '',
214
215 /**
216 * The target element that contains items. If this is not set
217 * core-selector is the container.
218 *
219 * @attribute target
220 * @type Object
221 * @default null
222 */
223 target: null,
224
225 /**
226 * This can be used to query nodes from the target node to be used for
227 * selection items. Note this only works if `target` is set
228 * and is not `core-selector` itself.
229 *
230 * Example:
231 *
232 * <core-selector target="{{$.myForm}}" itemsSelector="input[type=radi o]"></core-selector>
233 * <form id="myForm">
234 * <label><input type="radio" name="color" value="red"> Red</label> <br>
235 * <label><input type="radio" name="color" value="green"> Green</lab el> <br>
236 * <label><input type="radio" name="color" value="blue"> Blue</label > <br>
237 * <p>color = {{color}}</p>
238 * </form>
239 *
240 * @attribute itemsSelector
241 * @type string
242 * @default ''
243 */
244 itemsSelector: '',
245
246 /**
247 * The event that would be fired from the item element to indicate
248 * it is being selected.
249 *
250 * @attribute activateEvent
251 * @type string
252 * @default 'tap'
253 */
254 activateEvent: 'tap',
255
256 /**
257 * Set this to true to disallow changing the selection via the
258 * `activateEvent`.
259 *
260 * @attribute notap
261 * @type boolean
262 * @default false
263 */
264 notap: false,
265
266 defaultExcludedLocalNames: 'template',
267
268 ready: function() {
269 this.activateListener = this.activateHandler.bind(this);
270 this.itemFilter = this.filterItem.bind(this);
271 this.excludedLocalNamesChanged();
272 this.observer = new MutationObserver(this.updateSelected.bind(this));
273 if (!this.target) {
274 this.target = this;
275 }
276 },
277
278 /**
279 * Returns an array of all items.
280 *
281 * @property items
282 */
283 get items() {
284 if (!this.target) {
285 return [];
286 }
287 var nodes = this.target !== this ? (this.itemsSelector ?
288 this.target.querySelectorAll(this.itemsSelector) :
289 this.target.children) : this.$.items.getDistributedNodes();
290 return Array.prototype.filter.call(nodes, this.itemFilter);
291 },
292
293 filterItem: function(node) {
294 return !this._excludedNames[node.localName];
295 },
296
297 excludedLocalNamesChanged: function() {
298 this._excludedNames = {};
299 var s = this.defaultExcludedLocalNames;
300 if (this.excludedLocalNames) {
301 s += ' ' + this.excludedLocalNames;
302 }
303 s.split(/\s+/g).forEach(function(n) {
304 this._excludedNames[n] = 1;
305 }, this);
306 },
307
308 targetChanged: function(old) {
309 if (old) {
310 this.removeListener(old);
311 this.observer.disconnect();
312 this.clearSelection();
313 }
314 if (this.target) {
315 this.addListener(this.target);
316 this.observer.observe(this.target, {childList: true});
317 this.updateSelected();
318 }
319 },
320
321 addListener: function(node) {
322 Polymer.addEventListener(node, this.activateEvent, this.activateListener );
323 },
324
325 removeListener: function(node) {
326 Polymer.removeEventListener(node, this.activateEvent, this.activateListe ner);
327 },
328
329 /**
330 * Returns the selected item(s). If the `multi` property is true,
331 * this will return an array, otherwise it will return
332 * the selected item or undefined if there is no selection.
333 */
334 get selection() {
335 return this.$.selection.getSelection();
336 },
337
338 selectedChanged: function() {
339 this.updateSelected();
340 },
341
342 updateSelected: function() {
343 this.validateSelected();
344 if (this.multi) {
345 this.clearSelection();
346 this.selected && this.selected.forEach(function(s) {
347 this.valueToSelection(s);
348 }, this);
349 } else {
350 this.valueToSelection(this.selected);
351 }
352 },
353
354 validateSelected: function() {
355 // convert to an array for multi-selection
356 if (this.multi && !Array.isArray(this.selected) &&
357 this.selected !== null && this.selected !== undefined) {
358 this.selected = [this.selected];
359 }
360 },
361
362 clearSelection: function() {
363 if (this.multi) {
364 this.selection.slice().forEach(function(s) {
365 this.$.selection.setItemSelected(s, false);
366 }, this);
367 } else {
368 this.$.selection.setItemSelected(this.selection, false);
369 }
370 this.selectedItem = null;
371 this.$.selection.clear();
372 },
373
374 valueToSelection: function(value) {
375 var item = (value === null || value === undefined) ?
376 null : this.items[this.valueToIndex(value)];
377 this.$.selection.select(item);
378 },
379
380 updateSelectedItem: function() {
381 this.selectedItem = this.selection;
382 },
383
384 selectedItemChanged: function() {
385 if (this.selectedItem) {
386 var t = this.selectedItem.templateInstance;
387 this.selectedModel = t ? t.model : undefined;
388 } else {
389 this.selectedModel = null;
390 }
391 this.selectedIndex = this.selectedItem ?
392 parseInt(this.valueToIndex(this.selected)) : -1;
393 },
394
395 valueToIndex: function(value) {
396 // find an item with value == value and return it's index
397 for (var i=0, items=this.items, c; (c=items[i]); i++) {
398 if (this.valueForNode(c) == value) {
399 return i;
400 }
401 }
402 // if no item found, the value itself is probably the index
403 return value;
404 },
405
406 valueForNode: function(node) {
407 return node[this.valueattr] || node.getAttribute(this.valueattr);
408 },
409
410 // events fired from <core-selection> object
411 selectionSelect: function(e, detail) {
412 this.updateSelectedItem();
413 if (detail.item) {
414 this.applySelection(detail.item, detail.isSelected);
415 }
416 },
417
418 applySelection: function(item, isSelected) {
419 if (this.selectedClass) {
420 item.classList.toggle(this.selectedClass, isSelected);
421 }
422 if (this.selectedProperty) {
423 item[this.selectedProperty] = isSelected;
424 }
425 if (this.selectedAttribute && item.setAttribute) {
426 if (isSelected) {
427 item.setAttribute(this.selectedAttribute, '');
428 } else {
429 item.removeAttribute(this.selectedAttribute);
430 }
431 }
432 },
433
434 // event fired from host
435 activateHandler: function(e) {
436 if (!this.notap) {
437 var i = this.findDistributedTarget(e.target, this.items);
438 if (i >= 0) {
439 var item = this.items[i];
440 var s = this.valueForNode(item) || i;
441 if (this.multi) {
442 if (this.selected) {
443 this.addRemoveSelected(s);
444 } else {
445 this.selected = [s];
446 }
447 } else {
448 this.selected = s;
449 }
450 this.asyncFire('core-activate', {item: item});
451 }
452 }
453 },
454
455 addRemoveSelected: function(value) {
456 var i = this.selected.indexOf(value);
457 if (i >= 0) {
458 this.selected.splice(i, 1);
459 } else {
460 this.selected.push(value);
461 }
462 this.valueToSelection(value);
463 },
464
465 findDistributedTarget: function(target, nodes) {
466 // find first ancestor of target (including itself) that
467 // is in nodes, if any
468 while (target && target != this) {
469 var i = Array.prototype.indexOf.call(nodes, target);
470 if (i >= 0) {
471 return i;
472 }
473 target = target.parentNode;
474 }
475 },
476
477 selectIndex: function(index) {
478 var item = this.items[index];
479 if (item) {
480 this.selected = this.valueForNode(item) || index;
481 return item;
482 }
483 },
484
485 /**
486 * Selects the previous item. This should be used in single selection onl y.
487 *
488 * @method selectPrevious
489 * @param {boolean} wrap if true and it is already at the first item, wrap to the end
490 * @returns the previous item or undefined if there is none
491 */
492 selectPrevious: function(wrap) {
493 var i = wrap && !this.selectedIndex ? this.items.length - 1 : this.selec tedIndex - 1;
494 return this.selectIndex(i);
495 },
496
497 /**
498 * Selects the next item. This should be used in single selection only.
499 *
500 * @method selectNext
501 * @param {boolean} wrap if true and it is already at the last item, wrap to the front
502 * @returns the next item or undefined if there is none
503 */
504 selectNext: function(wrap) {
505 var i = wrap && this.selectedIndex >= this.items.length - 1 ? 0 : this.s electedIndex + 1;
506 return this.selectIndex(i);
507 }
508
509 });
510 </script>
511 </polymer-element>
OLDNEW
« no previous file with comments | « bower_components/core-selector/bower.json ('k') | bower_components/core-selector/demo.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698