Fix rebase issues and run Prettier on layout viewer code

This commit is contained in:
Fernando Jiménez Moreno 2020-02-17 16:38:23 +01:00
parent a042f85083
commit c4276aa27e
6 changed files with 380 additions and 331 deletions

View file

@ -9,8 +9,7 @@ use crate::flow::float::{FloatBox, FloatContext};
use crate::flow::inline::InlineFormattingContext; use crate::flow::inline::InlineFormattingContext;
use crate::formatting_contexts::{IndependentFormattingContext, IndependentLayout, NonReplacedIFC}; use crate::formatting_contexts::{IndependentFormattingContext, IndependentLayout, NonReplacedIFC};
use crate::fragments::{AnonymousFragment, BoxFragment}; use crate::fragments::{AnonymousFragment, BoxFragment};
use crate::fragments::{CollapsedBlockMargins, CollapsedMargin}; use crate::fragments::{CollapsedBlockMargins, CollapsedMargin, Fragment};
use crate::fragments::{DebugId, Fragment};
use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
use crate::replaced::ReplacedContent; use crate::replaced::ReplacedContent;

View file

@ -5,7 +5,7 @@
use crate::context::LayoutContext; use crate::context::LayoutContext;
use crate::dom_traversal::{Contents, NodeExt}; use crate::dom_traversal::{Contents, NodeExt};
use crate::formatting_contexts::IndependentFormattingContext; use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, DebugId, Fragment}; use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment};
use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::sizing::ContentSizesRequest; use crate::sizing::ContentSizesRequest;
use crate::style_ext::{ComputedValuesExt, DisplayInside}; use crate::style_ext::{ComputedValuesExt, DisplayInside};

View file

@ -166,7 +166,7 @@ impl LayoutRPC for LayoutRPCImpl {
pub fn process_content_box_request( pub fn process_content_box_request(
requested_node: OpaqueNode, requested_node: OpaqueNode,
fragment_tree_root: Option<&FragmentTreeRoot>, fragment_tree_root: Option<Arc<FragmentTreeRoot>>,
) -> Option<Rect<Au>> { ) -> Option<Rect<Au>> {
let fragment_tree_root = match fragment_tree_root { let fragment_tree_root = match fragment_tree_root {
Some(fragment_tree_root) => fragment_tree_root, Some(fragment_tree_root) => fragment_tree_root,
@ -182,7 +182,7 @@ pub fn process_content_boxes_request(_requested_node: OpaqueNode) -> Vec<Rect<Au
pub fn process_node_geometry_request( pub fn process_node_geometry_request(
requested_node: OpaqueNode, requested_node: OpaqueNode,
fragment_tree_root: Option<&FragmentTreeRoot>, fragment_tree_root: Option<Arc<FragmentTreeRoot>>,
) -> Rect<i32> { ) -> Rect<i32> {
let fragment_tree_root = match fragment_tree_root { let fragment_tree_root = match fragment_tree_root {
Some(fragment_tree_root) => fragment_tree_root, Some(fragment_tree_root) => fragment_tree_root,

View file

@ -34,7 +34,7 @@ pub(crate) struct ReplacedContent {
/// ///
/// * For SVG, see https://svgwg.org/svg2-draft/coords.html#SizingSVGInCSS /// * For SVG, see https://svgwg.org/svg2-draft/coords.html#SizingSVGInCSS
/// and again https://github.com/w3c/csswg-drafts/issues/4572. /// and again https://github.com/w3c/csswg-drafts/issues/4572.
#[derive(Debug)] #[derive(Debug, Serialize)]
pub(crate) struct IntrinsicSizes { pub(crate) struct IntrinsicSizes {
pub width: Option<Length>, pub width: Option<Length>,
pub height: Option<Length>, pub height: Option<Length>,

View file

@ -874,8 +874,8 @@ impl LayoutThread {
self.dump_style_tree, self.dump_style_tree,
self.dump_rule_tree, self.dump_rule_tree,
self.relayout_event, self.relayout_event,
true, // nonincremental_layout true, // nonincremental_layout
self.trace_layout, // trace_layout self.trace_layout, // trace_layout
self.dump_flow_tree, // dump_flow_tree self.dump_flow_tree, // dump_flow_tree
); );
} }
@ -1235,10 +1235,8 @@ impl LayoutThread {
match *reflow_goal { match *reflow_goal {
ReflowGoal::LayoutQuery(ref querymsg, _) => match querymsg { ReflowGoal::LayoutQuery(ref querymsg, _) => match querymsg {
&QueryMsg::ContentBoxQuery(node) => { &QueryMsg::ContentBoxQuery(node) => {
rw_data.content_box_response = process_content_box_request( rw_data.content_box_response =
node, process_content_box_request(node, self.fragment_tree_root.borrow().clone());
(&*self.fragment_tree_root.borrow()).as_ref(),
);
}, },
&QueryMsg::ContentBoxesQuery(node) => { &QueryMsg::ContentBoxesQuery(node) => {
rw_data.content_boxes_response = process_content_boxes_request(node); rw_data.content_boxes_response = process_content_boxes_request(node);
@ -1253,7 +1251,7 @@ impl LayoutThread {
&QueryMsg::ClientRectQuery(node) => { &QueryMsg::ClientRectQuery(node) => {
rw_data.client_rect_response = process_node_geometry_request( rw_data.client_rect_response = process_node_geometry_request(
node, node,
(&*self.fragment_tree_root.borrow()).as_ref(), self.fragment_tree_root.borrow().clone(),
); );
}, },
&QueryMsg::NodeScrollGeometryQuery(node) => { &QueryMsg::NodeScrollGeometryQuery(node) => {

View file

@ -1,345 +1,397 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Servo Layout Debugger</title> <title>Servo Layout Debugger</title>
<!-- Bootstrap --> <!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet"> <link href="css/bootstrap.min.css" rel="stylesheet" />
<!-- Treeview --> <!-- Treeview -->
<link href="css/bootstrap-treeview.min.css" rel="stylesheet"> <link href="css/bootstrap-treeview.min.css" rel="stylesheet" />
<!-- JSDiffPatch --> <!-- JSDiffPatch -->
<link href="css/formatters/html.css" rel="stylesheet"> <link href="css/formatters/html.css" rel="stylesheet" />
<!-- Custom --> <!-- Custom -->
<link href="css/main.css" rel="stylesheet"> <link href="css/main.css" rel="stylesheet" />
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <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> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]--> <![endif]-->
</head> </head>
<body> <body>
<div class="container" role="main"> <div class="container" role="main">
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<h1> Servo Layout Viewer </h1> <h1>Servo Layout Viewer</h1>
<p> Check the <a href="https://github.com/servo/servo/blob/master/etc/layout_viewer/README.md">README</a> for instructions.</p> <p>
</div> Check the
</div> <a
<div class="row"> href="https://github.com/servo/servo/blob/master/etc/layout_viewer/README.md"
<div class="col-sm-4"> >README</a
<div class="row"> >
<div class="col-sm-12"> for instructions.
<div class="well"> </p>
<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-8">
<div class="row">
<div class="col-sm-12">
<div class='panel panel-default'>
<div class='panel-heading'>Box Tree</div>
<div class='panel-body' id="box-tree"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class='panel panel-default'>
<div class='panel-heading'>Fragment Tree</div>
<div class='panel-body' id="fragment-tree"></div>
</div>
</div>
<div class="col-sm-12">
<div id="fragment-diffs"></div>
</div>
</div>
</div>
</div>
<div id="toolbar">
<a href="#" id="prev_trace">< Prev step</a>
|
<a href="#" id="next_trace">Next step ></a>
<br>
<input type="checkbox" name="show_unchanged" id="show_unchanged" />
<label for="show_unchanged">Show unchanged code</label>
<br>
<a href="#top">Back to top</a>
</div>
</div> </div>
</div>
<div class="row">
<div class="col-sm-4">
<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-8">
<div class="row">
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Box Tree</div>
<div class="panel-body" id="box-tree"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Fragment Tree</div>
<div class="panel-body" id="fragment-tree"></div>
</div>
</div>
<div class="col-sm-12">
<div id="fragment-diffs"></div>
</div>
</div>
</div>
</div>
<div id="toolbar">
<a href="#" id="prev_trace">< Prev step</a>
|
<a href="#" id="next_trace">Next step ></a>
<br />
<input type="checkbox" name="show_unchanged" id="show_unchanged" />
<label for="show_unchanged">Show unchanged code</label>
<br />
<a href="#top">Back to top</a>
</div>
</div>
<!-- jQuery --> <!-- jQuery -->
<script src="js/jquery.min.js"></script> <script src="js/jquery.min.js"></script>
<!-- Bootstrap --> <!-- Bootstrap -->
<script src="js/bootstrap.min.js"></script> <script src="js/bootstrap.min.js"></script>
<!-- Treeview --> <!-- Treeview -->
<script src="js/bootstrap-treeview.min.js"></script> <script src="js/bootstrap-treeview.min.js"></script>
<!-- JSDiffPatch --> <!-- JSDiffPatch -->
<script src="js/bundle.min.js"></script> <script src="js/bundle.min.js"></script>
<script src="js/formatters.min.js"></script> <script src="js/formatters.min.js"></script>
<script> <script>
function get_inner_boxes(box) { function get_inner_boxes(box) {
const box_type = Object.keys(box)[0]; const box_type = Object.keys(box)[0];
switch (box_type) { switch (box_type) {
case "BlockLevelBoxes": case "BlockLevelBoxes":
return box.BlockLevelBoxes; return box.BlockLevelBoxes;
case "InlineFormattingContext": case "InlineFormattingContext":
return box.InlineFormattingContext.inline_level_boxes; return box.InlineFormattingContext.inline_level_boxes;
case "InlineBox": case "InlineBox":
return box.InlineBox.children; return box.InlineBox.children;
case "SameFormattingContextBlock": case "SameFormattingContextBlock":
case "Independent": case "Independent":
case "Flow": case "Flow":
case "OutOfFlowAbsolutelyPositionedBox": case "OutOfFlowAbsolutelyPositionedBox":
case "OutOfFlowFloatBox": case "OutOfFlowFloatBox":
case "Atomic": case "Atomic":
return box[box_type].contents; return box[box_type].contents;
} }
return null; return null;
}
function box_tree_from_container(container) {
const box_type = Object.keys(container)[0];
let inner_boxes = get_inner_boxes(container);
let nodes = [];
let text = box_type;
if (Array.isArray(inner_boxes)) {
if (!inner_boxes.length) {
nodes = null;
} else {
for (let box in inner_boxes) {
nodes.push(box_tree_from_container(inner_boxes[box]));
} }
}
} else if (inner_boxes != null) {
nodes.push(box_tree_from_container(inner_boxes));
} else {
if (box_type == "TextRun") {
text += ` (${container.TextRun.text})`;
}
nodes = null;
}
return {
text,
nodes
};
}
function box_tree_from_container(container) { function box_tree_from_bfc(bfc) {
const box_type = Object.keys(container)[0]; const { contains_floats, contents } = bfc;
let inner_boxes = get_inner_boxes(container); var block_container = Object.values(contents)[0];
let nodes = []; return {
let text = box_type; text: "BlockFormattingContext",
if (Array.isArray(inner_boxes)) { info: {
if (!inner_boxes.length) { contains_floats
nodes = null; },
} else { nodes: [box_tree_from_container(contents)]
for (let box in inner_boxes) { };
nodes.push(box_tree_from_container(inner_boxes[box])); }
}
function create_fragment_tree(root) {
var fragment = Object.values(root)[0];
var node = {
text: Object.keys(root)[0],
id: fragment.debug_id,
icon: "dummy",
href: "#diff-" + fragment.debug_id
};
if (fragment.children) {
var children = [];
for (var i = 0; i < fragment.children.length; ++i) {
children.push(create_fragment_tree(fragment.children[i]));
}
if (children.length > 0) {
node.nodes = children;
}
}
return node;
}
function get_fragments_info(node, fragments_info) {
const fragmentType = Object.keys(node)[0];
const trace_node = Object.assign({}, Object.values(node)[0]);
let data = Object.assign({}, trace_node);
delete data.children;
delete data.debug_id;
fragments_info[trace_node.debug_id] = {
class: fragmentType,
data
};
if (trace_node.children) {
for (var i = 0; i < trace_node.children.length; ++i) {
get_fragments_info(trace_node.children[i], fragments_info);
}
}
}
function flatten_trace(trace_node) {
const fragment_tree_root = Object.values(trace_node.fragment_tree.children)[0];
var fragments_info = {};
get_fragments_info(fragment_tree_root, fragments_info);
return {
fragment_tree: create_fragment_tree(fragment_tree_root),
box_tree: box_tree_from_bfc(trace_node.box_tree),
fragments_info
};
}
function create_trace_tree_node(trace_node) {
var pre_trace = flatten_trace(trace_node.pre);
var post_trace = flatten_trace(trace_node.post);
var tree_node = {
text: trace_node.name,
icon: "dummy",
box_tree: pre_trace.box_tree,
fragment_tree: pre_trace.fragment_tree,
pre_boxes_info: pre_trace.boxes_info,
post_boxes_info: post_trace.boxes_info,
pre_fragments_info: pre_trace.fragments_info,
post_fragments_info: post_trace.fragments_info
};
var trace_node = Object.values(trace_node)[0];
if (trace_node.children) {
var children = [];
for (var i = 0; i < trace_node.children.length; ++i) {
children.push(create_trace_tree_node(trace_node.children[i]));
}
if (children.length > 0) {
tree_node.nodes = children;
}
}
return tree_node;
}
function update_fragment_tree_bgcolor(
fragment_tree_node,
node_color_hash
) {
fragment_tree_node.backColor =
node_color_hash[fragment_tree_node.debug_id];
if (fragment_tree_node.nodes !== undefined) {
for (var i = 0; i < fragment_tree_node.nodes.length; ++i) {
update_fragment_tree_bgcolor(
fragment_tree_node.nodes[i],
node_color_hash
);
}
}
}
function new_data_loaded(data) {
jsondiffpatch.formatters.html.hideUnchanged();
var node_color_hash = {};
var tree = [create_trace_tree_node(data)];
$("#trace-tree").treeview({ data: tree, levels: 3 });
$("#trace-tree").on("nodeSelected", function(event, node) {
$("#fragment-diffs").empty();
$("#trace-tree")
.treeview(true)
.revealNode(node);
for (var key in node.pre_fragments_info) {
var fragment_info_left = node.pre_fragments_info[key];
var fragment_info_right = node.post_fragments_info[key];
var delta = jsondiffpatch
.create({
objectHash: function(obj) {
return JSON.stringify(obj);
} }
} else if (inner_boxes != null) { })
nodes.push(box_tree_from_container(inner_boxes)); .diff(fragment_info_left, fragment_info_right);
} else {
if (box_type == "TextRun") {
text += ` (${container.TextRun.text})`;
}
nodes = null;
}
return {
text,
nodes,
}
}
function box_tree_from_bfc(bfc) { if (!delta) {
const { contains_floats, contents } = bfc; delta = jsondiffpatch
var block_container = Object.values(contents)[0]; .create({
return { objectHash: function(obj) {
text: "BlockFormattingContext", return JSON.stringify(obj);
info: {
contains_floats,
},
nodes: [box_tree_from_container(contents)]
};
}
function create_fragment_tree(root) {
var fragment = Object.values(root)[0];
var node = {
text: Object.keys(root)[0],
id: fragment.debug_id,
icon: "dummy",
href: "#diff-" + fragment.debug_id
};
if (fragment.children) {
var children = [];
for (var i=0 ; i < fragment.children.length ; ++i) {
children.push(create_fragment_tree(fragment.children[i]));
} }
})
if (children.length > 0) { .diff({}, fragment_info_right);
node.nodes = children;
}
}
return node;
} }
function get_fragments_info(node, fragments_info) { if (delta !== undefined) {
const fragmentType = Object.keys(node)[0]; var diff_id = "diff-" + key;
const trace_node = Object.assign({}, Object.values(node)[0]); $("#fragment-diffs").append(
let data = Object.assign({}, trace_node); "<div class='panel panel-default' id='" +
delete data.children; diff_id +
delete data.debug_id; "'><div class='panel-heading'>" +
fragments_info[trace_node.debug_id] = { fragment_info_left.class +
class: fragmentType, " (" +
data, key +
}; ")" +
"</div><div class='panel-body'></div></div>"
);
if (trace_node.children) { document
for (var i=0 ; i < trace_node.children.length ; ++i) { .getElementById(diff_id)
get_fragments_info(trace_node.children[i], fragments_info); .getElementsByClassName(
} "panel-body"
} )[0].innerHTML = jsondiffpatch.formatters.html.format(
delta,
fragment_info_left
);
node_color_hash[key] = "rgba(255, 0, 0, 0.7)";
} else {
node_color_hash[key] = "rgb(212, 248, 212)";
} }
}
function flatten_trace(trace_node) { update_fragment_tree_bgcolor(node.fragment_tree, node_color_hash);
const fragment_tree_root = Object.values(trace_node.fragment_tree)[0]; $("#fragment-tree").treeview({
var fragments_info = {}; data: [node.fragment_tree],
get_fragments_info(fragment_tree_root, fragments_info); levels: 100,
return { enableLinks: true,
fragment_tree: create_fragment_tree(fragment_tree_root), emptyIcon: "glyphicon glyphicon-unchecked hidden-glyphicon"
box_tree: box_tree_from_bfc(trace_node.box_tree), });
fragments_info, $("#box-tree").treeview({
}; data: [node.box_tree],
} levels: 100,
enableLinks: true,
emptyIcon: "glyphicon glyphicon-unchecked hidden-glyphicon"
});
});
function create_trace_tree_node(trace_node) { $("#trace-tree")
var pre_trace = flatten_trace(trace_node.pre); .treeview(true)
var post_trace = flatten_trace(trace_node.post); .selectNode(0);
}
var tree_node = { function register_toggle_unchanaged_code_handler() {
text: trace_node.name, var show_unchange_box = document.getElementById("show_unchanged");
icon: "dummy", show_unchange_box.addEventListener("change", function(evt) {
box_tree: pre_trace.box_tree, jsondiffpatch.formatters.html.showUnchanged(
fragment_tree: pre_trace.fragment_tree, show_unchange_box.checked,
pre_boxes_info: pre_trace.boxes_info, null,
post_boxes_info: post_trace.boxes_info, 800
pre_fragments_info: pre_trace.fragments_info, );
post_fragments_info: post_trace.fragments_info, });
}; }
var trace_node = Object.values(trace_node)[0]; function register_prev_next_trace_node() {
if (trace_node.children) { var prev_btn = document.getElementById("prev_trace");
var children = []; var next_btn = document.getElementById("next_trace");
for (var i=0 ; i < trace_node.children.length ; ++i) { prev_btn.addEventListener("click", function(evt) {
children.push(create_trace_tree_node(trace_node.children[i])); var node_id = $("#trace-tree")
} .treeview(true)
.getSelected()[0].nodeId;
// We deliberatly choose to ignore the node_id out of bound case,
// since it won't break the UI usability
$("#trace-tree")
.treeview(true)
.selectNode(node_id - 1);
});
next_btn.addEventListener("click", function(evt) {
var node_id = $("#trace-tree")
.treeview(true)
.getSelected()[0].nodeId;
$("#trace-tree")
.treeview(true)
.selectNode(node_id + 1);
});
}
if (children.length > 0) { $(document).ready(function() {
tree_node.nodes = children; var upload = document.getElementsByTagName("input")[0];
} upload.onchange = function(e) {
} e.preventDefault();
return tree_node; var file = upload.files[0],
} reader = new FileReader();
reader.onload = function(event) {
new_data_loaded(JSON.parse(event.target.result));
};
function update_fragment_tree_bgcolor(fragment_tree_node, node_color_hash) { reader.readAsText(file);
fragment_tree_node.backColor = node_color_hash[fragment_tree_node.debug_id]; return false;
if (fragment_tree_node.nodes !== undefined) { };
for (var i=0 ; i < fragment_tree_node.nodes.length ; ++i) { register_toggle_unchanaged_code_handler();
update_fragment_tree_bgcolor(fragment_tree_node.nodes[i], node_color_hash) register_prev_next_trace_node();
} });
} </script>
} </body>
function new_data_loaded(data) {
jsondiffpatch.formatters.html.hideUnchanged();
var node_color_hash = {};
var tree = [ create_trace_tree_node(data) ];
$('#trace-tree').treeview({data: tree, levels: 3});
$('#trace-tree').on('nodeSelected', function(event, node) {
$("#fragment-diffs").empty();
$('#trace-tree').treeview(true).revealNode(node);
for (var key in node.pre_fragments_info) {
var fragment_info_left = node.pre_fragments_info[key];
var fragment_info_right = node.post_fragments_info[key];
var delta = jsondiffpatch.create({
objectHash: function(obj) {
return JSON.stringify(obj);
}
}).diff(fragment_info_left, fragment_info_right);
if (!delta) {
delta = jsondiffpatch.create({
objectHash: function(obj) {
return JSON.stringify(obj);
}
}).diff({}, fragment_info_right);
}
if (delta !== undefined) {
var diff_id = "diff-" + key;
$("#fragment-diffs").append(
"<div class='panel panel-default' id='" +
diff_id +
"'><div class='panel-heading'>" +
fragment_info_left.class + " (" + key + ")" +
"</div><div class='panel-body'></div></div>");
document.getElementById(diff_id).getElementsByClassName('panel-body')[0].innerHTML =
jsondiffpatch.formatters.html.format(delta, fragment_info_left);
node_color_hash[key] = "rgba(255, 0, 0, 0.7)";
} else {
node_color_hash[key] = "rgb(212, 248, 212)";
}
}
update_fragment_tree_bgcolor(node.fragment_tree, node_color_hash);
$('#fragment-tree').treeview({data: [node.fragment_tree], levels: 100, enableLinks: true, emptyIcon: "glyphicon glyphicon-unchecked hidden-glyphicon"});
$('#box-tree').treeview({data: [node.box_tree], levels: 100, enableLinks: true, emptyIcon: "glyphicon glyphicon-unchecked hidden-glyphicon"});
});
$('#trace-tree').treeview(true).selectNode(0);
}
function register_toggle_unchanaged_code_handler() {
var show_unchange_box = document.getElementById("show_unchanged");
show_unchange_box.addEventListener("change", function(evt){
jsondiffpatch.formatters.html.showUnchanged(show_unchange_box.checked, null, 800);
});
}
function register_prev_next_trace_node() {
var prev_btn = document.getElementById("prev_trace");
var next_btn = document.getElementById("next_trace");
prev_btn.addEventListener("click", function(evt){
var node_id = $("#trace-tree").treeview(true).getSelected()[0].nodeId;
// We deliberatly choose to ignore the node_id out of bound case,
// since it won't break the UI usability
$("#trace-tree").treeview(true).selectNode(node_id - 1);
});
next_btn.addEventListener("click", function(evt){
var node_id = $("#trace-tree").treeview(true).getSelected()[0].nodeId;
$("#trace-tree").treeview(true).selectNode(node_id + 1);
});
}
$( 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;
};
register_toggle_unchanaged_code_handler();
register_prev_next_trace_node();
});
</script>
</body>
</html> </html>