diff --git a/components/layout/flex.rs b/components/layout/flex.rs index 452c68750313..da76775be93c 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -27,6 +27,7 @@ use std::cmp::{max, min}; use std::sync::Arc; use style::computed_values::flex_direction; use style::computed_values::{box_sizing, border_collapse}; +use style::computed_values::flex_wrap; use style::context::SharedStyleContext; use style::logical_geometry::LogicalSize; use style::properties::ServoComputedValues; @@ -276,19 +277,41 @@ pub struct FlexFlow { /// List of flex-items that belong to this flex-container items: Vec, /// True if the flex-direction is *-reversed - is_reverse: bool + main_reverse: bool, + /// True if this flex container can be multiline. + is_wrappable: bool, + /// True if the cross direction is reversed. + cross_reverse: bool } impl FlexFlow { pub fn from_fragment(fragment: Fragment, flotation: Option) -> FlexFlow { - let (main_mode, is_reverse) = match fragment.style.get_position().flex_direction { - flex_direction::T::row => (Mode::Inline, false), - flex_direction::T::row_reverse => (Mode::Inline, true), - flex_direction::T::column => (Mode::Block, false), - flex_direction::T::column_reverse => (Mode::Block, true), - }; + let main_mode; + let main_reverse; + let is_wrappable; + let cross_reverse; + { + let style = fragment.style(); + let (mode, reverse) = match style.get_position().flex_direction { + flex_direction::T::row => (Mode::Inline, false), + flex_direction::T::row_reverse => (Mode::Inline, true), + flex_direction::T::column => (Mode::Block, false), + flex_direction::T::column_reverse => (Mode::Block, true), + }; + main_mode = mode; + main_reverse = + reverse == style.writing_mode.is_bidi_ltr(); + let (wrappable, reverse) = match fragment.style.get_position().flex_wrap { + flex_wrap::T::nowrap => (false, false), + flex_wrap::T::wrap => (true, false), + flex_wrap::T::wrap_reverse => (true, true), + }; + is_wrappable = wrappable; + // TODO(stshine): Handle vertical writing mode. + cross_reverse = reverse; + } FlexFlow { block_flow: BlockFlow::from_fragment(fragment, flotation), @@ -296,7 +319,9 @@ impl FlexFlow { available_main_size: AxisSize::Infinite, available_cross_size: AxisSize::Infinite, items: Vec::new(), - is_reverse: is_reverse + main_reverse: main_reverse, + is_wrappable: is_wrappable, + cross_reverse: cross_reverse } } @@ -430,7 +455,7 @@ impl FlexFlow { self.block_flow.base.position.size.inline = inline_size; let block_container_explicit_block_size = self.block_flow.base.block_container_explicit_block_size; - let mut inline_child_start = if !self.is_reverse { + let mut inline_child_start = if !self.main_reverse { inline_start_content_edge } else { self.block_flow.fragment.border_box.size.inline @@ -441,7 +466,7 @@ impl FlexFlow { base.block_container_inline_size = even_content_inline_size; base.block_container_writing_mode = container_mode; base.block_container_explicit_block_size = block_container_explicit_block_size; - if !self.is_reverse { + if !self.main_reverse { base.position.start.i = inline_child_start; inline_child_start = inline_child_start + even_content_inline_size; } else { @@ -453,14 +478,14 @@ impl FlexFlow { // TODO(zentner): This function should actually flex elements! fn block_mode_assign_block_size<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { - let mut cur_b = if !self.is_reverse { + let mut cur_b = if !self.main_reverse { self.block_flow.fragment.border_padding.block_start } else { self.block_flow.fragment.border_box.size.block }; for kid in &mut self.items { let base = flow::mut_base(flow_ref::deref_mut(&mut kid.flow)); - if !self.is_reverse { + if !self.main_reverse { base.position.start.b = cur_b; cur_b = cur_b + base.position.size.block; } else {