blob: f6b0a51076a95a662433616f921749eedd5586c0 [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 2014 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.
-->
<link rel="stylesheet" href="/tracing/ui/base/list_view.css">
<link rel="import" href="/tracing/base/event.html">
<link rel="import" href="/tracing/ui/base/container_that_decorates_its_children.html">
<link rel="import" href="/tracing/ui/base/ui.html">
<link rel="import" href="/tracing/ui/base/utils.html">
<script>
'use strict';
/**
* @fileoverview Simple list view.
*/
tr.exportTo('tr.ui.b', function() {
/**
* @constructor
*/
var ListView = tr.ui.b.define(
'x-list-view', tr.ui.b.ContainerThatDecoratesItsChildren);
ListView.prototype = {
__proto__: tr.ui.b.ContainerThatDecoratesItsChildren.prototype,
decorate: function() {
tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);
Polymer.dom(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) {
Polymer.dom(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)
Polymer.dom(listView.selectedElement).removeAttribute(
'selected');
if (value)
Polymer.dom(this).setAttribute('selected', 'selected');
else
Polymer.dom(this).removeAttribute('selected');
var newSelection = listView.selectedElement;
if (newSelection != oldSelection)
tr.b.dispatchSimpleEvent(listView, 'selection-changed', false);
},
get: function() {
return this.hasAttribute('selected');
}
});
},
undecorateChild_: function(item) {
this.selectionChanged_ |= item.selected;
Polymer.dom(item).classList.remove('list-item');
item.removeEventListener('click', this.onItemClicked_);
delete item.selected;
},
beginDecorating_: function() {
this.selectionChanged_ = false;
},
doneDecoratingForNow_: function() {
if (this.selectionChanged_)
tr.b.dispatchSimpleEvent(this, 'selection-changed', false);
},
get selectedElement() {
var el = Polymer.dom(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;
},
getElementByIndex: function(index) {
return Polymer.dom(this)
.querySelector('.list-item:nth-child(' + index + ')');
},
clear: function() {
var changed = this.selectedElement !== undefined;
tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);
if (changed)
tr.b.dispatchSimpleEvent(this, 'selection-changed', false);
},
onItemClicked_: function(e) {
var currentSelectedElement = this.selectedElement;
if (currentSelectedElement)
Polymer.dom(currentSelectedElement).removeAttribute('selected');
var element = e.target;
while (element.parentElement != this)
element = element.parentElement;
if (element !== currentSelectedElement)
Polymer.dom(element).setAttribute('selected', 'selected');
tr.b.dispatchSimpleEvent(this, 'selection-changed', false);
},
onKeyDown_: function(e) {
if (this.selectedElement === undefined)
return;
if (e.keyCode == 38) { // Up arrow.
var prev = Polymer.dom(this.selectedElement).previousSibling;
if (prev) {
prev.selected = true;
tr.ui.b.scrollIntoViewIfNeeded(prev);
e.preventDefault();
return true;
}
} else if (e.keyCode == 40) { // Down arrow.
var next = Polymer.dom(this.selectedElement).nextSibling;
if (next) {
next.selected = true;
tr.ui.b.scrollIntoViewIfNeeded(next);
e.preventDefault();
return true;
}
}
},
addItem: function(textContent) {
var item = document.createElement('div');
Polymer.dom(item).textContent = textContent;
Polymer.dom(this).appendChild(item);
return item;
}
};
return {
ListView: ListView
};
});
</script>