// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
/**
* @fileoverview Simple list view.
*/
base.requireStylesheet('ui.list_view');
base.require('base.events');
base.require('ui');
base.require('ui.container_that_decorates_its_children');
base.exportTo('ui', function() {
/**
* @constructor
*/
var ListView = ui.define('x-list-view', ui.ContainerThatDecoratesItsChildren);
ListView.prototype = {
__proto__: ui.ContainerThatDecoratesItsChildren.prototype,
decorate: function() {
ui.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);
this.classList.add('x-list-view');
this.onItemClicked_ = this.onItemClicked_.bind(this);
this.onKeyDown_ = this.onKeyDown_.bind(this);
this.tabIndex = 0;
this.addEventListener('keydown', this.onKeyDown_);
this.selectionChanged_ = false;
},
decorateChild_: function(item) {
item.classList.add('list-item');
item.addEventListener('click', this.onItemClicked_, true);
var listView = this;
Object.defineProperty(
item,
'selected', {
configurable: true,
set: function(value) {
var oldSelection = listView.selectedElement;
if (oldSelection && oldSelection != this && value)
listView.selectedElement.removeAttribute('selected');
if (value)
this.setAttribute('selected', 'selected');
else
this.removeAttribute('selected');
var newSelection = listView.selectedElement;
if (newSelection != oldSelection)
base.dispatchSimpleEvent(listView, 'selection-changed', false);
},
get: function() {
return this.hasAttribute('selected');
}
});
},
undecorateChild_: function(item) {
this.selectionChanged_ |= item.selected;
item.classList.remove('list-item');
item.removeEventListener('click', this.onItemClicked_);
delete item.selected;
},
beginDecorating_: function() {
this.selectionChanged_ = false;
},
doneDecoratingForNow_: function() {
if (this.selectionChanged_)
base.dispatchSimpleEvent(this, 'selection-changed', false);
},
get selectedElement() {
var el = this.querySelector('.list-item[selected]');
if (!el)
return undefined;
return el;
},
set selectedElement(el) {
if (!el) {
if (this.selectedElement)
this.selectedElement.selected = false;
return;
}
if (el.parentElement != this)
throw new Error(
'Can only select elements that are children of this list view');
el.selected = true;
},
clear: function() {
var changed = this.selectedElement !== undefined;
ui.ContainerThatDecoratesItsChildren.prototype.clear.call(this);
if (changed)
base.dispatchSimpleEvent(this, 'selection-changed', false);
},
onItemClicked_: function(e) {
var currentSelectedElement = this.selectedElement;
if (currentSelectedElement)
currentSelectedElement.removeAttribute('selected');
var element = e.target;
while (element.parentElement != this)
element = element.parentElement;
element.setAttribute('selected', 'selected');
base.dispatchSimpleEvent(this, 'selection-changed', false);
},
onKeyDown_: function(e) {
if (e.keyCode == 38) { // Up arrow.
var prev = this.selectedElement.previousSibling;
if (prev) {
prev.selected = true;
prev.scrollIntoView(false);
e.preventDefault();
return true;
}
} else if (e.keyCode == 40) { // Down arrow.
var next = this.selectedElement.nextSibling;
if (next) {
next.selected = true;
next.scrollIntoView(false);
e.preventDefault();
return true;
}
}
},
addItem: function(textContent) {
var item = document.createElement('div');
item.textContent = textContent;
this.appendChild(item);
return item;
}
};
return {
ListView: ListView
};
});