v8/tools/system-analyzer/view/property-link-table.mjs
Camillo Bruni 1ca9a77095 [tools][system-analyzer] Add FeedbackVector support
Log FeedbackVectors for optimised code and show them in the code-panel.

Drive-by-fixes:
- Fix off-by-one in SourcePositionIteration, making sure we always show
  the last element
- Ensure we process all SourcePositions in SourcePositionIteration
- Fix first load error in script-panel
- Allow expanding all text with SHIFT-click

Bug: v8:10644
Change-Id: Ic40a36ea82f0dfa2386c3196f27ca6978cf23643
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3245931
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77567}
2021-10-27 09:40:41 +00:00

127 lines
4.1 KiB
JavaScript

// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {App} from '../index.mjs'
import {FocusEvent} from './events.mjs';
import {DOM, ExpandableText, V8CustomElement} from './helper.mjs';
DOM.defineCustomElement(
'view/property-link-table',
template => class PropertyLinkTable extends V8CustomElement {
_instance;
_propertyDict;
_instanceLinkButtons = false;
_logEntryClickHandler = this._handleLogEntryClick.bind(this);
_logEntryRelatedHandler = this._handleLogEntryRelated.bind(this);
_arrayValueSelectHandler = this._handleArrayValueSelect.bind(this);
constructor() {
super(template);
}
set instanceLinkButtons(newValue) {
this._instanceLinkButtons = newValue;
}
set propertyDict(propertyDict) {
if (this._propertyDict === propertyDict) return;
if (typeof propertyDict !== 'object') {
throw new Error(
`Invalid property dict, expected object: ${propertyDict}`);
}
this._propertyDict = propertyDict;
this.requestUpdate();
}
_update() {
this._fragment = new DocumentFragment();
this._table = DOM.table('properties');
for (let key in this._propertyDict) {
const value = this._propertyDict[key];
this._addKeyValue(key, value);
}
this._addFooter();
this._fragment.appendChild(this._table);
const newContent = DOM.div();
newContent.appendChild(this._fragment);
this.$('#content').replaceWith(newContent);
newContent.id = 'content';
this._fragment = undefined;
}
_addKeyValue(key, value) {
if (key == 'title') {
this._addTitle(value);
return;
}
if (key == '__this__') {
this._instance = value;
return;
}
const row = this._table.insertRow();
row.insertCell().innerText = key;
const cell = row.insertCell();
if (value == undefined) return;
if (Array.isArray(value)) {
cell.appendChild(this._addArrayValue(value));
return;
}
if (App.isClickable(value)) {
cell.className = 'clickable';
cell.onclick = this._logEntryClickHandler;
cell.data = value;
}
new ExpandableText(cell, value.toString());
}
_addArrayValue(array) {
if (array.length == 0) {
return DOM.text('empty');
} else if (array.length > 200) {
return DOM.text(`${array.length} items`);
}
const select = DOM.element('select');
select.onchange = this._arrayValueSelectHandler;
for (let value of array) {
const option = DOM.element('option');
option.innerText = value.toString();
option.data = value;
select.add(option);
}
return select;
}
_addTitle(value) {
const title = DOM.element('h3');
title.innerText = value;
this._fragment.appendChild(title);
}
_addFooter() {
if (this._instance === undefined) return;
if (!this._instanceLinkButtons) return;
const td = this._table.createTFoot().insertRow().insertCell();
td.colSpan = 2;
let showButton =
td.appendChild(DOM.button('Show', this._logEntryClickHandler));
showButton.data = this._instance;
let showRelatedButton = td.appendChild(
DOM.button('Show Related', this._logEntryRelatedClickHandler));
showRelatedButton.data = this._instance;
}
_handleArrayValueSelect(event) {
const logEntry = event.currentTarget.selectedOptions[0].data;
this.dispatchEvent(new FocusEvent(logEntry));
}
_handleLogEntryClick(event) {
this.dispatchEvent(new FocusEvent(event.currentTarget.data));
}
_handleLogEntryRelated(event) {
this.dispatchEvent(new SelectRelatedEvent(event.currentTarget.data));
}
});