aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/construct.rs
diff options
context:
space:
mode:
authorPu Xingyu <pu.stshine@gmail.com>2017-03-23 21:03:41 +0800
committerPu Xingyu <pu.stshine@gmail.com>2017-04-01 14:05:11 +0800
commit951c0506909ac5e6e180a97329a47c41ab6c458b (patch)
tree6bc3fc93ab50814651eaf025bbe9f207058f6e7e /components/layout/construct.rs
parent1677d479f61351ad22149eb577de6713a16b9908 (diff)
downloadservo-951c0506909ac5e6e180a97329a47c41ab6c458b.tar.gz
servo-951c0506909ac5e6e180a97329a47c41ab6c458b.zip
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.
Diffstat (limited to 'components/layout/construct.rs')
-rw-r--r--components/layout/construct.rs98
1 files changed, 40 insertions, 58 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 7dd4da8ada4..089209551ac 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -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,