Commit 8b338b25 authored by Zeynep Cankara's avatar Zeynep Cankara Committed by Commit Bot

[tools][system-analyzer] Add Transition View logic to Map Panel

This CL depreciates the TransitionView Class of the
app model to handle map transition only within map
model. It isolates the Map Panel to comply web
component standards.

Bug: v8:10667, v8:10644

Change-Id: Idf8ca58744aacd0159ee4af6e71886374385377e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2300541
Commit-Queue: Zeynep Cankara <zcankara@google.com>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68902}
parent 3c1bf982
......@@ -105,8 +105,8 @@ class App {
}
handleShowMaps(e) {
// show maps on the view
document.state.view.transitionView.showMaps(e.detail);
//document.state.view.transitionView.showMaps(e.detail);
document.state.mapPanel.showMaps(e.detail);
}
handleSelectIc(e){
......
......@@ -14,6 +14,8 @@ class State {
this._timeline = undefined;
this._chunks = undefined;
this._view = new View(this, mapPanelId, timelinePanelId);
//TODO(zcankara) Depreciate the view
this.mapPanel_ = $(mapPanelId);
this._navigation = new Navigation(this, this.view);
}
set filteredEntries(value) {
......@@ -32,7 +34,7 @@ class State {
this._timeline = value;
this.updateChunks();
this.view.updateTimeline();
this.view.updateStats();
this.mapPanel_.updateStats(this.timeline);
}
get chunks() {
return this._chunks
......@@ -45,6 +47,9 @@ class State {
this.updateChunks();
this.view.updateTimeline();
}
get mapPanel() {
return this.mapPanel_;
}
get view() {
return this._view
}
......@@ -57,7 +62,7 @@ class State {
set map(value) {
this._map = value;
this._navigation.updateUrl();
this.view.updateMapDetails();
this.mapPanel_.showMap(this.map);
this.view.redraw();
}
updateChunks() {
......@@ -154,8 +159,9 @@ class View {
this.state = state;
setInterval(this.updateOverviewWindow(timelinePanelId), 50);
this.backgroundCanvas = document.createElement('canvas');
this.transitionView =
new TransitionView(state, this.mapPanel_.transitionView);
//TODO(zcankara) Instantiate the map panel transition view
this.mapPanel_.transitionView = state;
this.isLocked = false;
this._filteredEntries = [];
}
......@@ -169,21 +175,6 @@ class View {
return this.state.map
}
updateStats() {
this.mapPanel_.timeline = this.state.timeline;
}
updateMapDetails() {
let details = '';
if (this.map) {
details += 'ID: ' + this.map.id;
details += '\nSource location: ' + this.map.filePosition;
details += '\n' + this.map.description;
}
this.mapPanel_.mapDetails.innerText = details;
this.transitionView.showMap(this.map);
}
updateTimeline() {
let chunksNode = this.timelinePanel_.timelineChunks;
removeAllChildren(chunksNode);
......@@ -218,6 +209,7 @@ class View {
chunk.markers.forEach(marker => addTimestamp(marker.time, marker.name));
}
this.asyncSetTimelineChunkBackground(backgroundTodo)
// Put a time marker roughly every 20 chunks.
......@@ -236,6 +228,7 @@ class View {
this.redraw();
}
handleChunkMouseMove(event) {
if (this.isLocked) return false;
let chunk = event.target.chunk;
......@@ -255,7 +248,7 @@ class View {
this.isLocked = true;
let chunk = event.target.chunk;
if (!chunk) return;
this.transitionView.showMaps(chunk.getUniqueTransitions());
this.mapPanel_.showMaps(chunk.getUniqueTransitions());
}
asyncSetTimelineChunkBackground(backgroundTodo) {
......@@ -483,139 +476,6 @@ class View {
}
}
class TransitionView {
constructor(state, node) {
this.state = state;
this.container = node;
this.currentNode = node;
this.currentMap = undefined;
}
selectMap(map) {
this.currentMap = map;
this.state.map = map;
}
showMap(map) {
if (this.currentMap === map) return;
this.currentMap = map;
this._showMaps([map]);
}
showMaps(list, name) {
this.state.view.isLocked = true;
this._showMaps(list);
}
_showMaps(list, name) {
// Hide the container to avoid any layouts.
this.container.style.display = 'none';
removeAllChildren(this.container);
list.forEach(map => this.addMapAndParentTransitions(map));
this.container.style.display = ''
}
addMapAndParentTransitions(map) {
if (map === void 0) return;
this.currentNode = this.container;
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 = div('map');
if (map.edge) node.style.backgroundColor = map.edge.getColor();
node.map = map;
node.addEventListener('click', () => this.selectMap(map));
if (map.children.length > 1) {
node.innerText = map.children.length;
let showSubtree = 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;
}
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 = div(classes);
edge.style.backgroundColor = map.edge.getColor();
let labelNode = div('transitionLabel');
labelNode.innerText = map.edge.toString();
edge.appendChild(labelNode);
return edge;
}
addTransitionTo(map) {
// transition[ transitions[ transition[...], transition[...], ...]];
let transition = 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 = 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]);
}
}
}
}
// =========================================================================
......
......@@ -77,5 +77,174 @@ defineCustomElement('map-panel', (templateText) =>
'click', {bubbles: true, composed: true, detail: dataModel}));
}
//TODO(zcankara) Take view, transitionView logic inside map panel
//TODO(zcankara) VIEW RELATED
updateStats(timeline) {
this.timeline = timeline;
}
updateMapDetails(map) {
let details = '';
if (map) {
details += 'ID: ' + map.id;
details += '\nSource location: ' + map.filePosition;
details += '\n' + map.description;
}
this.mapDetails.innerText = details;
}
//TODO(zcankara) DOM RELATED
div(classes) {
let node = document.createElement('div');
if (classes !== void 0) {
if (typeof classes === 'string') {
node.classList.add(classes);
} else {
classes.forEach(cls => node.classList.add(cls));
}
}
return node;
}
removeAllChildren(node) {
while (node.lastChild) {
node.removeChild(node.lastChild);
}
}
//TODO(zcankara) TRANSITIONVIEW RELATED
set transitionView(state){
this.state = state;
this.container = this.transitionView;
this.currentNode = this.transitionView;
this.currentMap = undefined;
}
selectMap(map) {
this.currentMap = map;
this.state.map = map;
}
showMap(map) {
this.updateMapDetails(map);
if (this.currentMap === map) return;
this.currentMap = map;
this._showMaps([map]);
}
showMaps(list) {
this.state.view.isLocked = true;
this._showMaps(list);
}
_showMaps(list) {
// Hide the container to avoid any layouts.
this.container.style.display = 'none';
this.removeAllChildren(this.container);
list.forEach(map => this.addMapAndParentTransitions(map));
this.container.style.display = ''
}
addMapAndParentTransitions(map) {
if (map === void 0) return;
this.currentNode = this.container;
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));
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 = '&#x25CF;'
}
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]);
}
}
}
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment