mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Add fragment debug id
This commit is contained in:
parent
84dd334160
commit
67706f9c0b
7 changed files with 90 additions and 38 deletions
|
@ -7,7 +7,7 @@ use crate::flow::float::FloatBox;
|
||||||
use crate::flow::FlowLayout;
|
use crate::flow::FlowLayout;
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragments::CollapsedBlockMargins;
|
use crate::fragments::CollapsedBlockMargins;
|
||||||
use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment};
|
use crate::fragments::{AnonymousFragment, BoxFragment, DebugId, Fragment, TextFragment};
|
||||||
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
||||||
use crate::positioned::{relative_adjustement, AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{relative_adjustement, AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::sizing::ContentSizes;
|
use crate::sizing::ContentSizes;
|
||||||
|
@ -713,6 +713,7 @@ impl TextRun {
|
||||||
.fragments_so_far
|
.fragments_so_far
|
||||||
.push(Fragment::Text(TextFragment {
|
.push(Fragment::Text(TextFragment {
|
||||||
tag: self.tag,
|
tag: self.tag,
|
||||||
|
debug_id: DebugId::new(),
|
||||||
parent_style: self.parent_style.clone(),
|
parent_style: self.parent_style.clone(),
|
||||||
rect,
|
rect,
|
||||||
ascent: font_ascent.into(),
|
ascent: font_ascent.into(),
|
||||||
|
|
|
@ -8,8 +8,9 @@ use crate::context::LayoutContext;
|
||||||
use crate::flow::float::{FloatBox, FloatContext};
|
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, Fragment};
|
use crate::fragments::{AnonymousFragment, BoxFragment};
|
||||||
use crate::fragments::{CollapsedBlockMargins, CollapsedMargin};
|
use crate::fragments::{CollapsedBlockMargins, CollapsedMargin};
|
||||||
|
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;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
||||||
use crate::geom::{PhysicalPoint, PhysicalRect};
|
use crate::geom::{PhysicalPoint, PhysicalRect};
|
||||||
|
use crate::layout_debug;
|
||||||
use gfx::text::glyph::GlyphStore;
|
use gfx::text::glyph::GlyphStore;
|
||||||
use gfx_traits::print_tree::PrintTree;
|
use gfx_traits::print_tree::PrintTree;
|
||||||
use serde::ser::{Serialize, SerializeStruct, Serializer};
|
use serde::ser::{Serialize, SerializeStruct, Serializer};
|
||||||
|
@ -27,6 +28,7 @@ pub(crate) enum Fragment {
|
||||||
|
|
||||||
pub(crate) struct BoxFragment {
|
pub(crate) struct BoxFragment {
|
||||||
pub tag: OpaqueNode,
|
pub tag: OpaqueNode,
|
||||||
|
pub debug_id: DebugId,
|
||||||
pub style: ServoArc<ComputedValues>,
|
pub style: ServoArc<ComputedValues>,
|
||||||
pub children: Vec<Fragment>,
|
pub children: Vec<Fragment>,
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ pub(crate) struct CollapsedMargin {
|
||||||
/// Can contain child fragments with relative coordinates, but does not contribute to painting itself.
|
/// Can contain child fragments with relative coordinates, but does not contribute to painting itself.
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub(crate) struct AnonymousFragment {
|
pub(crate) struct AnonymousFragment {
|
||||||
|
pub debug_id: DebugId,
|
||||||
pub rect: Rect<Length>,
|
pub rect: Rect<Length>,
|
||||||
pub children: Vec<Fragment>,
|
pub children: Vec<Fragment>,
|
||||||
pub mode: WritingMode,
|
pub mode: WritingMode,
|
||||||
|
@ -70,6 +73,7 @@ pub(crate) struct AnonymousFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct TextFragment {
|
pub(crate) struct TextFragment {
|
||||||
|
pub debug_id: DebugId,
|
||||||
pub tag: OpaqueNode,
|
pub tag: OpaqueNode,
|
||||||
pub parent_style: ServoArc<ComputedValues>,
|
pub parent_style: ServoArc<ComputedValues>,
|
||||||
pub rect: Rect<Length>,
|
pub rect: Rect<Length>,
|
||||||
|
@ -79,6 +83,7 @@ pub(crate) struct TextFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct ImageFragment {
|
pub(crate) struct ImageFragment {
|
||||||
|
pub debug_id: DebugId,
|
||||||
pub style: ServoArc<ComputedValues>,
|
pub style: ServoArc<ComputedValues>,
|
||||||
pub rect: Rect<Length>,
|
pub rect: Rect<Length>,
|
||||||
pub image_key: ImageKey,
|
pub image_key: ImageKey,
|
||||||
|
@ -123,6 +128,7 @@ impl Fragment {
|
||||||
impl AnonymousFragment {
|
impl AnonymousFragment {
|
||||||
pub fn no_op(mode: WritingMode) -> Self {
|
pub fn no_op(mode: WritingMode) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
debug_id: DebugId::new(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
rect: Rect::zero(),
|
rect: Rect::zero(),
|
||||||
mode,
|
mode,
|
||||||
|
@ -140,6 +146,7 @@ impl AnonymousFragment {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
AnonymousFragment {
|
AnonymousFragment {
|
||||||
|
debug_id: DebugId::new(),
|
||||||
rect,
|
rect,
|
||||||
children,
|
children,
|
||||||
mode,
|
mode,
|
||||||
|
@ -179,6 +186,7 @@ impl BoxFragment {
|
||||||
});
|
});
|
||||||
BoxFragment {
|
BoxFragment {
|
||||||
tag,
|
tag,
|
||||||
|
debug_id: DebugId::new(),
|
||||||
style,
|
style,
|
||||||
children,
|
children,
|
||||||
content_rect,
|
content_rect,
|
||||||
|
@ -349,7 +357,8 @@ impl CollapsedMargin {
|
||||||
|
|
||||||
impl Serialize for BoxFragment {
|
impl Serialize for BoxFragment {
|
||||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
let mut serializer = serializer.serialize_struct("BoxFragment", 6)?;
|
let mut serializer = serializer.serialize_struct("BoxFragment", 7)?;
|
||||||
|
serializer.serialize_field("debug_id", &self.debug_id)?;
|
||||||
serializer.serialize_field("content_rect", &self.content_rect)?;
|
serializer.serialize_field("content_rect", &self.content_rect)?;
|
||||||
serializer.serialize_field("padding", &self.padding)?;
|
serializer.serialize_field("padding", &self.padding)?;
|
||||||
serializer.serialize_field("border", &self.border)?;
|
serializer.serialize_field("border", &self.border)?;
|
||||||
|
@ -365,7 +374,8 @@ impl Serialize for BoxFragment {
|
||||||
|
|
||||||
impl Serialize for TextFragment {
|
impl Serialize for TextFragment {
|
||||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
let mut serializer = serializer.serialize_struct("TextFragment", 3)?;
|
let mut serializer = serializer.serialize_struct("TextFragment", 4)?;
|
||||||
|
serializer.serialize_field("debug_id", &self.debug_id)?;
|
||||||
serializer.serialize_field("rect", &self.rect)?;
|
serializer.serialize_field("rect", &self.rect)?;
|
||||||
serializer.serialize_field("ascent", &self.ascent)?;
|
serializer.serialize_field("ascent", &self.ascent)?;
|
||||||
serializer.serialize_field("glyphs", &self.glyphs)?;
|
serializer.serialize_field("glyphs", &self.glyphs)?;
|
||||||
|
@ -375,8 +385,45 @@ impl Serialize for TextFragment {
|
||||||
|
|
||||||
impl Serialize for ImageFragment {
|
impl Serialize for ImageFragment {
|
||||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
let mut serializer = serializer.serialize_struct("ImageFragment", 1)?;
|
let mut serializer = serializer.serialize_struct("ImageFragment", 2)?;
|
||||||
|
serializer.serialize_field("debug_id", &self.debug_id)?;
|
||||||
serializer.serialize_field("rect", &self.rect)?;
|
serializer.serialize_field("rect", &self.rect)?;
|
||||||
serializer.end()
|
serializer.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct DebugId;
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct DebugId(u16);
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
impl DebugId {
|
||||||
|
pub fn new() -> DebugId {
|
||||||
|
DebugId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
impl DebugId {
|
||||||
|
pub fn new() -> DebugId {
|
||||||
|
DebugId(layout_debug::generate_unique_debug_id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
impl Serialize for DebugId {
|
||||||
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
|
serializer.serialize_str(&format!("{:p}", &self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
impl Serialize for DebugId {
|
||||||
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
|
serializer.serialize_u16(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,10 +10,15 @@ use serde_json::{to_string, to_value, Value};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None));
|
thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None));
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
static DEBUG_ID_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
pub struct Scope;
|
pub struct Scope;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -80,6 +85,12 @@ impl Drop for Scope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate a unique ID for Fragments.
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
pub fn generate_unique_debug_id() -> u16 {
|
||||||
|
DEBUG_ID_COUNTER.fetch_add(1, Ordering::SeqCst) as u16
|
||||||
|
}
|
||||||
|
|
||||||
/// Begin a layout debug trace. If this has not been called,
|
/// Begin a layout debug trace. If this has not been called,
|
||||||
/// creating debug scopes has no effect.
|
/// creating debug scopes has no effect.
|
||||||
pub fn begin_trace(root: Arc<FragmentTreeRoot>) {
|
pub fn begin_trace(root: Arc<FragmentTreeRoot>) {
|
||||||
|
|
|
@ -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, Fragment};
|
use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, DebugId, 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};
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::dom_traversal::NodeExt;
|
use crate::dom_traversal::NodeExt;
|
||||||
use crate::fragments::{Fragment, ImageFragment};
|
use crate::fragments::{DebugId, Fragment, ImageFragment};
|
||||||
use crate::geom::flow_relative::{Rect, Vec2};
|
use crate::geom::flow_relative::{Rect, Vec2};
|
||||||
use crate::geom::PhysicalSize;
|
use crate::geom::PhysicalSize;
|
||||||
use crate::sizing::ContentSizes;
|
use crate::sizing::ContentSizes;
|
||||||
|
@ -113,6 +113,7 @@ impl ReplacedContent {
|
||||||
.and_then(|image| image.id)
|
.and_then(|image| image.id)
|
||||||
.map(|image_key| {
|
.map(|image_key| {
|
||||||
Fragment::Image(ImageFragment {
|
Fragment::Image(ImageFragment {
|
||||||
|
debug_id: DebugId::new(),
|
||||||
style: style.clone(),
|
style: style.clone(),
|
||||||
rect: Rect {
|
rect: Rect {
|
||||||
start_corner: Vec2::zero(),
|
start_corner: Vec2::zero(),
|
||||||
|
|
|
@ -57,8 +57,8 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class='panel panel-default'>
|
<div class='panel panel-default'>
|
||||||
<div class='panel-heading'>Flow Tree</div>
|
<div class='panel-heading'>Fragment Tree</div>
|
||||||
<div class='panel-body' id="flow-tree"></div>
|
<div class='panel-body' id="fragment-tree"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
|
@ -90,28 +90,19 @@
|
||||||
<script src="js/formatters.min.js"></script>
|
<script src="js/formatters.min.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function get_base(trace_node) {
|
function create_fragment_tree(trace_node) {
|
||||||
if (typeof(trace_node.data.base) == "undefined" && typeof(trace_node.data.block_flow) != "undefined") {
|
var fragment = Object.values(trace_node)[0];
|
||||||
return trace_node.data.block_flow.base;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return trace_node.data.base;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function create_flow_tree(trace_node) {
|
|
||||||
var node = {
|
var node = {
|
||||||
text: Object.keys(trace_node)[0],
|
text: Object.keys(trace_node)[0],
|
||||||
// id: base.id,
|
id: fragment.id,
|
||||||
// icon: "dummy",
|
icon: "dummy",
|
||||||
// href: "#diff-" + base.id
|
href: "#diff-" + fragment.id
|
||||||
};
|
};
|
||||||
|
|
||||||
var fragment = Object.values(trace_node)[0];
|
|
||||||
if (fragment.children) {
|
if (fragment.children) {
|
||||||
var children = [];
|
var children = [];
|
||||||
for (var i=0 ; i < fragment.children.length ; ++i) {
|
for (var i=0 ; i < fragment.children.length ; ++i) {
|
||||||
children.push(create_flow_tree(fragment.children[i]));
|
children.push(create_fragment_tree(fragment.children[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
|
@ -134,25 +125,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function flatten_trace(trace_node) {
|
function flatten_trace(trace_node) {
|
||||||
var flow_tree = create_flow_tree(Object.values(trace_node)[0]);
|
var fragment_tree = create_fragment_tree(Object.values(trace_node)[0]);
|
||||||
|
|
||||||
//var flow_hash = {};
|
//var flow_hash = {};
|
||||||
//create_flow_hash(trace_node[0], flow_hash);
|
//create_flow_hash(trace_node[0], flow_hash);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tree: flow_tree,
|
tree: fragment_tree,
|
||||||
//flows: flow_hash,
|
//flows: flow_hash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function create_tree_node(trace_node) {
|
function create_trace_tree_node(trace_node) {
|
||||||
var pre_trace = flatten_trace(trace_node.pre);
|
var pre_trace = flatten_trace(trace_node.pre);
|
||||||
var post_trace = flatten_trace(trace_node.post);
|
var post_trace = flatten_trace(trace_node.post);
|
||||||
|
|
||||||
var tree_node = {
|
var tree_node = {
|
||||||
text: Object.keys(trace_node)[0],
|
text: trace_node.name,
|
||||||
icon: "dummy",
|
icon: "dummy",
|
||||||
flow_tree: pre_trace.tree, // assume pre/post trace always have same tree!
|
fragment_tree: pre_trace.tree, // assume pre/post trace always have same tree!
|
||||||
//pre: pre_trace.flows,
|
//pre: pre_trace.flows,
|
||||||
//post: post_trace.flows,
|
//post: post_trace.flows,
|
||||||
};
|
};
|
||||||
|
@ -161,7 +152,7 @@
|
||||||
if (trace_node.children) {
|
if (trace_node.children) {
|
||||||
var children = [];
|
var children = [];
|
||||||
for (var i=0 ; i < trace_node.children.length ; ++i) {
|
for (var i=0 ; i < trace_node.children.length ; ++i) {
|
||||||
children.push(create_tree_node(trace_node.children[i]));
|
children.push(create_trace_tree_node(trace_node.children[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
|
@ -172,11 +163,11 @@
|
||||||
return tree_node;
|
return tree_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_flow_tree_bgcolor(flow_tree_node, node_color_hash) {
|
function update_fragment_tree_bgcolor(fragment_tree_node, node_color_hash) {
|
||||||
flow_tree_node.backColor = node_color_hash[flow_tree_node.id];
|
fragment_tree_node.backColor = node_color_hash[fragment_tree_node.id];
|
||||||
if (flow_tree_node.nodes !== undefined) {
|
if (fragment_tree_node.nodes !== undefined) {
|
||||||
for (var i=0 ; i < flow_tree_node.nodes.length ; ++i) {
|
for (var i=0 ; i < fragment_tree_node.nodes.length ; ++i) {
|
||||||
update_flow_tree_bgcolor(flow_tree_node.nodes[i], node_color_hash)
|
update_fragment_tree_bgcolor(fragment_tree_node.nodes[i], node_color_hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +176,7 @@
|
||||||
jsondiffpatch.formatters.html.hideUnchanged();
|
jsondiffpatch.formatters.html.hideUnchanged();
|
||||||
|
|
||||||
var node_color_hash = {};
|
var node_color_hash = {};
|
||||||
var tree = [ create_tree_node(data) ];
|
var tree = [ create_trace_tree_node(data) ];
|
||||||
$('#trace-tree').treeview({data: tree, levels: 3});
|
$('#trace-tree').treeview({data: tree, levels: 3});
|
||||||
$('#trace-tree').on('nodeSelected', function(event, node) {
|
$('#trace-tree').on('nodeSelected', function(event, node) {
|
||||||
$("#flow-diffs").empty();
|
$("#flow-diffs").empty();
|
||||||
|
@ -228,8 +219,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update_flow_tree_bgcolor(node.flow_tree, node_color_hash);
|
update_fragment_tree_bgcolor(node.fragment_tree, node_color_hash);
|
||||||
$('#flow-tree').treeview({data: [node.flow_tree], levels: 100, enableLinks: true, emptyIcon: "glyphicon glyphicon-unchecked hidden-glyphicon"});
|
$('#fragment-tree').treeview({data: [node.fragment_tree], levels: 100, enableLinks: true, emptyIcon: "glyphicon glyphicon-unchecked hidden-glyphicon"});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#trace-tree').treeview(true).selectNode(0);
|
$('#trace-tree').treeview(true).selectNode(0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue