resources/perf.webkit.org/public/v3/components/pane-selector.js (195 lines of code) (raw):

class PaneSelector extends ComponentBase { constructor() { super('pane-selector'); this._currentPlatform = null; this._currentPath = []; this._platformItems = []; this._renderedMetric = null; this._renderedPath = null; this._updateTimer = null; this._platformContainer = this.content().querySelector('#platform'); this._testsContainer = this.content().querySelector('#tests'); this._callback = null; this._previouslySelectedItem = null; } render() { this._renderPlatformList(); this._renderTestLists(); } focus() { var select = this.content().querySelector('select'); if (select) { if (select.selectedIndex < 0) select.selectedIndex = 0; select.focus(); } } _renderPlatformList() { var currentMetric = null; if (this._currentPath.length) { var lastItem = this._currentPath[this._currentPath.length - 1]; if (lastItem instanceof Metric) currentMetric = lastItem; } if (this._renderedMetric != currentMetric) { if (this._platformContainer.firstChild) this._platformContainer.removeChild(this._platformContainer.firstChild); this._renderedMetric = currentMetric; this._platformItems = []; if (currentMetric) { for (var platform of Platform.sortByName(Platform.all())) { if (platform.isHidden()) continue; if (platform.hasMetric(currentMetric)) this._platformItems.push(this._createListItem(platform, platform.label())); } this._platformContainer.appendChild(this._buildList(this._platformItems)); } } for (var li of this._platformItems) { if (li.data == this._currentPlatform) li.selected = true; } } _renderTestLists() { if (this._renderedPath == null) this._replaceList(0, this._buildTestList(Test.topLevelTests()), []); for (var i = 0; i < this._currentPath.length; i++) { var item = this._currentPath[i]; if (this._renderedPath[i] == item) continue; if (item instanceof Metric) break; var newList = this._buildTestList(Test.sortByName(item.childTests()), Metric.sortByName(item.metrics())); this._replaceList(i + 1, newList); } var removeNodeCount = this._testsContainer.childNodes.length - i - 1; if (removeNodeCount > 0) { while (removeNodeCount--) this._testsContainer.removeChild(this._testsContainer.lastChild); } for (var i = 0; i < this._currentPath.length; i++) { var list = this._testsContainer.childNodes[i]; var item = this._currentPath[i]; for (var j = 0; j < list.childNodes.length; j++) { var option = list.childNodes[j]; if (option.data == item) option.selected = true; } } this._renderedPath = this._currentPath; } _buildTestList(tests, metrics) { var self = this; var platform = this._currentPlatform; var metricItems = (metrics || []) .map(function (metric) { return self._createListItem(metric, metric.label()); }); var testItems = tests .filter(test => !test.isHidden()) .map(function (test) { var data = test; var label = test.label(); if (test.onlyContainsSingleMetric()) { data = test.metrics()[0]; label = test.label() + ' (' + data.label() + ')'; } return self._createListItem(data, label); }); return this._buildList([metricItems, testItems]); } _replaceList(position, newList) { var existingList = this._testsContainer.childNodes[position]; if (existingList) this._testsContainer.replaceChild(newList, existingList); else this._testsContainer.appendChild(newList); } _createListItem(data, label, hoverCallback, activationCallback) { var element = ComponentBase.createElement; var item = element('option', { // Can't use mouseenter because of webkit.org/b/152149. onmousemove: this._selectedItem.bind(this, data), onclick: this._clickedItem.bind(this, data), }, label); item.data = data; return item; } _buildList(items, onchange) { var self = this; return ComponentBase.createElement('select', { size: 10, onmousemove: function (event) { }, onchange: function () { if (this.selectedIndex >= 0) self._selectedItem(this.options[this.selectedIndex].data); } }, items); } _selectedItem(data) { if (data == this._previouslySelectedItem) return; this._previouslySelectedItem = data; if (data instanceof Platform) this._currentPlatform = data; else { this._currentPath = data.path(); if (data instanceof Metric && data.test().onlyContainsSingleMetric()) this._currentPath.splice(this._currentPath.length - 2, 1); } this.enqueueToRender(); } setCallback(callback) { this._callback = callback; } _clickedItem(data, event) { if (!(data instanceof Platform) || !this._callback || !this._currentPlatform || !this._currentPath.length) return; event.preventDefault(); this._callback(this._currentPlatform, this._currentPath[this._currentPath.length - 1]); } static htmlTemplate() { return ` <div class="pane-selector-container"><div id="tests"></div><div id="platform"></div></div> `; } static cssTemplate() { return ` .pane-selector-container, .pane-selector-container > div { display: flex; flex-direction: row-reverse; height: 10rem; font-size: 0.9rem; white-space: nowrap; } .pane-selector-container select { height: 100%; border: solid 1px red; font-size: 0.9rem; border: solid 1px #ccc; border-radius: 0.2rem; margin-right: 0.2rem; background: transparent; max-width: 20rem; } .pane-selector-container li.selected a { background: rgba(204, 153, 51, 0.1); } `; } } ComponentBase.defineElement('pane-selector', PaneSelector);