diff options
Diffstat (limited to 'components/layout/construct.rs')
-rw-r--r-- | components/layout/construct.rs | 118 |
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() } } } |