mirror of
https://github.com/servo/servo.git
synced 2025-07-29 02:00:23 +01: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.
|
/// Inline fragments and associated {ib} splits that have not yet found flows.
|
||||||
InlineFragments(InlineFragmentsConstructionResult),
|
InlineFragments(InlineFragmentsConstructionResult),
|
||||||
/// Potentially ignorable whitespace.
|
/// Potentially ignorable whitespace.
|
||||||
Whitespace(OpaqueNode, Arc<ComputedValues>, RestyleDamage),
|
Whitespace(OpaqueNode, PseudoElementType<()>, Arc<ComputedValues>, RestyleDamage),
|
||||||
/// TableColumn Fragment
|
/// TableColumn Fragment
|
||||||
TableColumnFragment(Fragment),
|
TableColumnFragment(Fragment),
|
||||||
}
|
}
|
||||||
|
@ -217,6 +217,7 @@ impl InlineFragmentsAccumulator {
|
||||||
fragments: IntermediateInlineFragments::new(),
|
fragments: IntermediateInlineFragments::new(),
|
||||||
enclosing_node: Some(InlineFragmentNodeInfo {
|
enclosing_node: Some(InlineFragmentNodeInfo {
|
||||||
address: node.opaque(),
|
address: node.opaque(),
|
||||||
|
pseudo: node.get_pseudo_element_type().strip(),
|
||||||
style: node.style().clone(),
|
style: node.style().clone(),
|
||||||
}),
|
}),
|
||||||
bidi_control_chars: None,
|
bidi_control_chars: None,
|
||||||
|
@ -573,6 +574,7 @@ impl<'a> FlowConstructor<'a> {
|
||||||
}
|
}
|
||||||
ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
||||||
whitespace_node,
|
whitespace_node,
|
||||||
|
whitespace_pseudo,
|
||||||
mut whitespace_style,
|
mut whitespace_style,
|
||||||
whitespace_damage)) => {
|
whitespace_damage)) => {
|
||||||
// Add whitespace results. They will be stripped out later on when
|
// Add whitespace results. They will be stripped out later on when
|
||||||
|
@ -581,6 +583,7 @@ impl<'a> FlowConstructor<'a> {
|
||||||
UnscannedTextFragmentInfo::from_text(" ".to_owned()));
|
UnscannedTextFragmentInfo::from_text(" ".to_owned()));
|
||||||
properties::modify_style_for_replaced_content(&mut whitespace_style);
|
properties::modify_style_for_replaced_content(&mut whitespace_style);
|
||||||
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
|
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
|
||||||
|
whitespace_pseudo,
|
||||||
whitespace_style,
|
whitespace_style,
|
||||||
whitespace_damage,
|
whitespace_damage,
|
||||||
fragment_info);
|
fragment_info);
|
||||||
|
@ -712,6 +715,8 @@ impl<'a> FlowConstructor<'a> {
|
||||||
|
|
||||||
fragments.fragments
|
fragments.fragments
|
||||||
.push_back(Fragment::from_opaque_node_and_style(node.opaque(),
|
.push_back(Fragment::from_opaque_node_and_style(node.opaque(),
|
||||||
|
node.get_pseudo_element_type()
|
||||||
|
.strip(),
|
||||||
style.clone(),
|
style.clone(),
|
||||||
node.restyle_damage(),
|
node.restyle_damage(),
|
||||||
specific))
|
specific))
|
||||||
|
@ -793,12 +798,14 @@ impl<'a> FlowConstructor<'a> {
|
||||||
} else {
|
} else {
|
||||||
// Push the absolutely-positioned kid as an inline containing block.
|
// Push the absolutely-positioned kid as an inline containing block.
|
||||||
let kid_node = flow.as_block().fragment.node;
|
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_style = flow.as_block().fragment.style.clone();
|
||||||
let kid_restyle_damage = flow.as_block().fragment.restyle_damage;
|
let kid_restyle_damage = flow.as_block().fragment.restyle_damage;
|
||||||
let fragment_info = SpecificFragmentInfo::InlineAbsolute(
|
let fragment_info = SpecificFragmentInfo::InlineAbsolute(
|
||||||
InlineAbsoluteFragmentInfo::new(flow));
|
InlineAbsoluteFragmentInfo::new(flow));
|
||||||
fragment_accumulator.push(Fragment::from_opaque_node_and_style(
|
fragment_accumulator.push(Fragment::from_opaque_node_and_style(
|
||||||
kid_node,
|
kid_node,
|
||||||
|
kid_pseudo,
|
||||||
kid_style,
|
kid_style,
|
||||||
kid_restyle_damage,
|
kid_restyle_damage,
|
||||||
fragment_info));
|
fragment_info));
|
||||||
|
@ -826,6 +833,7 @@ impl<'a> FlowConstructor<'a> {
|
||||||
}
|
}
|
||||||
ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
||||||
whitespace_node,
|
whitespace_node,
|
||||||
|
whitespace_pseudo,
|
||||||
mut whitespace_style,
|
mut whitespace_style,
|
||||||
whitespace_damage)) => {
|
whitespace_damage)) => {
|
||||||
// Instantiate the whitespace fragment.
|
// Instantiate the whitespace fragment.
|
||||||
|
@ -833,6 +841,7 @@ impl<'a> FlowConstructor<'a> {
|
||||||
UnscannedTextFragmentInfo::from_text(" ".to_owned()));
|
UnscannedTextFragmentInfo::from_text(" ".to_owned()));
|
||||||
properties::modify_style_for_replaced_content(&mut whitespace_style);
|
properties::modify_style_for_replaced_content(&mut whitespace_style);
|
||||||
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
|
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
|
||||||
|
whitespace_pseudo,
|
||||||
whitespace_style,
|
whitespace_style,
|
||||||
whitespace_damage,
|
whitespace_damage,
|
||||||
fragment_info);
|
fragment_info);
|
||||||
|
@ -875,6 +884,7 @@ impl<'a> FlowConstructor<'a> {
|
||||||
if node.is_ignorable_whitespace() {
|
if node.is_ignorable_whitespace() {
|
||||||
return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
||||||
node.opaque(),
|
node.opaque(),
|
||||||
|
node.get_pseudo_element_type().strip(),
|
||||||
node.style().clone(),
|
node.style().clone(),
|
||||||
node.restyle_damage()))
|
node.restyle_damage()))
|
||||||
}
|
}
|
||||||
|
@ -1295,10 +1305,14 @@ impl<'a> FlowConstructor<'a> {
|
||||||
for fragment in inline_fragments_construction_result.fragments
|
for fragment in inline_fragments_construction_result.fragments
|
||||||
.fragments
|
.fragments
|
||||||
.iter_mut() {
|
.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() {
|
if fragment.node != node.opaque() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if fragment.pseudo != node.get_pseudo_element_type().strip() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
match fragment.specific {
|
match fragment.specific {
|
||||||
SpecificFragmentInfo::InlineBlock(ref mut inline_block_fragment) => {
|
SpecificFragmentInfo::InlineBlock(ref mut inline_block_fragment) => {
|
||||||
|
@ -1689,6 +1703,7 @@ fn control_chars_to_fragment(node: &InlineFragmentNodeInfo, text: &str,
|
||||||
let info = SpecificFragmentInfo::UnscannedText(
|
let info = SpecificFragmentInfo::UnscannedText(
|
||||||
UnscannedTextFragmentInfo::from_text(String::from(text)));
|
UnscannedTextFragmentInfo::from_text(String::from(text)));
|
||||||
Fragment::from_opaque_node_and_style(node.address,
|
Fragment::from_opaque_node_and_style(node.address,
|
||||||
|
node.pseudo,
|
||||||
node.style.clone(),
|
node.style.clone(),
|
||||||
restyle_damage,
|
restyle_damage,
|
||||||
info)
|
info)
|
||||||
|
|
|
@ -17,7 +17,7 @@ use inline::{InlineFragmentContext, InlineFragmentNodeInfo, InlineMetrics};
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified};
|
use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified};
|
||||||
use text;
|
use text;
|
||||||
use wrapper::ThreadSafeLayoutNode;
|
use wrapper::{PseudoElementType, ThreadSafeLayoutNode};
|
||||||
|
|
||||||
use euclid::{Point2D, Rect, Size2D};
|
use euclid::{Point2D, Rect, Size2D};
|
||||||
use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
|
use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
|
||||||
|
@ -107,6 +107,9 @@ pub struct Fragment {
|
||||||
/// How damaged this fragment is since last reflow.
|
/// How damaged this fragment is since last reflow.
|
||||||
pub restyle_damage: RestyleDamage,
|
pub restyle_damage: RestyleDamage,
|
||||||
|
|
||||||
|
/// The pseudo-element that this fragment represents.
|
||||||
|
pub pseudo: PseudoElementType<()>,
|
||||||
|
|
||||||
/// A debug ID that is consistent for the life of this fragment (via transform etc).
|
/// A debug ID that is consistent for the life of this fragment (via transform etc).
|
||||||
pub debug_id: u16,
|
pub debug_id: u16,
|
||||||
}
|
}
|
||||||
|
@ -752,6 +755,7 @@ impl Fragment {
|
||||||
margin: LogicalMargin::zero(writing_mode),
|
margin: LogicalMargin::zero(writing_mode),
|
||||||
specific: specific,
|
specific: specific,
|
||||||
inline_context: None,
|
inline_context: None,
|
||||||
|
pseudo: node.get_pseudo_element_type().strip(),
|
||||||
debug_id: layout_debug::generate_unique_debug_id(),
|
debug_id: layout_debug::generate_unique_debug_id(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -782,12 +786,14 @@ impl Fragment {
|
||||||
margin: LogicalMargin::zero(writing_mode),
|
margin: LogicalMargin::zero(writing_mode),
|
||||||
specific: specific,
|
specific: specific,
|
||||||
inline_context: None,
|
inline_context: None,
|
||||||
|
pseudo: node.get_pseudo_element_type().strip(),
|
||||||
debug_id: layout_debug::generate_unique_debug_id(),
|
debug_id: layout_debug::generate_unique_debug_id(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new `Fragment` instance from an opaque node.
|
/// Constructs a new `Fragment` instance from an opaque node.
|
||||||
pub fn from_opaque_node_and_style(node: OpaqueNode,
|
pub fn from_opaque_node_and_style(node: OpaqueNode,
|
||||||
|
pseudo: PseudoElementType<()>,
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
restyle_damage: RestyleDamage,
|
restyle_damage: RestyleDamage,
|
||||||
specific: SpecificFragmentInfo)
|
specific: SpecificFragmentInfo)
|
||||||
|
@ -802,6 +808,7 @@ impl Fragment {
|
||||||
margin: LogicalMargin::zero(writing_mode),
|
margin: LogicalMargin::zero(writing_mode),
|
||||||
specific: specific,
|
specific: specific,
|
||||||
inline_context: None,
|
inline_context: None,
|
||||||
|
pseudo: pseudo,
|
||||||
debug_id: layout_debug::generate_unique_debug_id(),
|
debug_id: layout_debug::generate_unique_debug_id(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -834,6 +841,7 @@ impl Fragment {
|
||||||
margin: self.margin,
|
margin: self.margin,
|
||||||
specific: info,
|
specific: info,
|
||||||
inline_context: self.inline_context.clone(),
|
inline_context: self.inline_context.clone(),
|
||||||
|
pseudo: self.pseudo.clone(),
|
||||||
debug_id: self.debug_id,
|
debug_id: self.debug_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTe
|
||||||
use incremental::{self, RESOLVE_GENERATED_CONTENT};
|
use incremental::{self, RESOLVE_GENERATED_CONTENT};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use text::TextRunScanner;
|
use text::TextRunScanner;
|
||||||
|
use wrapper::PseudoElementType;
|
||||||
|
|
||||||
use gfx::display_list::OpaqueNode;
|
use gfx::display_list::OpaqueNode;
|
||||||
use std::collections::{LinkedList, HashMap};
|
use std::collections::{LinkedList, HashMap};
|
||||||
|
@ -174,6 +175,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
|
||||||
GeneratedContentInfo::ListItem => {
|
GeneratedContentInfo::ListItem => {
|
||||||
new_info = self.traversal.list_item.render(self.traversal.layout_context,
|
new_info = self.traversal.list_item.render(self.traversal.layout_context,
|
||||||
fragment.node,
|
fragment.node,
|
||||||
|
fragment.pseudo.clone(),
|
||||||
fragment.style.clone(),
|
fragment.style.clone(),
|
||||||
list_style_type,
|
list_style_type,
|
||||||
RenderingMode::Suffix(".\u{00a0}"))
|
RenderingMode::Suffix(".\u{00a0}"))
|
||||||
|
@ -190,6 +192,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
|
||||||
.unwrap_or(&mut temporary_counter);
|
.unwrap_or(&mut temporary_counter);
|
||||||
new_info = counter.render(self.traversal.layout_context,
|
new_info = counter.render(self.traversal.layout_context,
|
||||||
fragment.node,
|
fragment.node,
|
||||||
|
fragment.pseudo.clone(),
|
||||||
fragment.style.clone(),
|
fragment.style.clone(),
|
||||||
counter_style,
|
counter_style,
|
||||||
RenderingMode::Plain)
|
RenderingMode::Plain)
|
||||||
|
@ -204,6 +207,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
|
||||||
.unwrap_or(&mut temporary_counter);
|
.unwrap_or(&mut temporary_counter);
|
||||||
new_info = counter.render(self.traversal.layout_context,
|
new_info = counter.render(self.traversal.layout_context,
|
||||||
fragment.node,
|
fragment.node,
|
||||||
|
fragment.pseudo,
|
||||||
fragment.style.clone(),
|
fragment.style.clone(),
|
||||||
counter_style,
|
counter_style,
|
||||||
RenderingMode::All(&separator));
|
RenderingMode::All(&separator));
|
||||||
|
@ -211,6 +215,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
|
||||||
GeneratedContentInfo::ContentItem(ContentItem::OpenQuote) => {
|
GeneratedContentInfo::ContentItem(ContentItem::OpenQuote) => {
|
||||||
new_info = Some(render_text(self.traversal.layout_context,
|
new_info = Some(render_text(self.traversal.layout_context,
|
||||||
fragment.node,
|
fragment.node,
|
||||||
|
fragment.pseudo,
|
||||||
fragment.style.clone(),
|
fragment.style.clone(),
|
||||||
self.quote(&*fragment.style, false)));
|
self.quote(&*fragment.style, false)));
|
||||||
self.traversal.quote += 1
|
self.traversal.quote += 1
|
||||||
|
@ -222,6 +227,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
|
||||||
|
|
||||||
new_info = Some(render_text(self.traversal.layout_context,
|
new_info = Some(render_text(self.traversal.layout_context,
|
||||||
fragment.node,
|
fragment.node,
|
||||||
|
fragment.pseudo,
|
||||||
fragment.style.clone(),
|
fragment.style.clone(),
|
||||||
self.quote(&*fragment.style, true)));
|
self.quote(&*fragment.style, true)));
|
||||||
}
|
}
|
||||||
|
@ -356,6 +362,7 @@ impl Counter {
|
||||||
fn render(&self,
|
fn render(&self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
node: OpaqueNode,
|
node: OpaqueNode,
|
||||||
|
pseudo: PseudoElementType<()>,
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
list_style_type: list_style_type::T,
|
list_style_type: list_style_type::T,
|
||||||
mode: RenderingMode)
|
mode: RenderingMode)
|
||||||
|
@ -392,7 +399,7 @@ impl Counter {
|
||||||
if string.is_empty() {
|
if string.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(render_text(layout_context, node, style, string))
|
Some(render_text(layout_context, node, pseudo, style, string))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,12 +425,14 @@ struct CounterValue {
|
||||||
/// Creates fragment info for a literal string.
|
/// Creates fragment info for a literal string.
|
||||||
fn render_text(layout_context: &LayoutContext,
|
fn render_text(layout_context: &LayoutContext,
|
||||||
node: OpaqueNode,
|
node: OpaqueNode,
|
||||||
|
pseudo: PseudoElementType<()>,
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
string: String)
|
string: String)
|
||||||
-> SpecificFragmentInfo {
|
-> SpecificFragmentInfo {
|
||||||
let mut fragments = LinkedList::new();
|
let mut fragments = LinkedList::new();
|
||||||
let info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(string));
|
let info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(string));
|
||||||
fragments.push_back(Fragment::from_opaque_node_and_style(node,
|
fragments.push_back(Fragment::from_opaque_node_and_style(node,
|
||||||
|
pseudo,
|
||||||
style,
|
style,
|
||||||
incremental::rebuild_and_reflow(),
|
incremental::rebuild_and_reflow(),
|
||||||
info));
|
info));
|
||||||
|
|
|
@ -15,6 +15,7 @@ use incremental::{REFLOW, REFLOW_OUT_OF_FLOW, RESOLVE_GENERATED_CONTENT};
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
use model::IntrinsicISizesContribution;
|
use model::IntrinsicISizesContribution;
|
||||||
use text;
|
use text;
|
||||||
|
use wrapper::PseudoElementType;
|
||||||
|
|
||||||
use euclid::{Point2D, Rect, Size2D};
|
use euclid::{Point2D, Rect, Size2D};
|
||||||
use gfx::display_list::OpaqueNode;
|
use gfx::display_list::OpaqueNode;
|
||||||
|
@ -1349,8 +1350,7 @@ impl Flow for InlineFlow {
|
||||||
self.base.block_container_explicit_block_size;
|
self.base.block_container_explicit_block_size;
|
||||||
for fragment in self.fragments.fragments.iter_mut() {
|
for fragment in self.fragments.fragments.iter_mut() {
|
||||||
fragment.update_late_computed_replaced_inline_size_if_necessary();
|
fragment.update_late_computed_replaced_inline_size_if_necessary();
|
||||||
fragment.assign_replaced_block_size_if_necessary(
|
fragment.assign_replaced_block_size_if_necessary(containing_block_block_size);
|
||||||
containing_block_block_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset our state, so that we handle incremental reflow correctly.
|
// Reset our state, so that we handle incremental reflow correctly.
|
||||||
|
@ -1687,6 +1687,7 @@ impl fmt::Debug for InlineFlow {
|
||||||
pub struct InlineFragmentNodeInfo {
|
pub struct InlineFragmentNodeInfo {
|
||||||
pub address: OpaqueNode,
|
pub address: OpaqueNode,
|
||||||
pub style: Arc<ComputedValues>,
|
pub style: Arc<ComputedValues>,
|
||||||
|
pub pseudo: PseudoElementType<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
|
@ -588,13 +588,13 @@ impl<'le> TElementAttributes for LayoutElement<'le> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, PartialEq, Clone)]
|
#[derive(Copy, PartialEq, Clone)]
|
||||||
pub enum PseudoElementType {
|
pub enum PseudoElementType<T> {
|
||||||
Normal,
|
Normal,
|
||||||
Before(display::T),
|
Before(T),
|
||||||
After(display::T),
|
After(T),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PseudoElementType {
|
impl<T> PseudoElementType<T> {
|
||||||
pub fn is_before(&self) -> bool {
|
pub fn is_before(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
PseudoElementType::Before(_) => true,
|
PseudoElementType::Before(_) => true,
|
||||||
|
@ -608,6 +608,14 @@ impl PseudoElementType {
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn strip(&self) -> PseudoElementType<()> {
|
||||||
|
match *self {
|
||||||
|
PseudoElementType::Normal => PseudoElementType::Normal,
|
||||||
|
PseudoElementType::Before(_) => PseudoElementType::Before(()),
|
||||||
|
PseudoElementType::After(_) => PseudoElementType::After(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A thread-safe version of `LayoutNode`, used during flow construction. This type of layout
|
/// A thread-safe version of `LayoutNode`, used during flow construction. This type of layout
|
||||||
|
@ -617,7 +625,7 @@ pub struct ThreadSafeLayoutNode<'ln> {
|
||||||
/// The wrapped node.
|
/// The wrapped node.
|
||||||
node: LayoutNode<'ln>,
|
node: LayoutNode<'ln>,
|
||||||
|
|
||||||
pseudo: PseudoElementType,
|
pseudo: PseudoElementType<display::T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ln> ThreadSafeLayoutNode<'ln> {
|
impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||||
|
@ -639,7 +647,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||||
|
|
||||||
/// Creates a new `ThreadSafeLayoutNode` for the same `LayoutNode`
|
/// Creates a new `ThreadSafeLayoutNode` for the same `LayoutNode`
|
||||||
/// with a different pseudo-element type.
|
/// with a different pseudo-element type.
|
||||||
fn with_pseudo(&self, pseudo: PseudoElementType) -> ThreadSafeLayoutNode<'ln> {
|
fn with_pseudo(&self, pseudo: PseudoElementType<display::T>) -> ThreadSafeLayoutNode<'ln> {
|
||||||
ThreadSafeLayoutNode {
|
ThreadSafeLayoutNode {
|
||||||
node: self.node.clone(),
|
node: self.node.clone(),
|
||||||
pseudo: pseudo,
|
pseudo: pseudo,
|
||||||
|
@ -697,7 +705,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_pseudo_element_type(&self) -> PseudoElementType {
|
pub fn get_pseudo_element_type(&self) -> PseudoElementType<display::T> {
|
||||||
self.pseudo
|
self.pseudo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
tests/html/inline-pseudo-repair-jumpiness.html
Normal file
1
tests/html/inline-pseudo-repair-jumpiness.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<body>a<br>b</body>
|
Loading…
Add table
Add a link
Reference in a new issue