mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Use empty pseudo to cascade only inheritable properties for text
Since for nested inline elements non-inheritable properties are properly stored in the inline context of an inline fragment, so get rid of them on the style.
This commit is contained in:
parent
1677d479f6
commit
951c050690
8 changed files with 84 additions and 191 deletions
|
@ -51,7 +51,7 @@ use style::computed_values::content::ContentItem;
|
|||
use style::computed_values::position;
|
||||
use style::context::SharedStyleContext;
|
||||
use style::logical_geometry::Direction;
|
||||
use style::properties::{self, ServoComputedValues};
|
||||
use style::properties::ServoComputedValues;
|
||||
use style::selector_parser::{PseudoElement, RestyleDamage};
|
||||
use style::servo::restyle_damage::{BUBBLE_ISIZES, RECONSTRUCT_FLOW};
|
||||
use style::values::Either;
|
||||
|
@ -178,7 +178,7 @@ impl InlineBlockSplit {
|
|||
predecessors: mem::replace(
|
||||
fragment_accumulator,
|
||||
InlineFragmentsAccumulator::from_inline_node(
|
||||
node, style_context)).to_intermediate_inline_fragments(),
|
||||
node, style_context)).to_intermediate_inline_fragments(style_context),
|
||||
flow: flow,
|
||||
};
|
||||
|
||||
|
@ -273,7 +273,8 @@ impl InlineFragmentsAccumulator {
|
|||
self.fragments.absolute_descendants.push_descendants(fragments.absolute_descendants);
|
||||
}
|
||||
|
||||
fn to_intermediate_inline_fragments(self) -> IntermediateInlineFragments {
|
||||
fn to_intermediate_inline_fragments(self, context: &SharedStyleContext)
|
||||
-> IntermediateInlineFragments {
|
||||
let InlineFragmentsAccumulator {
|
||||
mut fragments,
|
||||
enclosing_node,
|
||||
|
@ -299,9 +300,9 @@ impl InlineFragmentsAccumulator {
|
|||
|
||||
if let Some((start, end)) = bidi_control_chars {
|
||||
fragments.fragments.push_front(
|
||||
control_chars_to_fragment(&enclosing_node, start, restyle_damage));
|
||||
control_chars_to_fragment(&enclosing_node, context, start, restyle_damage));
|
||||
fragments.fragments.push_back(
|
||||
control_chars_to_fragment(&enclosing_node, end, restyle_damage));
|
||||
control_chars_to_fragment(&enclosing_node, context, end, restyle_damage));
|
||||
}
|
||||
}
|
||||
fragments
|
||||
|
@ -340,7 +341,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
}
|
||||
|
||||
/// Builds the fragment for the given block or subclass thereof.
|
||||
fn build_fragment_for_block(&mut self, node: &ConcreteThreadSafeLayoutNode) -> Fragment {
|
||||
fn build_fragment_for_block(&self, node: &ConcreteThreadSafeLayoutNode) -> Fragment {
|
||||
let specific_fragment_info = match node.type_id() {
|
||||
Some(LayoutNodeType::Element(LayoutElementType::HTMLIFrameElement)) => {
|
||||
SpecificFragmentInfo::Iframe(IframeFragmentInfo::new(node))
|
||||
|
@ -399,7 +400,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
absolute_descendants: &mut AbsoluteDescendants,
|
||||
legalizer: &mut Legalizer,
|
||||
node: &ConcreteThreadSafeLayoutNode) {
|
||||
let mut fragments = fragment_accumulator.to_intermediate_inline_fragments();
|
||||
let mut fragments = fragment_accumulator.to_intermediate_inline_fragments(self.style_context());
|
||||
if fragments.is_empty() {
|
||||
return
|
||||
};
|
||||
|
@ -546,14 +547,12 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
||||
whitespace_node,
|
||||
whitespace_pseudo,
|
||||
mut whitespace_style,
|
||||
whitespace_style,
|
||||
whitespace_damage)) => {
|
||||
// Add whitespace results. They will be stripped out later on when
|
||||
// between block elements, and retained when between inline elements.
|
||||
let fragment_info = SpecificFragmentInfo::UnscannedText(
|
||||
box UnscannedTextFragmentInfo::new(" ".to_owned(), None));
|
||||
properties::modify_style_for_replaced_content(&mut whitespace_style);
|
||||
properties::modify_style_for_text(&mut whitespace_style);
|
||||
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
|
||||
whitespace_pseudo,
|
||||
whitespace_style,
|
||||
|
@ -644,7 +643,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
/// `<textarea>`.
|
||||
fn build_flow_for_block_like(&mut self, flow: FlowRef, node: &ConcreteThreadSafeLayoutNode)
|
||||
-> ConstructionResult {
|
||||
let mut initial_fragments = IntermediateInlineFragments::new();
|
||||
let mut fragments = IntermediateInlineFragments::new();
|
||||
let node_is_input_or_text_area =
|
||||
node.type_id() == Some(LayoutNodeType::Element(LayoutElementType::HTMLInputElement)) ||
|
||||
node.type_id() == Some(LayoutNodeType::Element(LayoutElementType::HTMLTextAreaElement));
|
||||
|
@ -658,17 +657,18 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
}
|
||||
}
|
||||
|
||||
let mut style = node.style(self.style_context());
|
||||
let context = self.style_context();
|
||||
let mut style = node.style(context);
|
||||
style = context.stylist.style_for_anonymous(
|
||||
&context.guards, &PseudoElement::ServoText, &style);
|
||||
if node_is_input_or_text_area {
|
||||
let context = self.style_context();
|
||||
style = context.stylist.style_for_anonymous_box(
|
||||
style = context.stylist.style_for_anonymous(
|
||||
&context.guards, &PseudoElement::ServoInputText, &style)
|
||||
}
|
||||
|
||||
self.create_fragments_for_node_text_content(&mut initial_fragments, node, &style)
|
||||
self.create_fragments_for_node_text_content(&mut fragments, node, &style)
|
||||
}
|
||||
|
||||
self.build_flow_for_block_starting_with_fragments(flow, node, initial_fragments)
|
||||
self.build_flow_for_block_starting_with_fragments(flow, node, fragments)
|
||||
}
|
||||
|
||||
/// Pushes fragments appropriate for the content of the given node onto the given list.
|
||||
|
@ -682,13 +682,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
return
|
||||
}
|
||||
|
||||
let mut style = (*style).clone();
|
||||
match node.get_pseudo_element_type() {
|
||||
PseudoElementType::Before(_) |
|
||||
PseudoElementType::After(_) => {}
|
||||
_ => properties::modify_style_for_text(&mut style)
|
||||
}
|
||||
|
||||
let style = (*style).clone();
|
||||
let selected_style = node.selected_style();
|
||||
|
||||
match text_content {
|
||||
|
@ -824,13 +818,11 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
||||
whitespace_node,
|
||||
whitespace_pseudo,
|
||||
mut whitespace_style,
|
||||
whitespace_style,
|
||||
whitespace_damage)) => {
|
||||
// Instantiate the whitespace fragment.
|
||||
let fragment_info = SpecificFragmentInfo::UnscannedText(
|
||||
box UnscannedTextFragmentInfo::new(" ".to_owned(), None));
|
||||
properties::modify_style_for_replaced_content(&mut whitespace_style);
|
||||
properties::modify_style_for_text(&mut whitespace_style);
|
||||
let fragment =
|
||||
Fragment::from_opaque_node_and_style(whitespace_node,
|
||||
whitespace_pseudo,
|
||||
|
@ -852,12 +844,9 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
// An empty inline box needs at least one fragment to draw its background and borders.
|
||||
let info = SpecificFragmentInfo::UnscannedText(
|
||||
box UnscannedTextFragmentInfo::new(String::new(), None));
|
||||
let mut modified_style = node_style.clone();
|
||||
properties::modify_style_for_replaced_content(&mut modified_style);
|
||||
properties::modify_style_for_text(&mut modified_style);
|
||||
let fragment = Fragment::from_opaque_node_and_style(node.opaque(),
|
||||
node.get_pseudo_element_type().strip(),
|
||||
modified_style,
|
||||
node_style.clone(),
|
||||
node.selected_style(),
|
||||
node.restyle_damage(),
|
||||
info);
|
||||
|
@ -880,7 +869,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
let construction_item = ConstructionItem::InlineFragments(
|
||||
InlineFragmentsConstructionResult {
|
||||
splits: opt_inline_block_splits,
|
||||
fragments: fragment_accumulator.to_intermediate_inline_fragments(),
|
||||
fragments: fragment_accumulator.to_intermediate_inline_fragments(self.style_context()),
|
||||
});
|
||||
ConstructionResult::ConstructionItem(construction_item)
|
||||
} else {
|
||||
|
@ -897,31 +886,27 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
self.set_flow_construction_result(&kid, ConstructionResult::None)
|
||||
}
|
||||
|
||||
let context = self.style_context();
|
||||
let style = node.style(context);
|
||||
// If this node is ignorable whitespace, bail out now.
|
||||
if node.is_ignorable_whitespace(self.style_context()) {
|
||||
if node.is_ignorable_whitespace(context) {
|
||||
return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
|
||||
node.opaque(),
|
||||
node.get_pseudo_element_type().strip(),
|
||||
node.style(self.style_context()),
|
||||
context.stylist.style_for_anonymous(
|
||||
&context.guards, &PseudoElement::ServoText, &style),
|
||||
node.restyle_damage()))
|
||||
}
|
||||
|
||||
// Modify the style as necessary. (See the comment in
|
||||
// `properties::modify_style_for_replaced_content()`.)
|
||||
let mut style = node.style(self.style_context());
|
||||
match node.get_pseudo_element_type() {
|
||||
PseudoElementType::Before(_) |
|
||||
PseudoElementType::After(_) => {}
|
||||
_ => properties::modify_style_for_replaced_content(&mut style)
|
||||
}
|
||||
|
||||
// If this is generated content, then we need to initialize the accumulator with the
|
||||
// fragment corresponding to that content. Otherwise, just initialize with the ordinary
|
||||
// fragment that needs to be generated for this inline node.
|
||||
let mut fragments = IntermediateInlineFragments::new();
|
||||
match (node.get_pseudo_element_type(), node.type_id()) {
|
||||
(_, Some(LayoutNodeType::Text)) => {
|
||||
self.create_fragments_for_node_text_content(&mut fragments, node, &style)
|
||||
let text_style = context.stylist.style_for_anonymous(
|
||||
&context.guards, &PseudoElement::ServoText, &style);
|
||||
self.create_fragments_for_node_text_content(&mut fragments, node, &text_style)
|
||||
}
|
||||
(PseudoElementType::Normal, _) => {
|
||||
fragments.fragments.push_back(self.build_fragment_for_block(node));
|
||||
|
@ -952,7 +937,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
|
||||
let context = self.style_context();
|
||||
let style = node.style(context);
|
||||
let style = context.stylist.style_for_anonymous_box(
|
||||
let style = context.stylist.style_for_anonymous(
|
||||
&context.guards, &PseudoElement::ServoInlineBlockWrapper, &style);
|
||||
let fragment_info = SpecificFragmentInfo::InlineBlock(InlineBlockFragmentInfo::new(
|
||||
block_flow));
|
||||
|
@ -970,7 +955,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
let construction_item =
|
||||
ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
|
||||
splits: LinkedList::new(),
|
||||
fragments: fragment_accumulator.to_intermediate_inline_fragments(),
|
||||
fragments: fragment_accumulator.to_intermediate_inline_fragments(context),
|
||||
});
|
||||
ConstructionResult::ConstructionItem(construction_item)
|
||||
}
|
||||
|
@ -990,7 +975,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
InlineAbsoluteHypotheticalFragmentInfo::new(block_flow));
|
||||
let style_context = self.style_context();
|
||||
let style = node.style(style_context);
|
||||
let style = style_context.stylist.style_for_anonymous_box(
|
||||
let style = style_context.stylist.style_for_anonymous(
|
||||
&style_context.guards, &PseudoElement::ServoInlineAbsolute, &style);
|
||||
let fragment = Fragment::from_opaque_node_and_style(node.opaque(),
|
||||
PseudoElementType::Normal,
|
||||
|
@ -1006,7 +991,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
let construction_item =
|
||||
ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
|
||||
splits: LinkedList::new(),
|
||||
fragments: fragment_accumulator.to_intermediate_inline_fragments(),
|
||||
fragments: fragment_accumulator.to_intermediate_inline_fragments(style_context),
|
||||
});
|
||||
ConstructionResult::ConstructionItem(construction_item)
|
||||
}
|
||||
|
@ -1103,7 +1088,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
{
|
||||
let context = self.style_context();
|
||||
table_style = node.style(context);
|
||||
wrapper_style = context.stylist.style_for_anonymous_box(
|
||||
wrapper_style = context.stylist.style_for_anonymous(
|
||||
&context.guards, &PseudoElement::ServoTableWrapper, &table_style);
|
||||
}
|
||||
let wrapper_fragment =
|
||||
|
@ -1370,7 +1355,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
|
||||
let mut set_has_newly_constructed_flow_flag = false;
|
||||
let result = {
|
||||
let mut style = node.style(self.style_context());
|
||||
let style = node.style(self.style_context());
|
||||
let damage = node.restyle_damage();
|
||||
let mut data = node.mutate_layout_data().unwrap();
|
||||
|
||||
|
@ -1441,9 +1426,6 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
|||
return false
|
||||
}
|
||||
_ => {
|
||||
if node.is_replaced_content() {
|
||||
properties::modify_style_for_replaced_content(&mut style);
|
||||
}
|
||||
fragment.repair_style(&style);
|
||||
set_has_newly_constructed_flow_flag = true;
|
||||
}
|
||||
|
@ -1845,17 +1827,17 @@ fn bidi_control_chars(style: &Arc<ServoComputedValues>) -> Option<(&'static str,
|
|||
}
|
||||
|
||||
fn control_chars_to_fragment(node: &InlineFragmentNodeInfo,
|
||||
context: &SharedStyleContext,
|
||||
text: &str,
|
||||
restyle_damage: RestyleDamage)
|
||||
-> Fragment {
|
||||
let info = SpecificFragmentInfo::UnscannedText(
|
||||
box UnscannedTextFragmentInfo::new(String::from(text), None));
|
||||
let mut style = node.style.clone();
|
||||
properties::modify_style_for_replaced_content(&mut style);
|
||||
properties::modify_style_for_text(&mut style);
|
||||
let text_style = context.stylist.style_for_anonymous(
|
||||
&context.guards, &PseudoElement::ServoText, &node.style);
|
||||
Fragment::from_opaque_node_and_style(node.address,
|
||||
node.pseudo,
|
||||
style.clone(),
|
||||
text_style,
|
||||
node.selected_style.clone(),
|
||||
restyle_damage,
|
||||
info)
|
||||
|
@ -2085,7 +2067,7 @@ impl Legalizer {
|
|||
let reference_block = reference.as_block();
|
||||
let mut new_style = reference_block.fragment.style.clone();
|
||||
for pseudo in pseudos {
|
||||
new_style = context.stylist.style_for_anonymous_box(&context.guards, pseudo, &new_style)
|
||||
new_style = context.stylist.style_for_anonymous(&context.guards, pseudo, &new_style)
|
||||
}
|
||||
let fragment = reference_block.fragment
|
||||
.create_similar_anonymous_fragment(new_style,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue