mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Detect body elements during layout
During layout it is often useful, for various specification reasons, to know if an element is the `<body>` element of an `<html>` element root. There are a couple places where a brittle heuristic is used to detect `<body>` elements. This information is going to be even more important to properly handle `<html>` elements that inherit their overflow property from their `<body>` children. Implementing this properly requires updating the DOM wrapper interface. This check does reach up to the parent of thread-safe nodes, but this is essentially the same kind of operation that `parent_style()` does, so is ostensibly safe. This change should not change any behavior and is just a preparation step for properly handle `<body>` overflow.
This commit is contained in:
parent
77a184a0e7
commit
72302e2dae
26 changed files with 487 additions and 277 deletions
|
@ -967,13 +967,23 @@ impl fmt::Debug for BaseFlow {
|
|||
"".to_owned()
|
||||
};
|
||||
|
||||
let flags_string = if !self.flags.is_empty() {
|
||||
format!("\nflags={:?}", self.flags)
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
|
||||
write!(
|
||||
f,
|
||||
"\nsc={:?}\
|
||||
\npos={:?}{}{}\
|
||||
\nfloatspec-in={:?}\
|
||||
\nfloatspec-out={:?}\
|
||||
\noverflow={:?}{}{}{}",
|
||||
\noverflow={:?}\
|
||||
{child_count_string}\
|
||||
{absolute_descendants_string}\
|
||||
{damage_string}\
|
||||
{flags_string}",
|
||||
self.stacking_context_id,
|
||||
self.position,
|
||||
if self.flags.contains(FlowFlags::FLOATS_LEFT) {
|
||||
|
@ -989,9 +999,6 @@ impl fmt::Debug for BaseFlow {
|
|||
self.speculated_float_placement_in,
|
||||
self.speculated_float_placement_out,
|
||||
self.overflow,
|
||||
child_count_string,
|
||||
absolute_descendants_string,
|
||||
damage_string
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -677,18 +677,27 @@ impl Fragment {
|
|||
let mut restyle_damage = node.restyle_damage();
|
||||
restyle_damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW);
|
||||
|
||||
let mut flags = FragmentFlags::empty();
|
||||
let is_body = node
|
||||
.as_element()
|
||||
.map(|element| element.is_body_element_of_html_element_root())
|
||||
.unwrap_or(false);
|
||||
if is_body {
|
||||
flags |= FragmentFlags::IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT;
|
||||
}
|
||||
|
||||
Fragment {
|
||||
node: node.opaque(),
|
||||
style: style,
|
||||
style,
|
||||
selected_style: node.selected_style(),
|
||||
restyle_damage: restyle_damage,
|
||||
restyle_damage,
|
||||
border_box: LogicalRect::zero(writing_mode),
|
||||
border_padding: LogicalMargin::zero(writing_mode),
|
||||
margin: LogicalMargin::zero(writing_mode),
|
||||
specific: specific,
|
||||
specific,
|
||||
inline_context: None,
|
||||
pseudo: node.get_pseudo_element_type(),
|
||||
flags: FragmentFlags::empty(),
|
||||
flags,
|
||||
debug_id: DebugId::new(),
|
||||
stacking_context_id: StackingContextId::root(),
|
||||
established_reference_frame: None,
|
||||
|
@ -3277,16 +3286,24 @@ impl fmt::Debug for Fragment {
|
|||
"".to_owned()
|
||||
};
|
||||
|
||||
let flags_string = if !self.flags.is_empty() {
|
||||
format!("\nflags={:?}", self.flags)
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
|
||||
write!(
|
||||
f,
|
||||
"\n{}({}) [{:?}]\nborder_box={:?}{}{}{}",
|
||||
"\n{}({}) [{:?}]\
|
||||
\nborder_box={:?}\
|
||||
{border_padding_string}\
|
||||
{margin_string}\
|
||||
{damage_string}\
|
||||
{flags_string}",
|
||||
self.specific.get_type(),
|
||||
self.debug_id,
|
||||
self.specific,
|
||||
self.border_box,
|
||||
border_padding_string,
|
||||
margin_string,
|
||||
damage_string
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -3430,6 +3447,8 @@ bitflags! {
|
|||
const IS_BLOCK_FLEX_ITEM = 0b0000_0010;
|
||||
/// Whether this fragment represents the generated text from a text-overflow clip.
|
||||
const IS_ELLIPSIS = 0b0000_0100;
|
||||
/// Whether this fragment is for the body element child of a html element root element.
|
||||
const IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT = 0b0000_1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::context::LayoutContext;
|
|||
use crate::display_list::items::{DisplayList, OpaqueNode, ScrollOffsetMap};
|
||||
use crate::display_list::IndexableText;
|
||||
use crate::flow::{Flow, GetBaseFlow};
|
||||
use crate::fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
|
||||
use crate::fragment::{Fragment, FragmentBorderBoxIterator, FragmentFlags, SpecificFragmentInfo};
|
||||
use crate::inline::InlineFragmentNodeFlags;
|
||||
use crate::opaque_node::OpaqueNodeMethods;
|
||||
use crate::sequential;
|
||||
|
@ -666,11 +666,9 @@ impl FragmentBorderBoxIterator for ParentOffsetBorderBoxIterator {
|
|||
self.has_processed_node = true;
|
||||
}
|
||||
} else if self.node_offset_box.is_none() {
|
||||
// TODO(gw): Is there a less fragile way of checking whether this
|
||||
// fragment is the body element, rather than just checking that
|
||||
// it's at level 1 (below the root node)?
|
||||
let is_body_element = level == 1;
|
||||
|
||||
let is_body_element = fragment
|
||||
.flags
|
||||
.contains(FragmentFlags::IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT);
|
||||
let is_valid_parent = match (
|
||||
is_body_element,
|
||||
fragment.style.get_box().position,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue