Re-enable index-basics-workers test to see if still times
[chromium-blink-merge.git] / tools / cc-frame-viewer / src / ui / list_view.js
blobc4efc0480374d0ab8c0873db7fd155b21cc61caf
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 'use strict';
6 /**
7  * @fileoverview Simple list view.
8  */
9 base.require('ui');
10 base.requireStylesheet('ui.list_view');
11 base.exportTo('ui', function() {
13   /**
14    * @constructor
15    */
16   var ListView = ui.define('x-list-view');
18   ListView.prototype = {
19     __proto__: HTMLUnknownElement.prototype,
21     decorate: function() {
22       this.onItemClicked_ = this.onItemClicked_.bind(this);
23       this.onKeyDown_ = this.onKeyDown_.bind(this);
24       this.observer_ = new WebKitMutationObserver(this.didMutate_.bind(this));
25       this.observer_.observe(this, { childList: true });
26       this.tabIndex = 0;
27       this.addEventListener('keydown', this.onKeyDown_);
28     },
30     appendChild: function(x) {
31       HTMLUnknownElement.prototype.appendChild.call(this, x);
32       this.didMutate_(this.observer_.takeRecords());
33     },
35     insertBefore: function(x, y) {
36       HTMLUnknownElement.prototype.insertBefore.call(this, x, y);
37       this.didMutate_(this.observer_.takeRecords());
38     },
40     removeChild: function(x) {
41       HTMLUnknownElement.prototype.removeChild.call(this, x);
42       this.didMutate_(this.observer_.takeRecords());
43     },
45     replaceChild: function(x, y) {
46       HTMLUnknownElement.prototype.replaceChild.call(this, x, y);
47       this.didMutate_(this.observer_.takeRecords());
48     },
50     didMutate_: function(records) {
51       var selectionChanged = false;
52       for (var i = 0; i < records.length; i++) {
53         var addedNodes = records[i].addedNodes;
54         if (addedNodes) {
55           for (var j = 0; j < addedNodes.length; j++)
56             this.decorateItem_(addedNodes[j]);
57         }
58         var removedNodes = records[i].removedNodes;
59         if (removedNodes) {
60           for (var j = 0; j < removedNodes.length; j++) {
61             selectionChanged |= removedNodes[j].selected;
62             this.undecorateItem_(removedNodes[j]);
63           }
64         }
65       }
66       if (selectionChanged)
67         base.dispatchSimpleEvent(this, 'selection-changed', false);
68     },
70     decorateItem_: function(item) {
71       item.classList.add('list-item');
72       item.addEventListener('click', this.onItemClicked_);
74       var listView = this;
75       Object.defineProperty(
76         item,
77         "selected", {
78           configurable: true,
79           set: function(value) {
80             var oldSelection = listView.selectedElement;
81             if (oldSelection && oldSelection != this && value)
82               listView.selectedElement.removeAttribute('selected');
83             if (value)
84               this.setAttribute('selected', 'selected');
85             else
86               this.removeAttribute('selected');
87             var newSelection = listView.selectedElement;
88             if (newSelection != oldSelection)
89               base.dispatchSimpleEvent(listView, 'selection-changed', false);
90           },
91           get: function() {
92             return this.hasAttribute('selected');
93           }
94         });
95     },
97     undecorateItem_: function(item) {
98       item.classList.remove('list-item');
99       item.removeEventListener('click', this.onItemClicked_);
100       delete item.selected;
101     },
103     get selectedElement() {
104       var el = this.querySelector('.list-item[selected]');
105       if (!el)
106         return undefined;
107       return el;
108     },
110     set selectedElement(el) {
111       if (!el) {
112         if (this.selectedElement)
113           this.selectedElement.selected = false;
114         return;
115       }
117       if (el.parentElement != this)
118         throw new Error(
119             'Can only select elements that are children of this list view');
120       el.selected = true;
121     },
123     clear: function() {
124       var changed = this.selectedElement !== undefined;
125       this.textContent = '';
126       if (changed)
127         base.dispatchSimpleEvent(this, 'selection-changed', false);
128     },
130     onItemClicked_: function(e) {
131       var currentSelectedElement = this.selectedElement;
132       if (currentSelectedElement)
133         currentSelectedElement.removeAttribute('selected');
134       e.target.setAttribute('selected', 'selected');
135       base.dispatchSimpleEvent(this, 'selection-changed', false);
136     },
138     onKeyDown_: function(e) {
139       if (e.keyCode == 38) { // Up arrow.
140         var prev = this.selectedElement.previousSibling;
141         if (prev) {
142           prev.selected = true;
143           prev.scrollIntoView(false);
144           e.preventDefault();
145           return true;
146         }
147       } else if(e.keyCode == 40) { // Down arrow.
148         var next = this.selectedElement.nextSibling;
149         if (next) {
150           next.selected = true;
151           next.scrollIntoView(false);
152           e.preventDefault();
153           return true;
154         }
155       }
156     },
158     addItem: function(textContent) {
159       var item = document.createElement('div');
160       item.textContent = textContent;
161       this.appendChild(item);
162       return item;
163     },
165   };
167   return {
168     ListView: ListView
169   };