[tools] Add V8CustomElement.update method

Drive-by-fix:
- Remove duplicated LazyTable
- Introduce more pseudo private _* fields
- Remove MapPanel.mapDetails getter
- Rename MapDetails.setSelectedMap to .map

Bug: v8:10644
Change-Id: I0f976ab86f24de2677e024e386e7d4169c9abbb3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2523192
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Sathya Gunasekaran  <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71093}
This commit is contained in:
Camillo Bruni 2020-11-10 14:21:40 +01:00 committed by Commit Bot
parent 7555761b9b
commit 6c69379497
9 changed files with 67 additions and 83 deletions

View File

@ -177,11 +177,15 @@ function $(id) {
}
class V8CustomElement extends HTMLElement {
_updateTimeoutId;
_updateCallback = this._update.bind(this);
constructor(templateText) {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = templateText;
}
$(id) {
return this.shadowRoot.querySelector(id);
}
@ -189,30 +193,16 @@ class V8CustomElement extends HTMLElement {
querySelectorAll(query) {
return this.shadowRoot.querySelectorAll(query);
}
}
class LazyTable {
constructor(table, rowData, rowElementCreator) {
this._table = table;
this._rowData = rowData;
this._rowElementCreator = rowElementCreator;
const tbody = table.querySelector('tbody');
table.replaceChild(document.createElement('tbody'), tbody);
table.querySelector('tfoot td').onclick = (e) => this._addMoreRows();
this._addMoreRows();
update() {
// Use timeout tasks to asynchronously update the UI without blocking.
clearTimeout(this._updateTimeoutId);
const kDelayMs = 5;
this._updateTimeoutId = setTimeout(this._updateCallback, kDelayMs);
}
_nextRowDataSlice() {
return this._rowData.splice(0, 100);
}
_addMoreRows() {
const fragment = new DocumentFragment();
for (let row of this._nextRowDataSlice()) {
const tr = this._rowElementCreator(row);
fragment.appendChild(tr);
}
this._table.querySelector('tbody').appendChild(fragment);
_update() {
throw Error('Subclass responsibility');
}
}

View File

@ -21,7 +21,7 @@ DOM.defineCustomElement(
console.assert(value !== undefined, 'timeline undefined!');
this._timeline = value;
this.selectedLogEntries = this._timeline.all;
this.updateCount();
this.update();
}
get groupKey() {
return this.$('#group-key');
@ -48,22 +48,21 @@ DOM.defineCustomElement(
this.update();
}
async update() {
await delay(1);
this.updateCount();
this.updateTable();
_update() {
this._updateCount();
this._updateTable();
}
updateCount() {
_updateCount() {
this.count.innerHTML = `length=${this._selectedLogEntries.length}`;
}
updateTable(event) {
_updateTable(event) {
let select = this.groupKey;
let key = select.options[select.selectedIndex].text;
DOM.removeAllChildren(this.tableBody);
let groups = Group.groupBy(this._selectedLogEntries, key, true);
this.render(groups, this.tableBody);
this._render(groups, this.tableBody);
}
escapeHtml(unsafe) {
@ -102,7 +101,7 @@ DOM.defineCustomElement(
this.dispatchEvent(new FocusEvent(sourcePosition));
}
render(groups, parent) {
_render(groups, parent) {
const fragment = document.createDocumentFragment();
const max = Math.min(1000, groups.length)
const detailsClickHandler = this.handleDetailsClick.bind(this);
@ -176,7 +175,7 @@ DOM.defineCustomElement(
`Grouped by ${key} [top ${max} out of ${children.length}]`;
td.appendChild(div);
const table = DOM.table();
this.render(children.slice(0, max), table, false)
this._render(children.slice(0, max), table, false)
td.appendChild(table);
}

View File

@ -17,11 +17,11 @@ DOM.defineCustomElement('log-file-reader',
}
set error(message) {
this.updateLabel(message);
this._updateLabel(message);
this.root.className = 'fail';
}
updateLabel(text) {
_updateLabel(text) {
this.$('#label').innerText = text;
}
@ -73,7 +73,7 @@ DOM.defineCustomElement('log-file-reader',
handleFileLoad(e, file) {
const chunk = e.target.result;
this.updateLabel(`Finished loading '${file.name}'.`);
this._updateLabel(`Finished loading '${file.name}'.`);
this.dispatchEvent(new CustomEvent('fileuploadend', {
bubbles: true,
composed: true,

View File

@ -21,7 +21,7 @@ DOM.defineCustomElement('map-panel',
handleUpdateMapDetails(e) {
if (e.entry instanceof MapLogEntry) {
this.mapDetailsPanel.mapDetails = e.entry;
this.mapDetailsPanel.map = e.entry;
}
}
@ -41,10 +41,6 @@ DOM.defineCustomElement('map-panel',
return this.$('#searchBar');
}
get mapDetails() {
return this.mapDetailsPanel.mapDetails;
}
set timeline(timeline) {
this._timeline = timeline;
}

View File

@ -7,13 +7,14 @@ import {DOM, V8CustomElement} from '../helper.mjs';
DOM.defineCustomElement(
'./map-panel/map-details',
(templateText) => class MapDetails extends V8CustomElement {
_map;
constructor() {
super(templateText);
this._filePositionNode.addEventListener(
'click', e => this.handleFilePositionClick(e));
this.selectedMap = undefined;
this._filePositionNode.onclick = e => this._handleFilePositionClick(e);
}
get mapDetails() {
get _mapDetails() {
return this.$('#mapDetails');
}
@ -21,25 +22,26 @@ DOM.defineCustomElement(
return this.$('#filePositionNode');
}
setSelectedMap(value) {
this.selectedMap = value;
set map(map) {
if (this._map === map) return;
this._map = map;
this.update();
}
set mapDetails(map) {
_update() {
let details = '';
let clickableDetails = '';
if (map) {
clickableDetails += `ID: ${map.id}`;
clickableDetails += `\nSource location: ${map.filePosition}`;
details += `\n${map.description}`;
this.setSelectedMap(map);
if (this._map) {
clickableDetails = `ID: ${this._map.id}`;
clickableDetails += `\nSource location: ${this._map.filePosition}`;
details = this._map.description;
}
this._filePositionNode.innerText = clickableDetails;
this._filePositionNode.classList.add('clickable');
this.mapDetails.innerText = details;
this._mapDetails.innerText = details;
}
handleFilePositionClick() {
this.dispatchEvent(new FocusEvent(this.selectedMap.sourcePosition));
_handleFilePositionClick(event) {
this.dispatchEvent(new FocusEvent(this._map.sourcePosition));
}
});

View File

@ -10,7 +10,7 @@ DOM.defineCustomElement('./map-panel/map-transitions',
_map;
_selectedMapLogEntries;
_displayedMapsInTree;
_showMapsUpdateId;
constructor() {
super(templateText);
this.transitionView.addEventListener(
@ -45,7 +45,7 @@ DOM.defineCustomElement('./map-panel/map-transitions',
}
}
selectMap(map) {
_selectMap(map) {
this.dispatchEvent(new SelectionEvent([map]));
}
@ -53,14 +53,10 @@ DOM.defineCustomElement('./map-panel/map-transitions',
if (this.currentMap === this._map) return;
this.currentMap = this._map;
this.selectedMapLogEntries = [this._map];
this.showMaps();
this.update();
}
showMaps() {
clearTimeout(this._showMapsUpdateId);
this._showMapsUpdateId = setTimeout(() => this._showMaps(), 250);
}
_showMaps() {
_update() {
this.transitionView.style.display = 'none';
DOM.removeAllChildren(this.transitionView);
this._displayedMapsInTree = new Set();
@ -73,7 +69,7 @@ DOM.defineCustomElement('./map-panel/map-transitions',
set selectedMapLogEntries(list) {
this._selectedMapLogEntries = list;
this.showMaps();
this.update();
}
get selectedMapLogEntries() {
@ -149,7 +145,7 @@ DOM.defineCustomElement('./map-panel/map-transitions',
let node = DOM.div('map');
if (map.edge) node.style.backgroundColor = typeToColor(map.edge);
node.map = map;
node.addEventListener('click', () => this.selectMap(map));
node.addEventListener('click', () => this._selectMap(map));
if (map.children.length > 1) {
node.innerText = map.children.length;
let showSubtree = DOM.div('showSubtransitions');

View File

@ -32,7 +32,7 @@ DOM.defineCustomElement(
this._transitions = value;
}
filterUniqueTransitions(filter) {
_filterUniqueTransitions(filter) {
// Returns a list of Maps whose parent is not in the list.
return this._selectedLogEntries.filter((map) => {
if (filter(map) === false) return false;
@ -42,13 +42,12 @@ DOM.defineCustomElement(
});
}
async update() {
await delay(1);
this.updateGeneralStats();
this.updateNamedTransitionsStats();
_update() {
this._updateGeneralStats();
this._updateNamedTransitionsStats();
}
updateGeneralStats() {
_updateGeneralStats() {
console.assert(this._timeline !== undefined, 'Timeline not set yet!');
let pairs = [
['Transitions', 'primary', (e) => e.edge && e.edge.isTransition()],
@ -89,12 +88,12 @@ DOM.defineCustomElement(
// lazily compute the stats
let node = e.target.parentNode;
if (node.maps == undefined) {
node.maps = this.filterUniqueTransitions(filter);
node.maps = this._filterUniqueTransitions(filter);
}
this.dispatchEvent(new SelectionEvent(node.maps));
};
row.appendChild(DOM.td(name));
let count = this.count(filter);
let count = this._count(filter);
row.appendChild(DOM.td(count));
let percent = Math.round((count / total) * 1000) / 10;
row.appendChild(DOM.td(percent.toFixed(1) + '%'));
@ -103,7 +102,7 @@ DOM.defineCustomElement(
this.$('#typeTable').replaceChild(tbody, this.$('#typeTable tbody'));
}
count(filter) {
_count(filter) {
let count = 0;
for (const map of this._selectedLogEntries) {
if (filter(map)) count++;
@ -111,7 +110,7 @@ DOM.defineCustomElement(
return count;
}
updateNamedTransitionsStats() {
_updateNamedTransitionsStats() {
let rowData = Array.from(this._transitions.entries());
rowData.sort((a, b) => b[1].length - a[1].length);
new LazyTable(this.$('#nameTable'), rowData, ([name, maps]) => {

View File

@ -50,7 +50,6 @@ DOM.defineCustomElement(
}
for (const track of this.timelineTracks) {
track.timeSelection = timeSelection;
;
}
}
});

View File

@ -167,9 +167,13 @@ DOM.defineCustomElement('./timeline/timeline-track',
set data(value) {
this._timeline = value;
this._resetTypeToColorCache();
this.updateChunks();
this.updateTimeline();
this.renderLegend();
this.update();
}
_update() {
this._updateChunks();
this._updateTimeline();
this._renderLegend();
}
_resetTypeToColorCache() {
@ -186,15 +190,14 @@ DOM.defineCustomElement('./timeline/timeline-track',
set nofChunks(count) {
this._nofChunks = count;
this.updateChunks();
this.updateTimeline();
this.update();
}
get nofChunks() {
return this._nofChunks;
}
updateChunks() {
_updateChunks() {
this._chunks = this.data.chunks(this.nofChunks);
}
@ -219,7 +222,7 @@ DOM.defineCustomElement('./timeline/timeline-track',
return this._typeToColor.get(type);
}
renderLegend() {
_renderLegend() {
let timelineLegendContent = this.timelineLegendContent;
DOM.removeAllChildren(timelineLegendContent);
this._timeline.uniqueTypes.forEach((entries, type) => {
@ -308,7 +311,7 @@ DOM.defineCustomElement('./timeline/timeline-track',
node.style.backgroundImage = `url(${imageData})`;
}
updateTimeline() {
_updateTimeline() {
let chunksNode = this.timelineChunks;
DOM.removeAllChildren(chunksNode);
let chunks = this.chunks;