Merge pull request #3458 from pcwalton/whitespace-nowrap

layout: Implement `white-space: nowrap`.
This commit is contained in:
Patrick Walton 2014-09-23 20:22:33 -07:00
commit d9f836bc75
6 changed files with 122 additions and 15 deletions

View file

@ -253,6 +253,16 @@ pub fn each_char_index(range: &Range<LineIndices>) -> EachIndex<int, CharIndex>
range::each_index(range.begin().char_index, range.end().char_index) 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 { struct LineBreaker {
pub floats: Floats, pub floats: Floats,
pub new_fragments: Vec<Fragment>, pub new_fragments: Vec<Fragment>,
@ -323,8 +333,13 @@ impl LineBreaker {
}; };
let fragment_was_appended = match cur_fragment.white_space() { 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::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 { 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 /// Tries to append the given fragment to the line, splitting it if necessary. Returns false if
/// we should break the line. /// and only if we should break the line.
fn try_append_to_line(&mut self, in_fragment: Fragment, flow: &InlineFlow, layout_context: &LayoutContext) -> bool { ///
/// `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(); let line_is_empty = self.pending_line.range.length() == num::zero();
if line_is_empty { if line_is_empty {
let (line_bounds, _) = self.initial_line_placement(&in_fragment, self.cur_b, flow); let (line_bounds, _) = self.initial_line_placement(&in_fragment, self.cur_b, flow);
@ -546,16 +568,14 @@ impl LineBreaker {
return true 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? // 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 \ debug!("LineBreaker: case=fragment can't split and line {:u} is empty, so \
overflowing.", overflowing.",
self.lines.len()); self.lines.len());
self.push_fragment_to_line(in_fragment); self.push_fragment_to_line(in_fragment);
return true return true
} }
}
let available_inline_size = green_zone.inline - self.pending_line.bounds.size.inline; let available_inline_size = green_zone.inline - self.pending_line.bounds.size.inline;
let split = in_fragment.find_split_info_for_inline_size(CharIndex(0), available_inline_size, line_is_empty); let split = in_fragment.find_split_info_for_inline_size(CharIndex(0), available_inline_size, line_is_empty);

View file

@ -124,7 +124,7 @@ impl TextRunScanner {
let font_style = old_fragment.font_style(); let font_style = old_fragment.font_style();
let compression = match old_fragment.white_space() { let compression = match old_fragment.white_space() {
white_space::normal => CompressWhitespaceNewline, white_space::normal | white_space::nowrap => CompressWhitespaceNewline,
white_space::pre => CompressNone, white_space::pre => CompressNone,
}; };
@ -168,7 +168,7 @@ impl TextRunScanner {
let fontgroup = font_context.get_layout_font_group_for_style(&font_style); let fontgroup = font_context.get_layout_font_group_for_style(&font_style);
let compression = match in_fragment.white_space() { let compression = match in_fragment.white_space() {
white_space::normal => CompressWhitespaceNewline, white_space::normal | white_space::nowrap => CompressWhitespaceNewline,
white_space::pre => CompressNone, white_space::pre => CompressNone,
}; };

View file

@ -1067,7 +1067,7 @@ pub mod longhands {
} }
</%self:longhand> </%self:longhand>
${single_keyword("white-space", "normal pre")} ${single_keyword("white-space", "normal pre nowrap")}
// CSS 2.1, Section 17 - Tables // CSS 2.1, Section 17 - Tables
${new_style_struct("Table", is_inherited=False)} ${new_style_struct("Table", is_inherited=False)}

View file

@ -141,3 +141,4 @@ flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html
== float_clearance_a.html float_clearance_ref.html == float_clearance_a.html float_clearance_ref.html
== block_formatting_context_a.html block_formatting_context_ref.html == block_formatting_context_a.html block_formatting_context_ref.html
== inline_block_parent_padding_a.html inline_block_parent_padding_ref.html == inline_block_parent_padding_a.html inline_block_parent_padding_ref.html
== whitespace_nowrap_a.html whitespace_nowrap_ref.html

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div style="white-space: nowrap;">
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
</div>
</body>
</html>

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div style="width: 9999999px;">
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA I DON'T WANNA
</div>
</body>
</html>