diff options
author | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2020-02-19 17:18:25 +0100 |
---|---|---|
committer | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2020-02-21 11:11:01 +0100 |
commit | c33a5173870990aa4a91cbf0677f266309305e71 (patch) | |
tree | cc114d3c287335d44dc7f00004f2fd1ed57529e8 /etc | |
parent | f81a2f021e630b6d086a83fc90b917dbef89e888 (diff) | |
download | servo-c33a5173870990aa4a91cbf0677f266309305e71.tar.gz servo-c33a5173870990aa4a91cbf0677f266309305e71.zip |
Keep layout viewer versions for both 2013 and 2020 engines
Diffstat (limited to 'etc')
-rw-r--r-- | etc/layout_viewer/viewer.html | 591 | ||||
-rw-r--r-- | etc/layout_viewer/viewer_2020.html | 339 |
2 files changed, 603 insertions, 327 deletions
diff --git a/etc/layout_viewer/viewer.html b/etc/layout_viewer/viewer.html index 76b85641e38..2deded56f8e 100644 --- a/etc/layout_viewer/viewer.html +++ b/etc/layout_viewer/viewer.html @@ -1,339 +1,276 @@ <!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="container" role="main"> - <div class="row"> - <div class="col-sm-12"> - <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> - </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 - <a - id="box-tree-collapse" - class="tree-collapse" - data-collapsed="0" - ></a> + <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="container" role="main"> + <div class="row"> + <div class="col-sm-12"> + <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> </div> - <div class="panel-body" id="box-tree"></div> - </div> - </div> - <div class="col-sm-12"> - <div id="box-diffs"></div> </div> - </div> - <div class="row"> - <div class="col-sm-12"> - <div class="panel panel-default"> - <div class="panel-heading"> - Fragment Tree - <a - id="fragment-tree-collapse" - class="tree-collapse" - data-collapsed="0" - ></a> + <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'>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 class="panel-body" id="fragment-tree"></div> - </div> </div> - <div class="col-sm-12"> - <div id="fragment-diffs"></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> - - <!-- jQuery --> - <script src="js/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_inner_boxes(box) { - const box_type = Object.keys(box)[0]; - switch (box_type) { - case "BlockLevelBoxes": - return box.BlockLevelBoxes; - case "InlineFormattingContext": - return box.InlineFormattingContext.inline_level_boxes; - case "InlineBox": - return box.InlineBox.children; - case "SameFormattingContextBlock": - case "Independent": - case "Flow": - case "OutOfFlowAbsolutelyPositionedBox": - case "OutOfFlowFloatBox": - case "Atomic": - return box[box_type].contents; - } - 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])); + + <!-- jQuery --> + <script src="js/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(trace_node) { + if (typeof(trace_node.data.base) == "undefined" && typeof(trace_node.data.block_flow) != "undefined") { + return trace_node.data.block_flow.base; + } + else { + return trace_node.data.base; + } + } + + function create_flow_tree(trace_node) { + var base = get_base(trace_node); + + var node = { + text: trace_node.class + " (" + base.id + ")", + id: base.id, + icon: "dummy", + href: "#diff-" + base.id + }; + + var children = []; + for (var i=0 ; i < base.children.length ; ++i) { + children.push(create_flow_tree(base.children[i])); + } + + if (children.length > 0) { + node.nodes = children; + } + + return node; + } + + function create_flow_hash(trace_node, flow_hash) { + var base = get_base(trace_node); + flow_hash[base.id] = trace_node; + + for (var i=0 ; i < base.children.length ; ++i) { + create_flow_hash(base.children[i], flow_hash); + } + + delete base.children; } - } - } else if (inner_boxes != null) { - nodes.push(box_tree_from_container(inner_boxes)); - } else { - if (box_type == "TextRun") { - text += ` (${container.TextRun.text})`; - } - nodes = null; - } - - let info; - if ( - box_type != "BlockLevelBoxes" && - box_type != "InlineFormattingContext" - ) { - info = Object.assign({}, Object.values(container)[0]); - delete info.children; - delete info.contents; - delete info.tag; - } - - return { - text, - nodes, - info - }; - } - - function box_tree_from_bfc(bfc) { - const { contains_floats, contents } = bfc; - let block_container = Object.values(contents)[0]; - return { - text: "BlockFormattingContext", - info: { - contains_floats - }, - nodes: [box_tree_from_container(contents)] - }; - } - - function create_fragment_tree(root) { - let fragment = Object.values(root)[0]; - let node = { - text: Object.keys(root)[0], - id: fragment.debug_id, - href: "#diff-" + fragment.debug_id - }; - - if (fragment.children) { - let children = []; - for (let i = 0; i < fragment.children.length; ++i) { - children.push(create_fragment_tree(fragment.children[i])); - } - - if (children.length > 0) { - node.nodes = children; - } - } - - node.info = Object.assign({}, fragment); - delete node.info.children; - delete node.info.debug_id; - - return node; - } - - function flatten_trace(trace_node) { - const fragment_tree_root = Object.values( - trace_node.fragment_tree.children - )[0]; - return { - fragment_tree: create_fragment_tree(fragment_tree_root), - box_tree: box_tree_from_bfc(trace_node.box_tree) - }; - } - - function create_trace_tree_node(trace_node) { - const trace = flatten_trace(trace_node.pre); - - let tree_node = { - text: trace_node.name, - icon: "dummy", - box_tree: trace.box_tree, - fragment_tree: trace.fragment_tree - }; - - let node = Object.values(trace_node)[0]; - if (node.children) { - let children = []; - for (let i = 0; i < node.children.length; ++i) { - children.push(create_trace_tree_node(node.children[i])); - } - - if (children.length > 0) { - tree_node.nodes = children; - } - } - - return tree_node; - } - - function new_data_loaded(data) { - jsondiffpatch.formatters.html.hideUnchanged(); - - let node_color_hash = {}; - let 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); - - const on_tree_node_selected = tree => (event, data) => { - $(`#${tree}-diffs`).empty(); - if (!data.info) return; - // XXX(ferjm) no diff for now. - const delta = jsondiffpatch - .create({ - objectHash: function(obj) { - return JSON.stringify(obj); + + function flatten_trace(trace_node) { + var flow_tree = create_flow_tree(trace_node.children[0]); + + var flow_hash = {}; + create_flow_hash(trace_node.children[0], flow_hash); + + return { + tree: flow_tree, + flows: flow_hash, + } + } + + function create_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", + 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])); } - }) - .diff({}, data.info); - - const json = jsondiffpatch.formatters.html.format(delta, data.info); - - $(`#${tree}-diffs`).append( - "<div class='panel panel-default'><div class='panel-heading'>" + - data.text + - "</div><div class='panel-body'>" + - json + - "</div></div>" - ); - }; - - const on_fragment_tree_node_selected = on_tree_node_selected( - "fragment" - ); - const on_box_tree_node_selected = on_tree_node_selected("box"); - - $("#fragment-tree").treeview({ - data: [node.fragment_tree], - levels: 100, - enableLinks: false, - emptyIcon: "glyphicon glyphicon-unchecked hidden-glyphicon", - onNodeSelected: on_fragment_tree_node_selected - }); - - $("#box-tree").treeview({ - data: [node.box_tree], - levels: 100, - enableLinks: false, - emptyIcon: "glyphicon glyphicon-unchecked hidden-glyphicon", - onNodeSelected: on_box_tree_node_selected - }); - - ["fragment", "box"].forEach(key => { - const collapsable = $(`#${key}-tree-collapse`); - collapsable.html("Collapse all").on("click", () => { - const collapsed = collapsable.data("collapsed"); - if (collapsed == 0) { - $(`#${key}-tree`).treeview("collapseAll"); - } else { - $(`#${key}-tree`).treeview("expandAll"); - } - collapsable.html(collapsed == 0 ? "Expand all" : "Collapse all"); - collapsable.data("collapsed", collapsed == 0 ? 1 : 0); + + 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(); + $('#trace-tree').treeview(true).revealNode(node); + + 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.id !== undefined) { + return obj.id; + } + if (obj.index !== undefined) { + // FlexItem and FlexLine + return obj.index; + } + 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' id='" + + diff_id + + "'><div class='panel-heading'>" + + flow_left.class + " (" + key + ")" + + "</div><div class='panel-body'></div></div>"); + + document.getElementById(diff_id).getElementsByClassName('panel-body')[0].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, 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(); }); - }); - }); - - $("#trace-tree") - .treeview(true) - .selectNode(0); - } - - $(document).ready(function() { - let upload = document.getElementsByTagName("input")[0]; - upload.onchange = function(e) { - e.preventDefault(); - - let file = upload.files[0], - reader = new FileReader(); - reader.onload = function(event) { - new_data_loaded(JSON.parse(event.target.result)); - }; - - reader.readAsText(file); - return false; - }; - }); - </script> - </body> + </script> + </body> </html> diff --git a/etc/layout_viewer/viewer_2020.html b/etc/layout_viewer/viewer_2020.html new file mode 100644 index 00000000000..76b85641e38 --- /dev/null +++ b/etc/layout_viewer/viewer_2020.html @@ -0,0 +1,339 @@ +<!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="container" role="main"> + <div class="row"> + <div class="col-sm-12"> + <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> + </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 + <a + id="box-tree-collapse" + class="tree-collapse" + data-collapsed="0" + ></a> + </div> + <div class="panel-body" id="box-tree"></div> + </div> + </div> + <div class="col-sm-12"> + <div id="box-diffs"></div> + </div> + </div> + <div class="row"> + <div class="col-sm-12"> + <div class="panel panel-default"> + <div class="panel-heading"> + Fragment Tree + <a + id="fragment-tree-collapse" + class="tree-collapse" + data-collapsed="0" + ></a> + </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> + + <!-- jQuery --> + <script src="js/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_inner_boxes(box) { + const box_type = Object.keys(box)[0]; + switch (box_type) { + case "BlockLevelBoxes": + return box.BlockLevelBoxes; + case "InlineFormattingContext": + return box.InlineFormattingContext.inline_level_boxes; + case "InlineBox": + return box.InlineBox.children; + case "SameFormattingContextBlock": + case "Independent": + case "Flow": + case "OutOfFlowAbsolutelyPositionedBox": + case "OutOfFlowFloatBox": + case "Atomic": + return box[box_type].contents; + } + 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; + } + + let info; + if ( + box_type != "BlockLevelBoxes" && + box_type != "InlineFormattingContext" + ) { + info = Object.assign({}, Object.values(container)[0]); + delete info.children; + delete info.contents; + delete info.tag; + } + + return { + text, + nodes, + info + }; + } + + function box_tree_from_bfc(bfc) { + const { contains_floats, contents } = bfc; + let block_container = Object.values(contents)[0]; + return { + text: "BlockFormattingContext", + info: { + contains_floats + }, + nodes: [box_tree_from_container(contents)] + }; + } + + function create_fragment_tree(root) { + let fragment = Object.values(root)[0]; + let node = { + text: Object.keys(root)[0], + id: fragment.debug_id, + href: "#diff-" + fragment.debug_id + }; + + if (fragment.children) { + let children = []; + for (let i = 0; i < fragment.children.length; ++i) { + children.push(create_fragment_tree(fragment.children[i])); + } + + if (children.length > 0) { + node.nodes = children; + } + } + + node.info = Object.assign({}, fragment); + delete node.info.children; + delete node.info.debug_id; + + return node; + } + + function flatten_trace(trace_node) { + const fragment_tree_root = Object.values( + trace_node.fragment_tree.children + )[0]; + return { + fragment_tree: create_fragment_tree(fragment_tree_root), + box_tree: box_tree_from_bfc(trace_node.box_tree) + }; + } + + function create_trace_tree_node(trace_node) { + const trace = flatten_trace(trace_node.pre); + + let tree_node = { + text: trace_node.name, + icon: "dummy", + box_tree: trace.box_tree, + fragment_tree: trace.fragment_tree + }; + + let node = Object.values(trace_node)[0]; + if (node.children) { + let children = []; + for (let i = 0; i < node.children.length; ++i) { + children.push(create_trace_tree_node(node.children[i])); + } + + if (children.length > 0) { + tree_node.nodes = children; + } + } + + return tree_node; + } + + function new_data_loaded(data) { + jsondiffpatch.formatters.html.hideUnchanged(); + + let node_color_hash = {}; + let 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); + + const on_tree_node_selected = tree => (event, data) => { + $(`#${tree}-diffs`).empty(); + if (!data.info) return; + // XXX(ferjm) no diff for now. + const delta = jsondiffpatch + .create({ + objectHash: function(obj) { + return JSON.stringify(obj); + } + }) + .diff({}, data.info); + + const json = jsondiffpatch.formatters.html.format(delta, data.info); + + $(`#${tree}-diffs`).append( + "<div class='panel panel-default'><div class='panel-heading'>" + + data.text + + "</div><div class='panel-body'>" + + json + + "</div></div>" + ); + }; + + const on_fragment_tree_node_selected = on_tree_node_selected( + "fragment" + ); + const on_box_tree_node_selected = on_tree_node_selected("box"); + + $("#fragment-tree").treeview({ + data: [node.fragment_tree], + levels: 100, + enableLinks: false, + emptyIcon: "glyphicon glyphicon-unchecked hidden-glyphicon", + onNodeSelected: on_fragment_tree_node_selected + }); + + $("#box-tree").treeview({ + data: [node.box_tree], + levels: 100, + enableLinks: false, + emptyIcon: "glyphicon glyphicon-unchecked hidden-glyphicon", + onNodeSelected: on_box_tree_node_selected + }); + + ["fragment", "box"].forEach(key => { + const collapsable = $(`#${key}-tree-collapse`); + collapsable.html("Collapse all").on("click", () => { + const collapsed = collapsable.data("collapsed"); + if (collapsed == 0) { + $(`#${key}-tree`).treeview("collapseAll"); + } else { + $(`#${key}-tree`).treeview("expandAll"); + } + collapsable.html(collapsed == 0 ? "Expand all" : "Collapse all"); + collapsable.data("collapsed", collapsed == 0 ? 1 : 0); + }); + }); + }); + + $("#trace-tree") + .treeview(true) + .selectNode(0); + } + + $(document).ready(function() { + let upload = document.getElementsByTagName("input")[0]; + upload.onchange = function(e) { + e.preventDefault(); + + let file = upload.files[0], + reader = new FileReader(); + reader.onload = function(event) { + new_data_loaded(JSON.parse(event.target.result)); + }; + + reader.readAsText(file); + return false; + }; + }); + </script> + </body> +</html> |