aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/construct.rs
diff options
context:
space:
mode:
authorPermutator <permutatorem@gmail.com>2016-11-02 20:13:40 -0700
committerPermutator <permutatorem@gmail.com>2016-11-02 20:13:40 -0700
commitfec3a49d434572e2bde86291a7451625113a7cfb (patch)
treece4dd1cda4675a1fd5b381cfb7ea62e5754fffb3 /components/layout/construct.rs
parent6ef46ab9e4ec08d5f5226d41f0cac77c3584bae9 (diff)
downloadservo-fec3a49d434572e2bde86291a7451625113a7cfb.tar.gz
servo-fec3a49d434572e2bde86291a7451625113a7cfb.zip
Don't mark start/end of {ib} split as FIRST/LAST_FRAGMENT_OF_ELEMENT
Diffstat (limited to 'components/layout/construct.rs')
-rw-r--r--components/layout/construct.rs65
1 files changed, 39 insertions, 26 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 572498aad35..126d325d939 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -29,7 +29,7 @@ use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo};
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use fragment::WhitespaceStrippingResult;
use gfx::display_list::OpaqueNode;
-use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, InlineFragmentNodeFlags};
+use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow};
use inline::{InlineFragmentNodeInfo, LAST_FRAGMENT_OF_ELEMENT};
use linked_list::prepend_from;
use list_item::{ListItemFlow, ListStyleTypeContent};
@@ -159,6 +159,32 @@ pub struct InlineBlockSplit {
pub flow: FlowRef,
}
+/// Flushes the given accumulator to the new split and makes a new accumulator to hold any
+/// subsequent fragments.
+impl InlineBlockSplit {
+ fn new<ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>(fragment_accumulator: &mut InlineFragmentsAccumulator,
+ node: &ConcreteThreadSafeLayoutNode,
+ style_context: &SharedStyleContext,
+ flow: FlowRef)
+ -> InlineBlockSplit {
+ fragment_accumulator.enclosing_node.as_mut().expect(
+ "enclosing_node is None; Are {ib} splits being generated outside of an inline node?"
+ ).flags.remove(LAST_FRAGMENT_OF_ELEMENT);
+
+ let split = InlineBlockSplit {
+ predecessors: mem::replace(
+ fragment_accumulator,
+ InlineFragmentsAccumulator::from_inline_node(
+ node, style_context)).to_intermediate_inline_fragments(),
+ flow: flow,
+ };
+
+ fragment_accumulator.enclosing_node.as_mut().unwrap().flags.remove(FIRST_FRAGMENT_OF_ELEMENT);
+
+ split
+ }
+}
+
/// Holds inline fragments and absolute descendants.
#[derive(Clone)]
pub struct IntermediateInlineFragments {
@@ -222,7 +248,7 @@ impl InlineFragmentsAccumulator {
pseudo: node.get_pseudo_element_type().strip(),
style: node.style(style_context),
selected_style: node.selected_style(),
- flags: InlineFragmentNodeFlags::empty(),
+ flags: FIRST_FRAGMENT_OF_ELEMENT | LAST_FRAGMENT_OF_ELEMENT,
}),
bidi_control_chars: None,
restyle_damage: node.restyle_damage(),
@@ -245,19 +271,21 @@ impl InlineFragmentsAccumulator {
bidi_control_chars,
restyle_damage,
} = self;
- if let Some(enclosing_node) = enclosing_node {
+ if let Some(mut enclosing_node) = enclosing_node {
let fragment_count = fragments.fragments.len();
for (index, fragment) in fragments.fragments.iter_mut().enumerate() {
let mut enclosing_node = enclosing_node.clone();
- if index == 0 {
- enclosing_node.flags.insert(FIRST_FRAGMENT_OF_ELEMENT)
+ if index != 0 {
+ enclosing_node.flags.remove(FIRST_FRAGMENT_OF_ELEMENT)
}
- if index == fragment_count - 1 {
- enclosing_node.flags.insert(LAST_FRAGMENT_OF_ELEMENT)
+ if index != fragment_count - 1 {
+ enclosing_node.flags.remove(LAST_FRAGMENT_OF_ELEMENT)
}
fragment.add_inline_context_style(enclosing_node);
}
+ enclosing_node.flags.remove(FIRST_FRAGMENT_OF_ELEMENT | LAST_FRAGMENT_OF_ELEMENT);
+
// Control characters are later discarded in transform_text, so they don't affect the
// is_first/is_last styles above.
if let Some((start, end)) = bidi_control_chars {
@@ -715,14 +743,8 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
} = split;
fragment_accumulator.push_all(predecessors);
- let split = InlineBlockSplit {
- predecessors: mem::replace(
- fragment_accumulator,
- InlineFragmentsAccumulator::from_inline_node(
- node, self.style_context())).to_intermediate_inline_fragments(),
- flow: kid_flow,
- };
- opt_inline_block_splits.push_back(split)
+ opt_inline_block_splits.push_back(
+ InlineBlockSplit::new(fragment_accumulator, node, self.style_context(), kid_flow));
}
}
@@ -749,17 +771,8 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
ConstructionResult::None => {}
ConstructionResult::Flow(flow, kid_abs_descendants) => {
if !flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
- // {ib} split. Flush the accumulator to our new split and make a new
- // accumulator to hold any subsequent fragments we come across.
- let split = InlineBlockSplit {
- predecessors:
- mem::replace(
- &mut fragment_accumulator,
- InlineFragmentsAccumulator::from_inline_node(
- node, self.style_context())).to_intermediate_inline_fragments(),
- flow: flow,
- };
- opt_inline_block_splits.push_back(split);
+ opt_inline_block_splits.push_back(InlineBlockSplit::new(
+ &mut fragment_accumulator, node, self.style_context(), flow));
abs_descendants.push_descendants(kid_abs_descendants);
} else {
// Push the absolutely-positioned kid as an inline containing block.