71e0331137
This CL aims to clean the code in App Class to handle State, View according to the Model-View-Controller design pattern. Bug: v8:10644, v8:10735 Link: https://docs.google.com/presentation/d/1ssCIWKS5TIp_PHZRUx2BfElEz6JFrYzz_Ce1h1g8ZBg/edit?usp=sharing Change-Id: Ie36d437df0df574f505a4396b26526a82215f237 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2324247 Commit-Queue: Zeynep Cankara <zcankara@google.com> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#69218}
164 lines
5.9 KiB
JavaScript
164 lines
5.9 KiB
JavaScript
// 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 CustomIcProcessor from "./ic-processor.mjs";
|
|
import {State} from './app-model.mjs';
|
|
import {MapProcessor, V8Map} from './map-processor.mjs';
|
|
import {Chunk} from './timeline.mjs';
|
|
import {$} from './helper.mjs';
|
|
import './ic-panel.mjs';
|
|
import './timeline-panel.mjs';
|
|
import './map-panel.mjs';
|
|
import './log-file-reader.mjs';
|
|
class App {
|
|
#state
|
|
#view;
|
|
constructor(fileReaderId, mapPanelId, timelinePanelId,
|
|
icPanelId, mapTrackId, icTrackId) {
|
|
this.#view = {
|
|
logFileReader: $(fileReaderId),
|
|
icPanel: $(icPanelId),
|
|
mapPanel: $(mapPanelId),
|
|
timelinePanel: $(timelinePanelId),
|
|
mapTrack: $(mapTrackId),
|
|
icTrack: $(icTrackId),
|
|
}
|
|
this.#state = new State();
|
|
this.#view.logFileReader.addEventListener('fileuploadstart',
|
|
e => this.handleFileUpload(e));
|
|
this.#view.logFileReader.addEventListener('fileuploadend',
|
|
e => this.handleDataUpload(e));
|
|
this.toggleSwitch = $('.theme-switch input[type="checkbox"]');
|
|
this.toggleSwitch.addEventListener('change', e => this.switchTheme(e));
|
|
this.#view.timelinePanel.addEventListener(
|
|
'mapchange', e => this.handleMapChange(e));
|
|
this.#view.timelinePanel.addEventListener(
|
|
'showmaps', e => this.handleShowMaps(e));
|
|
this.#view.mapPanel.addEventListener(
|
|
'mapchange', e => this.handleMapChange(e));
|
|
this.#view.mapPanel.addEventListener(
|
|
'selectmapdblclick', e => this.handleDblClickSelectMap(e));
|
|
this.#view.mapPanel.addEventListener(
|
|
'sourcepositionsclick', e => this.handleClickSourcePositions(e));
|
|
this.#view.icPanel.addEventListener(
|
|
'ictimefilter', e => this.handleICTimeFilter(e));
|
|
this.#view.icPanel.addEventListener(
|
|
'mapclick', e => this.handleMapClick(e));
|
|
this.#view.mapPanel.addEventListener(
|
|
'click', e => this.handleMapAddressSearch(e));
|
|
this.#view.mapPanel.addEventListener(
|
|
'change', e => this.handleShowMapsChange(e));
|
|
this.#view.icPanel.addEventListener(
|
|
'filepositionclick', e => this.handleFilePositionClick(e));
|
|
}
|
|
handleMapClick(e) {
|
|
//TODO(zcankara) Direct the event based on the key and value
|
|
console.log("map: ", e.detail.key);
|
|
}
|
|
handleFilePositionClick(e) {
|
|
//TODO(zcankara) Direct the event based on the key and value
|
|
console.log("filePosition: ", e.detail.key);
|
|
}
|
|
handleClickSourcePositions(e){
|
|
//TODO(zcankara) Handle source position
|
|
console.log("source position map detail: ", e.detail);
|
|
}
|
|
handleDblClickSelectMap(e){
|
|
//TODO(zcankara) Handle double clicked map
|
|
console.log("double clicked map: ", e.detail);
|
|
}
|
|
handleMapChange(e){
|
|
if (!(e.detail instanceof V8Map)){
|
|
console.error("selected entry not a V8Map instance");
|
|
return;
|
|
}
|
|
this.#state.map = e.detail;
|
|
this.#view.mapTrack.selectedEntry = e.detail;
|
|
this.#view.mapPanel.map = e.detail;
|
|
}
|
|
handleShowMaps(e){
|
|
if (!(e.detail instanceof Chunk)){
|
|
console.error("Chunk not selected");
|
|
return;
|
|
}
|
|
this.#view.mapPanel.mapEntries = e.detail.filter();
|
|
}
|
|
handleICTimeFilter(event) {
|
|
this.#state.timeSelection.start = event.detail.startTime;
|
|
this.#state.timeSelection.end = event.detail.endTime;
|
|
this.#view.icTrack.data.selectTimeRange(this.#state.timeSelection.start,
|
|
this.#state.timeSelection.end);
|
|
this.#view.icPanel.filteredEntries = this.#view.icTrack.data.selection;
|
|
}
|
|
handleMapAddressSearch(e) {
|
|
//TODO(zcankara) Combine with handleMapChange into selectMap event
|
|
//TODO(zcankara) Possibility of select no map
|
|
if(!e.detail.map) return;
|
|
this.#state.map = e.detail.map;
|
|
this.#view.mapTrack.selectedEntry = e.detail.map;
|
|
this.#view.mapPanel.map = e.detail.map;
|
|
}
|
|
handleShowMapsChange(e) {
|
|
//TODO(zcankara) Map entries repeats "map". Probabluy not needed
|
|
this.#view.mapPanel.mapEntries = e.detail;
|
|
}
|
|
handleFileUpload(e){
|
|
//TODO(zcankara) Set a state on the document.body. Exe: .loading, .loaded
|
|
$('#container').style.display = 'none';
|
|
}
|
|
|
|
// Map event log processing
|
|
handleLoadTextMapProcessor(text) {
|
|
let mapProcessor = new MapProcessor();
|
|
return mapProcessor.processString(text);
|
|
}
|
|
|
|
// IC event file reading and log processing
|
|
loadICLogFile(fileData) {
|
|
let reader = new FileReader();
|
|
reader.onload = (evt) => {
|
|
let icProcessor = new CustomIcProcessor();
|
|
//TODO(zcankara) Assign timeline directly to the ic panel
|
|
//TODO(zcankara) Exe: this.#icPanel.timeline = document.state.icTimeline
|
|
//TODO(zcankara) Set the data of the State object first
|
|
this.#state.icTimeline = icProcessor.processString(fileData.chunk);
|
|
this.#view.icTrack.data = this.#state.icTimeline;
|
|
this.#view.icPanel.filteredEntries = this.#view.icTrack.data.all;
|
|
this.#view.icPanel.count.innerHTML = this.#view.icTrack.data.all.length;
|
|
}
|
|
reader.readAsText(fileData.file);
|
|
this.#view.icPanel.initGroupKeySelect();
|
|
}
|
|
|
|
// call when a new file uploaded
|
|
handleDataUpload(e) {
|
|
if(!e.detail) return;
|
|
$('#container').style.display = 'block';
|
|
// instantiate the app logic
|
|
let fileData = e.detail;
|
|
try {
|
|
const timeline = this.handleLoadTextMapProcessor(fileData.chunk);
|
|
// Transitions must be set before timeline for stats panel.
|
|
this.#state.mapTimeline = timeline;
|
|
this.#view.mapPanel.transitions = this.#state.mapTimeline.transitions;
|
|
this.#view.mapTrack.data = this.#state.mapTimeline;
|
|
this.#state.chunks = this.#view.mapTrack.chunks;
|
|
this.#view.mapPanel.timeline = this.#state.mapTimeline;
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
this.loadICLogFile(fileData);
|
|
this.fileLoaded = true;
|
|
}
|
|
|
|
switchTheme(event) {
|
|
if(this.fileLoaded) return;
|
|
document.documentElement.dataset.theme =
|
|
event.target.checked ? 'dark' : 'light';
|
|
}
|
|
}
|
|
|
|
|
|
export {App};
|