mirror of
https://github.com/servo/servo.git
synced 2025-06-12 18:34:39 +00:00
layout: When repairing styles for incremental reflow, only repair
styles of nodes that represent the dirty node, *including its pseudo-element*. Fixes lots more jumpiness. A manual test, `inline-pseudo-repair-jumpiness.html`, has been added. I was unable to automate it, so I will file a followup issue on that.
This commit is contained in:
parent
0565df8596
commit
0a589d413d
6 changed files with 55 additions and 13 deletions
|
@ -105,7 +105,7 @@ pub enum ConstructionItem {
|
|||
/// Inline fragments and associated {ib} splits that have not yet found flows.
|
||||
InlineFragments(InlineFragmentsConstructionResult),
|
||||
/// Potentially ignorable whitespace.
|
||||
Whitespace(OpaqueNode, Arc<ComputedValues>, RestyleDamage),
|
||||
Whitespace(OpaqueNode, PseudoElementType<()>, Arc<ComputedValues>, RestyleDamage),
|
||||
/// TableColumn Fragment
|
||||
TableColumnFragment(Fragment),
|
||||
}
|
||||
|
@ -217,6 +217,7 @@ impl InlineFragmentsAccumulator {
|
|||
fragments: IntermediateInlineFragments::new(),
|
||||
enclosing_node: Some(InlineFragmentNodeInfo {
|
||||
address: node.opaque(),
|
||||
pseudo: node.get_pseudo_element_type().strip(),
|
||||
style: node.style().clone(),
|
||||
}),
|
||||
bidi_control_chars: None,
|
||||
|
@ -573,6 +574,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
}
|
||||
ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
||||
whitespace_node,
|
||||
whitespace_pseudo,
|
||||
mut whitespace_style,
|
||||
whitespace_damage)) => {
|
||||
// Add whitespace results. They will be stripped out later on when
|
||||
|
@ -581,6 +583,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
UnscannedTextFragmentInfo::from_text(" ".to_owned()));
|
||||
properties::modify_style_for_replaced_content(&mut whitespace_style);
|
||||
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
|
||||
whitespace_pseudo,
|
||||
whitespace_style,
|
||||
whitespace_damage,
|
||||
fragment_info);
|
||||
|
@ -712,6 +715,8 @@ impl<'a> FlowConstructor<'a> {
|
|||
|
||||
fragments.fragments
|
||||
.push_back(Fragment::from_opaque_node_and_style(node.opaque(),
|
||||
node.get_pseudo_element_type()
|
||||
.strip(),
|
||||
style.clone(),
|
||||
node.restyle_damage(),
|
||||
specific))
|
||||
|
@ -793,12 +798,14 @@ impl<'a> FlowConstructor<'a> {
|
|||
} else {
|
||||
// Push the absolutely-positioned kid as an inline containing block.
|
||||
let kid_node = flow.as_block().fragment.node;
|
||||
let kid_pseudo = flow.as_block().fragment.pseudo.clone();
|
||||
let kid_style = flow.as_block().fragment.style.clone();
|
||||
let kid_restyle_damage = flow.as_block().fragment.restyle_damage;
|
||||
let fragment_info = SpecificFragmentInfo::InlineAbsolute(
|
||||
InlineAbsoluteFragmentInfo::new(flow));
|
||||
fragment_accumulator.push(Fragment::from_opaque_node_and_style(
|
||||
kid_node,
|
||||
kid_pseudo,
|
||||
kid_style,
|
||||
kid_restyle_damage,
|
||||
fragment_info));
|
||||
|
@ -826,6 +833,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
}
|
||||
ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
||||
whitespace_node,
|
||||
whitespace_pseudo,
|
||||
mut whitespace_style,
|
||||
whitespace_damage)) => {
|
||||
// Instantiate the whitespace fragment.
|
||||
|
@ -833,6 +841,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
UnscannedTextFragmentInfo::from_text(" ".to_owned()));
|
||||
properties::modify_style_for_replaced_content(&mut whitespace_style);
|
||||
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
|
||||
whitespace_pseudo,
|
||||
whitespace_style,
|
||||
whitespace_damage,
|
||||
fragment_info);
|
||||
|
@ -875,6 +884,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
if node.is_ignorable_whitespace() {
|
||||
return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
||||
node.opaque(),
|
||||
node.get_pseudo_element_type().strip(),
|
||||
node.style().clone(),
|
||||
node.restyle_damage()))
|
||||
}
|
||||
|
@ -1295,10 +1305,14 @@ impl<'a> FlowConstructor<'a> {
|
|||
for fragment in inline_fragments_construction_result.fragments
|
||||
.fragments
|
||||
.iter_mut() {
|
||||
// Only mutate the styles of fragments that represent the dirty node.
|
||||
// Only mutate the styles of fragments that represent the dirty node (including
|
||||
// pseudo-element).
|
||||
if fragment.node != node.opaque() {
|
||||
continue
|
||||
}
|
||||
if fragment.pseudo != node.get_pseudo_element_type().strip() {
|
||||
continue
|
||||
}
|
||||
|
||||
match fragment.specific {
|
||||
SpecificFragmentInfo::InlineBlock(ref mut inline_block_fragment) => {
|
||||
|
@ -1689,6 +1703,7 @@ fn control_chars_to_fragment(node: &InlineFragmentNodeInfo, text: &str,
|
|||
let info = SpecificFragmentInfo::UnscannedText(
|
||||
UnscannedTextFragmentInfo::from_text(String::from(text)));
|
||||
Fragment::from_opaque_node_and_style(node.address,
|
||||
node.pseudo,
|
||||
node.style.clone(),
|
||||
restyle_damage,
|
||||
info)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue