diff options
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.mjs | 366 |
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 = '●'; + } + 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]); } } -); + } +}); |