blob: 00ef2f55c0e32fbbc013b387dbb193bb3efbbe6e [file] [log] [blame]
<!DOCTYPE html>
<!-- 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. -->
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Indicium</title>
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
<!-- <link rel="icon" type="image/png" href="/images/favicon.png"/> -->
<!-- <script type="module" src="index.js"></script> -->
<link rel="stylesheet" type="text/css" href="./index.css">
<script src="helper.js"></script>
<script type="module" src="log-file-reader.mjs"></script>
<script type="module" src="map-panel.mjs"></script>
<script type="module" src="timeline-panel.mjs"></script>
<script type="module" src="ic-panel.mjs"></script>
<script src="../splaytree.js"></script>
<script src="../codemap.js"></script>
<script src="../csvparser.js"></script>
<script src="../consarray.js"></script>
<script src="../profile.js"></script>
<script src="../profile_view.js"></script>
<script src="../logreader.js"></script>
<script src="../arguments.js"></script>
<script src="../SourceMap.js"></script>
<script src="./map-processor.js"></script>
<script src="./ic-processor.js"></script>
<script src="./map-model.js"></script>
<style>
#instructions {
padding: 10px 10px 60px 10px ;
margin: auto;
background-color: #121212;
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
}
kbd {
background-color: #BB86FC;
color:black;
border-radius: 3px;
border: 1px solid black;
display: inline-block;
font-size: .9em;
font-weight: bold;
padding: 0px 4px 2px 4px;
white-space: nowrap;
}
dl {
display: grid;
grid-template-columns: min-content auto;
grid-gap: 10px;
}
dt {
text-align: right;
white-space: nowrap;
}
dd {
margin: 0;
}
</style>
<script>
'use strict';
// Event handlers
document.onkeydown = handleKeyDown;
function handleKeyDown(event) {
stateGlobal.navigation = document.state.navigation;
let nav = document.state.navigation;
switch(event.key) {
case "ArrowUp":
event.preventDefault();
if (event.shiftKey) {
nav.selectPrevEdge();
} else {
nav.moveInChunk(-1);
}
return false;
case "ArrowDown":
event.preventDefault();
if (event.shiftKey) {
nav.selectNextEdge();
} else {
nav.moveInChunk(1);
}
return false;
case "ArrowLeft":
nav.moveInChunks(false);
break;
case "ArrowRight":
nav.moveInChunks(true);
break;
case "+":
nav.increaseTimelineResolution();
break;
case "-":
nav.decreaseTimelineResolution();
break;
}
}
// Update application state
function updateDocumentState(){
document.state = stateGlobal.state;
try {
document.state.timeline = stateGlobal.timeline;
} catch (error) {
console.log(error);
console.log("cannot assign timeline to the state!");
}
}
// Map event log processing
function handleLoadTextMapProcessor(text) {
let mapProcessor = new MapProcessor();
return mapProcessor.processString(text);
}
// IC event file reading and log processing
function loadFileIC(file) {
let reader = new FileReader();
reader.onload = function(evt) {
let icProcessor = new CustomIcProcessor();
icProcessor.processString(this.result);
let entries = icProcessor.entries;
$("ic-panel").countSelect.innerHTML = entries.length;
$('#ic-panel').entries = entries;
}
reader.readAsText(file);
$("ic-panel").initGroupKeySelect();
}
function $(id) { return document.querySelector(id); }
// holds the state of the application
let stateGlobal = Object.create(null);
// call when a new file uploaded
function globalDataUpload(e) {
stateGlobal.timeline = e.detail;
if(!e.detail) return;
$('#container').style.display = 'block';
// instantiate the app logic
stateGlobal.fileData = e.detail;
stateGlobal.state = new State('#map-panel','#timeline-panel');
stateGlobal.timeline = handleLoadTextMapProcessor(stateGlobal.fileData.chunk);
updateDocumentState();
loadFileIC(stateGlobal.fileData.file);
}
function globalSearchBarEvent(e) {
if(!e.detail.isValidMap) return;
document.state.map = e.detail.map;
}
function handleSelectIcEvents(e){
if(!e.detail) return;
// Set selected IC events on the View
document.state.filteredEntries = e.detail;
}
function showMaps(e) {
if(!e.detail) return;
// Show selected maps on the View
document.state.view.transitionView.showMaps(e.detail);
}
</script>
</head>
<body>
<div id="content">
<section id="file-reader">
<br></br>
<log-file-reader id="log-file-reader" onchange="globalDataUpload(event)"></log-file-reader>
<br></br>
</section>
<div id="container" style="display: none;">
<timeline-panel id="timeline-panel"></timeline-panel>
<map-panel id="map-panel" onclick="globalSearchBarEvent(event)" onchange="showMaps(event)"></map-panel>
<ic-panel id="ic-panel" onchange="handleSelectIcEvents(event)"></ic-panel>
</div>
</div>
<div id="instructions">
<h2>Instructions</h2>
<p>Unified web interface for analyzing the trace information of the Maps/ICs</p>
<ul>
<li> Visualize Map trees that have gathered</li>
<li><code> /path/to/d8 --trace-maps $FILE</code></li>
<li> Visualize IC events that have gathered</li>
<li><code> /path/to/d8 --trace_ic $FILE (your_script.js) </code></li>
</ul>
<h3>Keyboard Shortcuts</h3>
<dl>
<dt><kbd>SHIFT</kbd> + <kbd>Arrow Up</kbd></dt>
<dd>Follow Map transition forward (first child)</dd>
<dt><kbd>SHIFT</kbd> + <kbd>Arrow Down</kbd></dt>
<dd>Follow Map transition backwards</dd>
<dt><kbd>Arrow Up</kbd></dt>
<dd>Go to previous Map chunk</dd>
<dt><kbd>Arrow Down</kbd></dt>
<dd>Go to next Map in chunk</dd>
<dt><kbd>Arrow Left</kbd></dt>
<dd>Go to previous chunk</dd>
<dt><kbd>Arrow Right</kbd></dt>
<dd>Go to next chunk</dd>
<dt><kbd>+</kbd></dt>
<dd>Timeline zoom in</dd>
<dt><kbd>-</kbd></dt>
<dd>Timeline zoom out</dd>
</dl>
</div>
</body>
</html>