diff --git a/components/layout/inline.rs b/components/layout/inline.rs index bdae0326323..613cd27a3d1 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -253,6 +253,16 @@ pub fn each_char_index(range: &Range) -> EachIndex range::each_index(range.begin().char_index, range.end().char_index) } +/// The line wrapping mode, controlled by the `white-space` property as described in CSS 2.1 ยง +/// 16.6. +#[deriving(PartialEq, Eq)] +enum WrapMode { + /// `normal`. + WrapNormally, + /// `nowrap`. + NoWrap, +} + struct LineBreaker { pub floats: Floats, pub new_fragments: Vec, @@ -323,8 +333,13 @@ impl LineBreaker { }; let fragment_was_appended = match cur_fragment.white_space() { - white_space::normal => self.try_append_to_line(cur_fragment, flow, layout_context), + white_space::normal => { + self.try_append_to_line(cur_fragment, flow, layout_context, WrapNormally) + } white_space::pre => self.try_append_to_line_by_new_line(cur_fragment), + white_space::nowrap => { + self.try_append_to_line(cur_fragment, flow, layout_context, NoWrap) + } }; if !fragment_was_appended { @@ -506,9 +521,16 @@ impl LineBreaker { } } - /// Tries to append the given fragment to the line, splitting it if necessary. Returns false only if - /// we should break the line. - fn try_append_to_line(&mut self, in_fragment: Fragment, flow: &InlineFlow, layout_context: &LayoutContext) -> bool { + /// Tries to append the given fragment to the line, splitting it if necessary. Returns false if + /// and only if we should break the line. + /// + /// `wrap_mode` controls whether wrapping happens. + fn try_append_to_line(&mut self, + in_fragment: Fragment, + flow: &InlineFlow, + layout_context: &LayoutContext, + wrap_mode: WrapMode) + -> bool { let line_is_empty = self.pending_line.range.length() == num::zero(); if line_is_empty { let (line_bounds, _) = self.initial_line_placement(&in_fragment, self.cur_b, flow); @@ -546,15 +568,13 @@ impl LineBreaker { return true } - if !in_fragment.can_split() { + if (!in_fragment.can_split() && line_is_empty) || wrap_mode == NoWrap { // TODO(eatkinson, issue #224): Signal that horizontal overflow happened? - if line_is_empty { - debug!("LineBreaker: case=fragment can't split and line {:u} is empty, so \ - overflowing.", - self.lines.len()); - self.push_fragment_to_line(in_fragment); - return true - } + debug!("LineBreaker: case=fragment can't split and line {:u} is empty, so \ + overflowing.", + self.lines.len()); + self.push_fragment_to_line(in_fragment); + return true } let available_inline_size = green_zone.inline - self.pending_line.bounds.size.inline; diff --git a/components/layout/text.rs b/components/layout/text.rs index 36384e24290..c297eb4efd0 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -124,7 +124,7 @@ impl TextRunScanner { let font_style = old_fragment.font_style(); let compression = match old_fragment.white_space() { - white_space::normal => CompressWhitespaceNewline, + white_space::normal | white_space::nowrap => CompressWhitespaceNewline, white_space::pre => CompressNone, }; @@ -168,7 +168,7 @@ impl TextRunScanner { let fontgroup = font_context.get_layout_font_group_for_style(&font_style); let compression = match in_fragment.white_space() { - white_space::normal => CompressWhitespaceNewline, + white_space::normal | white_space::nowrap => CompressWhitespaceNewline, white_space::pre => CompressNone, }; diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako index d45a413caaf..c7ddd0ca6fe 100644 --- a/components/style/properties/mod.rs.mako +++ b/components/style/properties/mod.rs.mako @@ -1067,7 +1067,7 @@ pub mod longhands { } - ${single_keyword("white-space", "normal pre")} + ${single_keyword("white-space", "normal pre nowrap")} // CSS 2.1, Section 17 - Tables ${new_style_struct("Table", is_inherited=False)} diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 88c40413d69..6ab046437ce 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -141,3 +141,4 @@ flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html == float_clearance_a.html float_clearance_ref.html == block_formatting_context_a.html block_formatting_context_ref.html == inline_block_parent_padding_a.html inline_block_parent_padding_ref.html +== whitespace_nowrap_a.html whitespace_nowrap_ref.html diff --git a/tests/ref/whitespace_nowrap_a.html b/tests/ref/whitespace_nowrap_a.html new file mode 100644 index 00000000000..6fb4e6ac8e8 --- /dev/null +++ b/tests/ref/whitespace_nowrap_a.html @@ -0,0 +1,43 @@ + + + + + +
+ I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA +
+ + + + diff --git a/tests/ref/whitespace_nowrap_ref.html b/tests/ref/whitespace_nowrap_ref.html new file mode 100644 index 00000000000..dcb56fefb81 --- /dev/null +++ b/tests/ref/whitespace_nowrap_ref.html @@ -0,0 +1,43 @@ + + + + + +
+ I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA + I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA +
+ + + +