summaryrefslogtreecommitdiff
path: root/deps/v8/tools/system-analyzer/map-panel/map-transitions.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/tools/system-analyzer/map-panel/map-transitions.mjs')
-rw-r--r--deps/v8/tools/system-analyzer/map-panel/map-transitions.mjs366
1 files changed, 178 insertions, 188 deletions
diff --git a/deps/v8/tools/system-analyzer/map-panel/map-transitions.mjs b/deps/v8/tools/system-analyzer/map-panel/map-transitions.mjs
index d508b88694..60462a1db2 100644
--- a/deps/v8/tools/system-analyzer/map-panel/map-transitions.mjs
+++ b/deps/v8/tools/system-analyzer/map-panel/map-transitions.mjs
@@ -1,194 +1,184 @@
// Copyright 2020 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 { V8CustomElement, defineCustomElement } from "../helper.mjs";
-import { FocusEvent } from "../events.mjs";
-
-defineCustomElement(
- "./map-panel/map-transitions",
- (templateText) =>
- class MapTransitions extends V8CustomElement {
- #map;
- #selectedMapLogEvents;
- constructor() {
- super(templateText);
- this.transitionView.addEventListener("mousemove", (e) =>
- this.handleTransitionViewChange(e)
- );
- this.currentNode = this.transitionView;
- this.currentMap = undefined;
- }
-
- get transitionView() {
- return this.$("#transitionView");
- }
-
- get tooltip() {
- return this.$("#tooltip");
- }
-
- get tooltipContents() {
- return this.$("#tooltipContents");
- }
-
- set map(value) {
- this.#map = value;
- this.showMap();
- }
-
- handleTransitionViewChange(e) {
- this.tooltip.style.left = e.pageX + "px";
- this.tooltip.style.top = e.pageY + "px";
- let map = e.target.map;
- if (map) {
- this.tooltipContents.innerText = map.description;
- }
- }
-
- selectMap(map) {
- this.currentMap = map;
- this.showMap();
- this.dispatchEvent(new FocusEvent(map));
- }
-
- dblClickSelectMap(map) {
- this.dispatchEvent(new FocusEvent(map));
- }
-
- showMap() {
- // Called when a map selected
- if (this.currentMap === this.#map) return;
- this.currentMap = this.#map;
- this.selectedMapLogEvents = [this.#map];
- this.dispatchEvent(new FocusEvent(this.#map));
- }
-
- showMaps() {
- // Timeline dbl click to show map transitions of selected maps
- this.transitionView.style.display = "none";
- this.removeAllChildren(this.transitionView);
- this.selectedMapLogEvents.forEach((map) =>
- this.addMapAndParentTransitions(map));
- this.transitionView.style.display = "";
- }
-
- set selectedMapLogEvents(list) {
- this.#selectedMapLogEvents = list;
- this.showMaps();
- }
-
- get selectedMapLogEvents() {
- return this.#selectedMapLogEvents;
- }
-
- addMapAndParentTransitions(map) {
- if (map === void 0) return;
- this.currentNode = this.transitionView;
- let parents = map.getParents();
- if (parents.length > 0) {
- this.addTransitionTo(parents.pop());
- parents.reverse().forEach((each) => this.addTransitionTo(each));
- }
- let mapNode = this.addSubtransitions(map);
- // Mark and show the selected map.
- mapNode.classList.add("selected");
- if (this.selectedMap == map) {
- setTimeout(
- () =>
- mapNode.scrollIntoView({
- behavior: "smooth",
- block: "nearest",
- inline: "nearest",
- }),
- 1
- );
- }
- }
-
- addMapNode(map) {
- let node = this.div("map");
- if (map.edge) node.style.backgroundColor = map.edge.getColor();
- node.map = map;
- node.addEventListener("click", () => this.selectMap(map));
- node.addEventListener("dblclick", () => this.dblClickSelectMap(map));
- if (map.children.length > 1) {
- node.innerText = map.children.length;
- let showSubtree = this.div("showSubtransitions");
- showSubtree.addEventListener("click", (e) =>
- this.toggleSubtree(e, node)
- );
- node.appendChild(showSubtree);
- } else if (map.children.length == 0) {
- node.innerHTML = "●";
- }
- this.currentNode.appendChild(node);
- return node;
- }
-
- addSubtransitions(map) {
- let mapNode = this.addTransitionTo(map);
- // Draw outgoing linear transition line.
- let current = map;
- while (current.children.length == 1) {
- current = current.children[0].to;
- this.addTransitionTo(current);
- }
- return mapNode;
- }
-
- addTransitionEdge(map) {
- let classes = ["transitionEdge"];
- let edge = this.div(classes);
- edge.style.backgroundColor = map.edge.getColor();
- let labelNode = this.div("transitionLabel");
- labelNode.innerText = map.edge.toString();
- edge.appendChild(labelNode);
- return edge;
- }
-
- addTransitionTo(map) {
- // transition[ transitions[ transition[...], transition[...], ...]];
-
- let transition = this.div("transition");
- if (map.isDeprecated()) transition.classList.add("deprecated");
- if (map.edge) {
- transition.appendChild(this.addTransitionEdge(map));
- }
- let mapNode = this.addMapNode(map);
- transition.appendChild(mapNode);
-
- let subtree = this.div("transitions");
- transition.appendChild(subtree);
-
- this.currentNode.appendChild(transition);
- this.currentNode = subtree;
-
- return mapNode;
- }
-
- toggleSubtree(event, node) {
- let map = node.map;
- event.target.classList.toggle("opened");
- let transitionsNode = node.parentElement.querySelector(".transitions");
- let subtransitionNodes = transitionsNode.children;
- if (subtransitionNodes.length <= 1) {
- // Add subtransitions excepth the one that's already shown.
- let visibleTransitionMap =
- subtransitionNodes.length == 1
- ? transitionsNode.querySelector(".map").map
- : void 0;
- map.children.forEach((edge) => {
- if (edge.to != visibleTransitionMap) {
- this.currentNode = transitionsNode;
- this.addSubtransitions(edge.to);
- }
- });
- } else {
- // remove all but the first (currently selected) subtransition
- for (let i = subtransitionNodes.length - 1; i > 0; i--) {
- transitionsNode.removeChild(subtransitionNodes[i]);
- }
+import {FocusEvent, SelectionEvent} from '../events.mjs';
+import {DOM, typeToColor, V8CustomElement} from '../helper.mjs';
+
+DOM.defineCustomElement('./map-panel/map-transitions',
+ (templateText) =>
+ class MapTransitions extends V8CustomElement {
+ _map;
+ _selectedMapLogEntries;
+ _displayedMapsInTree;
+
+ constructor() {
+ super(templateText);
+ this.transitionView.addEventListener(
+ 'mousemove', (e) => this.handleTransitionViewChange(e));
+ this.currentNode = this.transitionView;
+ this.currentMap = undefined;
+ }
+
+ get transitionView() {
+ return this.$('#transitionView');
+ }
+
+ get tooltip() {
+ return this.$('#tooltip');
+ }
+
+ get tooltipContents() {
+ return this.$('#tooltipContents');
+ }
+
+ set map(value) {
+ this._map = value;
+ this.showMap();
+ }
+
+ handleTransitionViewChange(e) {
+ this.tooltip.style.left = e.pageX + 'px';
+ this.tooltip.style.top = e.pageY + 'px';
+ const map = e.target.map;
+ if (map) {
+ this.tooltipContents.innerText = map.description;
+ }
+ }
+
+ _selectMap(map) {
+ this.dispatchEvent(new SelectionEvent([map]));
+ }
+
+ showMap() {
+ if (this.currentMap === this._map) return;
+ this.currentMap = this._map;
+ this.selectedMapLogEntries = [this._map];
+ this.update();
+ }
+
+ _update() {
+ this.transitionView.style.display = 'none';
+ DOM.removeAllChildren(this.transitionView);
+ this._displayedMapsInTree = new Set();
+ // Limit view to 200 maps for performance reasons.
+ this.selectedMapLogEntries.slice(0, 200).forEach(
+ (map) => this.addMapAndParentTransitions(map));
+ this._displayedMapsInTree = undefined;
+ this.transitionView.style.display = '';
+ }
+
+ set selectedMapLogEntries(list) {
+ this._selectedMapLogEntries = list;
+ this.update();
+ }
+
+ get selectedMapLogEntries() {
+ return this._selectedMapLogEntries;
+ }
+
+ addMapAndParentTransitions(map) {
+ if (map === void 0) return;
+ if (this._displayedMapsInTree.has(map)) return;
+ this._displayedMapsInTree.add(map);
+ this.currentNode = this.transitionView;
+ let parents = map.getParents();
+ if (parents.length > 0) {
+ this.addTransitionTo(parents.pop());
+ parents.reverse().forEach((each) => this.addTransitionTo(each));
+ }
+ let mapNode = this.addSubtransitions(map);
+ // Mark and show the selected map.
+ mapNode.classList.add('selected');
+ if (this.selectedMap == map) {
+ setTimeout(
+ () => mapNode.scrollIntoView({
+ behavior: 'smooth',
+ block: 'nearest',
+ inline: 'nearest',
+ }),
+ 1);
+ }
+ }
+
+ addSubtransitions(map) {
+ let mapNode = this.addTransitionTo(map);
+ // Draw outgoing linear transition line.
+ let current = map;
+ while (current.children.length == 1) {
+ current = current.children[0].to;
+ this.addTransitionTo(current);
+ }
+ return mapNode;
+ }
+
+ addTransitionEdge(map) {
+ let classes = ['transitionEdge'];
+ let edge = DOM.div(classes);
+ edge.style.backgroundColor = typeToColor(map.edge);
+ let labelNode = DOM.div('transitionLabel');
+ labelNode.innerText = map.edge.toString();
+ edge.appendChild(labelNode);
+ return edge;
+ }
+
+ addTransitionTo(map) {
+ // transition[ transitions[ transition[...], transition[...], ...]];
+ this._displayedMapsInTree?.add(map);
+ let transition = DOM.div('transition');
+ if (map.isDeprecated()) transition.classList.add('deprecated');
+ if (map.edge) {
+ transition.appendChild(this.addTransitionEdge(map));
+ }
+ let mapNode = this.addMapNode(map);
+ transition.appendChild(mapNode);
+
+ let subtree = DOM.div('transitions');
+ transition.appendChild(subtree);
+
+ this.currentNode.appendChild(transition);
+ this.currentNode = subtree;
+
+ return mapNode;
+ }
+
+ addMapNode(map) {
+ let node = DOM.div('map');
+ if (map.edge) node.style.backgroundColor = typeToColor(map.edge);
+ node.map = map;
+ node.addEventListener('click', () => this._selectMap(map));
+ if (map.children.length > 1) {
+ node.innerText = map.children.length;
+ let showSubtree = DOM.div('showSubtransitions');
+ showSubtree.addEventListener('click', (e) => this.toggleSubtree(e, node));
+ node.appendChild(showSubtree);
+ } else if (map.children.length == 0) {
+ node.innerHTML = '&#x25CF;';
+ }
+ this.currentNode.appendChild(node);
+ return node;
+ }
+
+ toggleSubtree(event, node) {
+ let map = node.map;
+ event.target.classList.toggle('opened');
+ let transitionsNode = node.parentElement.querySelector('.transitions');
+ let subtransitionNodes = transitionsNode.children;
+ if (subtransitionNodes.length <= 1) {
+ // Add subtransitions excepth the one that's already shown.
+ let visibleTransitionMap = subtransitionNodes.length == 1 ?
+ transitionsNode.querySelector('.map').map :
+ void 0;
+ map.children.forEach((edge) => {
+ if (edge.to != visibleTransitionMap) {
+ this.currentNode = transitionsNode;
+ this.addSubtransitions(edge.to);
}
+ });
+ } else {
+ // remove all but the first (currently selected) subtransition
+ for (let i = subtransitionNodes.length - 1; i > 0; i--) {
+ transitionsNode.removeChild(subtransitionNodes[i]);
}
}
-);
+ }
+});