3 Copyright (c) 2014 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
7 <link rel="import" href="/base/events.html">
8 <link rel="import" href="/base/utils.html">
9 <link rel="import" href="/base/ui.html">
10 <link rel="import" href="/base/ui/container_that_decorates_its_children.html">
11 <link rel="stylesheet" href="/base/ui/list_view.css">
16 * @fileoverview Simple list view.
18 tv.exportTo('tv.ui', function() {
22 var ListView = tv.ui.define(
23 'x-list-view', tv.ui.ContainerThatDecoratesItsChildren);
25 ListView.prototype = {
26 __proto__: tv.ui.ContainerThatDecoratesItsChildren.prototype,
28 decorate: function() {
29 tv.ui.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);
31 this.classList.add('x-list-view');
32 this.onItemClicked_ = this.onItemClicked_.bind(this);
33 this.onKeyDown_ = this.onKeyDown_.bind(this);
35 this.addEventListener('keydown', this.onKeyDown_);
37 this.selectionChanged_ = false;
40 decorateChild_: function(item) {
41 item.classList.add('list-item');
42 item.addEventListener('click', this.onItemClicked_, true);
45 Object.defineProperty(
49 set: function(value) {
50 var oldSelection = listView.selectedElement;
51 if (oldSelection && oldSelection != this && value)
52 listView.selectedElement.removeAttribute('selected');
54 this.setAttribute('selected', 'selected');
56 this.removeAttribute('selected');
57 var newSelection = listView.selectedElement;
58 if (newSelection != oldSelection)
59 tv.dispatchSimpleEvent(listView, 'selection-changed', false);
62 return this.hasAttribute('selected');
67 undecorateChild_: function(item) {
68 this.selectionChanged_ |= item.selected;
70 item.classList.remove('list-item');
71 item.removeEventListener('click', this.onItemClicked_);
75 beginDecorating_: function() {
76 this.selectionChanged_ = false;
79 doneDecoratingForNow_: function() {
80 if (this.selectionChanged_)
81 tv.dispatchSimpleEvent(this, 'selection-changed', false);
84 get selectedElement() {
85 var el = this.querySelector('.list-item[selected]');
91 set selectedElement(el) {
93 if (this.selectedElement)
94 this.selectedElement.selected = false;
98 if (el.parentElement != this)
100 'Can only select elements that are children of this list view');
104 getElementByIndex: function(index) {
105 return this.querySelector('.list-item:nth-child(' + index + ')');
109 var changed = this.selectedElement !== undefined;
110 tv.ui.ContainerThatDecoratesItsChildren.prototype.clear.call(this);
112 tv.dispatchSimpleEvent(this, 'selection-changed', false);
115 onItemClicked_: function(e) {
116 var currentSelectedElement = this.selectedElement;
117 if (currentSelectedElement)
118 currentSelectedElement.removeAttribute('selected');
119 var element = e.target;
120 while (element.parentElement != this)
121 element = element.parentElement;
122 element.setAttribute('selected', 'selected');
123 tv.dispatchSimpleEvent(this, 'selection-changed', false);
126 onKeyDown_: function(e) {
127 if (this.selectedElement === undefined)
130 if (e.keyCode == 38) { // Up arrow.
131 var prev = this.selectedElement.previousSibling;
133 prev.selected = true;
134 tv.scrollIntoViewIfNeeded(prev);
138 } else if (e.keyCode == 40) { // Down arrow.
139 var next = this.selectedElement.nextSibling;
141 next.selected = true;
142 tv.scrollIntoViewIfNeeded(next);
149 addItem: function(textContent) {
150 var item = document.createElement('div');
151 item.textContent = textContent;
152 this.appendChild(item);