mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-02 07:05:24 +00:00
fad6bfb506
d1b433a3b3bab353f320b2f39fa953ce326d2d55 changed the encoding format for Flows. The root is no longer wrapped inside a `data` field, but instead includes BaseFlow fields directly. This broke the layout trace viewer, which threw an uncaught exception when the `data` property was missing. This fixes the exception, though some functionality may still be partly broken. Source-Repo: https://github.com/servo/servo Source-Revision: b2b6d4d0d1e381d038dc5e45cbe74304704934e7
254 lines
9.7 KiB
HTML
254 lines
9.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Servo Layout Debugger</title>
|
|
|
|
<!-- Bootstrap -->
|
|
<link href="css/bootstrap.min.css" rel="stylesheet">
|
|
|
|
<!-- Treeview -->
|
|
<link href="css/bootstrap-treeview.min.css" rel="stylesheet">
|
|
|
|
<!-- JSDiffPatch -->
|
|
<link href="css/formatters/html.css" rel="stylesheet">
|
|
|
|
<!-- Custom -->
|
|
<link href="css/main.css" rel="stylesheet">
|
|
|
|
<!--[if lt IE 9]>
|
|
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
|
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
|
<![endif]-->
|
|
</head>
|
|
<body>
|
|
|
|
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
|
<div class="container">
|
|
<div class="navbar-header">
|
|
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
|
<span class="sr-only">Toggle navigation</span>
|
|
<span class="icon-bar"></span>
|
|
<span class="icon-bar"></span>
|
|
<span class="icon-bar"></span>
|
|
</button>
|
|
<a class="navbar-brand" href="#">Servo Layout Debugger</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container" role="main">
|
|
<div class="row">
|
|
<div class="col-sm-3">
|
|
<div class="row">
|
|
<div class="col-sm-12">
|
|
<div class="well">
|
|
<input type=file>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-12">
|
|
<div id="trace-tree">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-sm-12">
|
|
<ul id="trace-list" class="list-group">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-9">
|
|
<div class="row">
|
|
<div class="col-sm-12">
|
|
<div class='panel panel-default'>
|
|
<div class='panel-heading'>Flow Tree</div>
|
|
<div class='panel-body' id="flow-tree"></div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-12">
|
|
<div id="flow-diffs"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- jQuery -->
|
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
|
|
<!-- Bootstrap -->
|
|
<script src="js/bootstrap.min.js"></script>
|
|
<!-- Treeview -->
|
|
<script src="js/bootstrap-treeview.min.js"></script>
|
|
<!-- JSDiffPatch -->
|
|
<script src="js/bundle.min.js"></script>
|
|
<script src="js/formatters.min.js"></script>
|
|
|
|
<script>
|
|
function get_base(node) {
|
|
if (node.id !== undefined) {
|
|
return node;
|
|
}
|
|
if (node.data.base !== undefined) {
|
|
return node.data.base;
|
|
}
|
|
if (node.data.block_flow.base !== undefined) {
|
|
return node.data.block_flow.base;
|
|
}
|
|
throw "Unknown node type";
|
|
}
|
|
|
|
function create_flow_tree(trace_node) {
|
|
var node = {
|
|
text: trace_node.class + " (" + get_base(trace_node).id + ")",
|
|
id: get_base(trace_node).id,
|
|
icon: "dummy",
|
|
};
|
|
|
|
var children = [];
|
|
for (var i=0 ; i < get_base(trace_node).children.length ; ++i) {
|
|
children.push(create_flow_tree(get_base(trace_node).children[i]));
|
|
}
|
|
|
|
if (children.length > 0) {
|
|
node.nodes = children;
|
|
}
|
|
|
|
return node;
|
|
}
|
|
|
|
function create_flow_hash(trace_node, flow_hash) {
|
|
flow_hash[get_base(trace_node).id] = trace_node;
|
|
|
|
for (var i=0 ; i < get_base(trace_node).children.length ; ++i) {
|
|
create_flow_hash(get_base(trace_node).children[i], flow_hash);
|
|
}
|
|
|
|
delete get_base(trace_node).children;
|
|
}
|
|
|
|
function flatten_trace(trace_node) {
|
|
var flow_tree = create_flow_tree(trace_node);
|
|
|
|
var flow_hash = {};
|
|
create_flow_hash(trace_node, flow_hash);
|
|
|
|
return {
|
|
tree: flow_tree,
|
|
flows: flow_hash,
|
|
}
|
|
}
|
|
|
|
function create_tree_node(trace_node) {
|
|
var pre_trace = flatten_trace(JSON.parse(trace_node.pre));
|
|
var post_trace = flatten_trace(JSON.parse(trace_node.post));
|
|
|
|
var tree_node = {
|
|
text: trace_node.name,
|
|
icon: "dummy",
|
|
flow_tree: pre_trace.tree, // assume pre/post trace always have same tree!
|
|
pre: pre_trace.flows,
|
|
post: post_trace.flows,
|
|
};
|
|
|
|
var children = [];
|
|
|
|
for (var i=0 ; i < trace_node.children.length ; ++i) {
|
|
children.push(create_tree_node(trace_node.children[i]));
|
|
}
|
|
|
|
if (children.length > 0) {
|
|
tree_node.nodes = children;
|
|
}
|
|
|
|
return tree_node;
|
|
}
|
|
|
|
function update_flow_tree_bgcolor(flow_tree_node, node_color_hash) {
|
|
flow_tree_node.backColor = node_color_hash[flow_tree_node.id];
|
|
if (flow_tree_node.nodes !== undefined) {
|
|
for (var i=0 ; i < flow_tree_node.nodes.length ; ++i) {
|
|
update_flow_tree_bgcolor(flow_tree_node.nodes[i], node_color_hash)
|
|
}
|
|
}
|
|
}
|
|
|
|
function new_data_loaded(data) {
|
|
jsondiffpatch.formatters.html.hideUnchanged();
|
|
|
|
var node_color_hash = {};
|
|
var tree = [ create_tree_node(data) ];
|
|
$('#trace-tree').treeview({data: tree, levels: 3});
|
|
$('#trace-tree').on('nodeSelected', function(event, node) {
|
|
$("#flow-diffs").empty();
|
|
|
|
for (var key in node.pre) {
|
|
var flow_left = node.pre[key];
|
|
var flow_right = node.post[key];
|
|
|
|
var delta = jsondiffpatch.create({
|
|
objectHash: function(obj) {
|
|
if (obj.data !== undefined && obj.data.base !== undefined) {
|
|
return obj.data.base.id;
|
|
}
|
|
if (obj.data !== undefined && obj.data.block_flow !== undefined &&
|
|
obj.data.block_flow.base !== undefined) {
|
|
return obj.data.block_flow.base.id;
|
|
}
|
|
if (obj.id !== undefined) {
|
|
return obj.id;
|
|
}
|
|
return JSON.stringify(obj);
|
|
}
|
|
}).diff(flow_left, flow_right);
|
|
|
|
if (delta !== undefined) {
|
|
var diff_id = "diff-" + key;
|
|
$("#flow-diffs").append(
|
|
"<div class='panel panel-default'><div class='panel-heading'>" +
|
|
flow_left.class + " (" + key + ")" +
|
|
"</div><div class='panel-body' id=" +
|
|
diff_id +
|
|
"></div></div>");
|
|
|
|
document.getElementById(diff_id).innerHTML =
|
|
jsondiffpatch.formatters.html.format(delta, flow_left);
|
|
node_color_hash[key] = "rgba(255, 0, 0, 0.7)";
|
|
} else {
|
|
node_color_hash[key] = "rgb(212, 248, 212)";
|
|
}
|
|
}
|
|
|
|
update_flow_tree_bgcolor(node.flow_tree, node_color_hash);
|
|
$('#flow-tree').treeview({data: [node.flow_tree], levels: 100});
|
|
});
|
|
}
|
|
|
|
$( document ).ready(function() {
|
|
var upload = document.getElementsByTagName('input')[0];
|
|
upload.onchange = function (e) {
|
|
e.preventDefault();
|
|
|
|
var file = upload.files[0],
|
|
reader = new FileReader();
|
|
reader.onload = function (event) {
|
|
new_data_loaded(JSON.parse(event.target.result));
|
|
};
|
|
|
|
reader.readAsText(file);
|
|
return false;
|
|
};
|
|
|
|
/*
|
|
$.getJSON( "layout_trace.json", function(data) {
|
|
new_data_loaded(data);
|
|
});*/
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|