aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/construct.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout/construct.rs')
-rw-r--r--components/layout/construct.rs118
1 files changed, 54 insertions, 64 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 82bff208604..58747ca13e9 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -30,10 +30,9 @@ use flow_ref::FlowRef;
use fragment::{Fragment, GenericFragment, IframeFragment, IframeFragmentInfo, ImageFragment};
use fragment::{ImageFragmentInfo, InlineAbsoluteHypotheticalFragment};
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, InlineBlockFragment};
-use fragment::{InlineBlockFragmentInfo, InputFragment, InputFragmentInfo, SpecificFragmentInfo};
-use fragment::{TableCellFragment, TableColumnFragment, TableColumnFragmentInfo, TableFragment};
-use fragment::{TableRowFragment, TableWrapperFragment, UnscannedTextFragment};
-use fragment::{UnscannedTextFragmentInfo};
+use fragment::{InlineBlockFragmentInfo, InputFragment, SpecificFragmentInfo, TableCellFragment};
+use fragment::{TableColumnFragment, TableColumnFragmentInfo, TableFragment, TableRowFragment};
+use fragment::{TableWrapperFragment, UnscannedTextFragment, UnscannedTextFragmentInfo};
use inline::{InlineFragments, InlineFlow};
use parallel;
use table_wrapper::TableWrapperFlow;
@@ -44,7 +43,7 @@ use table_rowgroup::TableRowGroupFlow;
use table_row::TableRowFlow;
use table_cell::TableCellFlow;
use text::TextRunScanner;
-use util::{LayoutDataAccess, OpaqueNodeMethods};
+use util::{LayoutDataAccess, OpaqueNodeMethods, LayoutDataWrapper};
use wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode};
use wrapper::{Before, After, Normal};
@@ -81,6 +80,22 @@ pub enum ConstructionResult {
ConstructionItemConstructionResult(ConstructionItem),
}
+impl ConstructionResult {
+ pub fn swap_out(&mut self, layout_context: &LayoutContext) -> ConstructionResult {
+ if layout_context.shared.opts.incremental_layout {
+ match *self {
+ NoConstructionResult =>
+ return NoConstructionResult,
+ FlowConstructionResult(ref flow_ref, ref abs_descendants) =>
+ return FlowConstructionResult((*flow_ref).clone(), (*abs_descendants).clone()),
+ ConstructionItemConstructionResult(_) => {},
+ }
+ }
+
+ mem::replace(self, NoConstructionResult)
+ }
+}
+
/// Represents the output of flow construction for a DOM node that has not yet resulted in a
/// complete flow. Construction items bubble up the tree until they find a `Flow` to be attached
/// to.
@@ -222,21 +237,6 @@ impl<'a> FlowConstructor<'a> {
}
}
- fn build_fragment_info_for_input(&mut self, node: &ThreadSafeLayoutNode) -> SpecificFragmentInfo {
- //FIXME: would it make more sense to use HTMLInputElement::input_type instead of the raw
- // value? definitely for string comparisons.
- let elem = node.as_element();
- let data = match elem.get_attr(&ns!(""), &atom!("type")) {
- Some("checkbox") | Some("radio") => None,
- Some("button") | Some("submit") | Some("reset") =>
- Some(node.get_input_value().len() as u32),
- Some("file") => Some(node.get_input_size()),
- _ => Some(node.get_input_size()),
- };
- data.map(|size| InputFragment(InputFragmentInfo { size: size }))
- .unwrap_or(GenericFragment)
- }
-
/// Builds specific `Fragment` info for the given node.
///
/// This does *not* construct the text for generated content (but, for generated content with
@@ -253,7 +253,7 @@ impl<'a> FlowConstructor<'a> {
self.build_fragment_info_for_image(node, node.image_url())
}
Some(ElementNodeTypeId(HTMLInputElementTypeId)) => {
- self.build_fragment_info_for_input(node)
+ InputFragment
}
Some(ElementNodeTypeId(HTMLObjectElementTypeId)) => {
let data = node.get_object_data();
@@ -361,7 +361,7 @@ impl<'a> FlowConstructor<'a> {
&mut InlineFragmentsAccumulator,
abs_descendants: &mut Descendants,
first_fragment: &mut bool) {
- match kid.swap_out_construction_result() {
+ match kid.swap_out_construction_result(self.layout_context) {
NoConstructionResult => {}
FlowConstructionResult(kid_flow, kid_abs_descendants) => {
// If kid_flow is TableCaptionFlow, kid_flow should be added under
@@ -562,7 +562,7 @@ impl<'a> FlowConstructor<'a> {
if kid.get_pseudo_element_type() != Normal {
self.process(&kid);
}
- match kid.swap_out_construction_result() {
+ match kid.swap_out_construction_result(self.layout_context) {
NoConstructionResult => {}
FlowConstructionResult(flow, kid_abs_descendants) => {
// {ib} split. Flush the accumulator to our new split and make a new
@@ -743,12 +743,13 @@ impl<'a> FlowConstructor<'a> {
table_wrapper_flow: &mut FlowRef,
node: &ThreadSafeLayoutNode) {
for kid in node.children() {
- match kid.swap_out_construction_result() {
+ match kid.swap_out_construction_result(self.layout_context) {
NoConstructionResult | ConstructionItemConstructionResult(_) => {}
FlowConstructionResult(kid_flow, _) => {
// Only kid flows with table-caption are matched here.
- assert!(kid_flow.get().is_table_caption());
- table_wrapper_flow.add_new_child(kid_flow);
+ if kid_flow.get().is_table_caption() {
+ table_wrapper_flow.add_new_child(kid_flow);
+ }
}
}
}
@@ -783,8 +784,8 @@ impl<'a> FlowConstructor<'a> {
flow.add_new_child(anonymous_flow);
}
- /// Builds a flow for a node with `display: table`. This yields a `TableWrapperFlow` with possibly
- /// other `TableCaptionFlow`s or `TableFlow`s underneath it.
+ /// Builds a flow for a node with `display: table`. This yields a `TableWrapperFlow` with
+ /// possibly other `TableCaptionFlow`s or `TableFlow`s underneath it.
fn build_flow_for_table_wrapper(&mut self, node: &ThreadSafeLayoutNode,
float_value: float::T) -> ConstructionResult {
let fragment = Fragment::new_from_specific_info(node, TableWrapperFragment);
@@ -905,7 +906,7 @@ impl<'a> FlowConstructor<'a> {
for kid in node.children() {
// CSS 2.1 § 17.2.1. Treat all non-column child fragments of `table-column-group`
// as `display: none`.
- match kid.swap_out_construction_result() {
+ match kid.swap_out_construction_result(self.layout_context) {
ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(
fragment)) => {
col_fragments.push(fragment);
@@ -974,7 +975,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
// results of children.
(display::none, _, _) => {
for child in node.children() {
- drop(child.swap_out_construction_result())
+ drop(child.swap_out_construction_result(self.layout_context))
}
}
@@ -1079,12 +1080,14 @@ trait NodeUtils {
/// Returns true if this node doesn't render its kids and false otherwise.
fn is_replaced_content(&self) -> bool;
+ fn get_construction_result<'a>(self, layout_data: &'a mut LayoutDataWrapper) -> &'a mut ConstructionResult;
+
/// Sets the construction result of a flow.
- fn set_flow_construction_result(&self, result: ConstructionResult);
+ fn set_flow_construction_result(self, result: ConstructionResult);
/// Replaces the flow construction result in a node with `NoConstructionResult` and returns the
/// old value.
- fn swap_out_construction_result(&self) -> ConstructionResult;
+ fn swap_out_construction_result(self, layout_context: &LayoutContext) -> ConstructionResult;
}
impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
@@ -1103,43 +1106,30 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
}
}
+ fn get_construction_result<'a>(self, layout_data: &'a mut LayoutDataWrapper) -> &'a mut ConstructionResult {
+ match self.get_pseudo_element_type() {
+ Before(_) => &mut layout_data.data.before_flow_construction_result,
+ After (_) => &mut layout_data.data.after_flow_construction_result,
+ Normal => &mut layout_data.data.flow_construction_result,
+ }
+ }
+
#[inline(always)]
- fn set_flow_construction_result(&self, result: ConstructionResult) {
+ fn set_flow_construction_result(self, result: ConstructionResult) {
let mut layout_data_ref = self.mutate_layout_data();
- match &mut *layout_data_ref {
- &Some(ref mut layout_data) =>{
- match self.get_pseudo_element_type() {
- Before(_) => layout_data.data.before_flow_construction_result = result,
- After(_) => layout_data.data.after_flow_construction_result = result,
- Normal => layout_data.data.flow_construction_result = result,
- }
- },
- &None => fail!("no layout data"),
- }
+ let layout_data = layout_data_ref.as_mut().expect("no layout data");
+
+ let dst = self.get_construction_result(layout_data);
+
+ *dst = result;
}
#[inline(always)]
- fn swap_out_construction_result(&self) -> ConstructionResult {
+ fn swap_out_construction_result(self, layout_context: &LayoutContext) -> ConstructionResult {
let mut layout_data_ref = self.mutate_layout_data();
- match &mut *layout_data_ref {
- &Some(ref mut layout_data) => {
- match self.get_pseudo_element_type() {
- Before(_) => {
- mem::replace(&mut layout_data.data.before_flow_construction_result,
- NoConstructionResult)
- }
- After(_) => {
- mem::replace(&mut layout_data.data.after_flow_construction_result,
- NoConstructionResult)
- }
- Normal => {
- mem::replace(&mut layout_data.data.flow_construction_result,
- NoConstructionResult)
- }
- }
- }
- &None => fail!("no layout data"),
- }
+ let layout_data = layout_data_ref.as_mut().expect("no layout data");
+
+ self.get_construction_result(layout_data).swap_out(layout_context)
}
}
@@ -1216,7 +1206,7 @@ impl FlowConstructionUtils for FlowRef {
/// This must not be public because only the layout constructor can do this.
fn finish(&mut self, context: &LayoutContext) {
if !context.shared.opts.bubble_inline_sizes_separately {
- self.get_mut().bubble_inline_sizes(context)
+ self.get_mut().bubble_inline_sizes()
}
}
}