mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Fix rebase issues and run Prettier on layout viewer code
This commit is contained in:
parent
a042f85083
commit
c4276aa27e
6 changed files with 380 additions and 331 deletions
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue