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:
Patrick Walton 2015-08-03 16:15:11 -07:00
parent 0565df8596
commit 0a589d413d
6 changed files with 55 additions and 13 deletions

View file

@ -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)