mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Handle all white-space
values when intrinsically sizing an IFC (#33343)
There were various cases like `text-wrap-mode: nowrap` and `white-space-collapse: break-spaces` that weren't handled well. Fixes #33335 flexbox_flex-formatting-interop.html fails now because we don't support `table-layout: fixed`. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
777fb81260
commit
d9be9d6bd4
10 changed files with 351 additions and 45 deletions
|
@ -291,15 +291,17 @@ bitflags! {
|
|||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct ShapingFlags: u8 {
|
||||
/// Set if the text is entirely whitespace.
|
||||
const IS_WHITESPACE_SHAPING_FLAG = 0x01;
|
||||
const IS_WHITESPACE_SHAPING_FLAG = 1 << 0;
|
||||
/// Set if the text ends with whitespace.
|
||||
const ENDS_WITH_WHITESPACE_SHAPING_FLAG = 1 << 1;
|
||||
/// Set if we are to ignore ligatures.
|
||||
const IGNORE_LIGATURES_SHAPING_FLAG = 0x02;
|
||||
const IGNORE_LIGATURES_SHAPING_FLAG = 1 << 2;
|
||||
/// Set if we are to disable kerning.
|
||||
const DISABLE_KERNING_SHAPING_FLAG = 0x04;
|
||||
const DISABLE_KERNING_SHAPING_FLAG = 1 << 3;
|
||||
/// Text direction is right-to-left.
|
||||
const RTL_FLAG = 0x08;
|
||||
const RTL_FLAG = 1 << 4;
|
||||
/// Set if word-break is set to keep-all.
|
||||
const KEEP_ALL_FLAG = 0x10;
|
||||
const KEEP_ALL_FLAG = 1 << 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,6 +346,9 @@ impl Font {
|
|||
options
|
||||
.flags
|
||||
.contains(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG),
|
||||
options
|
||||
.flags
|
||||
.contains(ShapingFlags::ENDS_WITH_WHITESPACE_SHAPING_FLAG),
|
||||
is_single_preserved_newline,
|
||||
options.flags.contains(ShapingFlags::RTL_FLAG),
|
||||
);
|
||||
|
@ -946,10 +951,10 @@ mod test {
|
|||
|
||||
assert!(font.can_do_fast_shaping(text, &shaping_options));
|
||||
|
||||
let mut expected_glyphs = GlyphStore::new(text.len(), false, false, false);
|
||||
let mut expected_glyphs = GlyphStore::new(text.len(), false, false, false, false);
|
||||
font.shape_text_harfbuzz(text, &shaping_options, &mut expected_glyphs);
|
||||
|
||||
let mut glyphs = GlyphStore::new(text.len(), false, false, false);
|
||||
let mut glyphs = GlyphStore::new(text.len(), false, false, false, false);
|
||||
font.shape_text_fast(text, &shaping_options, &mut glyphs);
|
||||
|
||||
assert_eq!(glyphs.len(), expected_glyphs.len());
|
||||
|
|
|
@ -446,6 +446,11 @@ pub struct GlyphStore {
|
|||
/// Whether or not this glyph store contains only glyphs for whitespace.
|
||||
is_whitespace: bool,
|
||||
|
||||
/// Whether or not this glyph store ends with whitespace glyphs.
|
||||
/// Typically whitespace glyphs are placed in a separate store,
|
||||
/// but that may not be the case with `white-space: break-spaces`.
|
||||
ends_with_whitespace: bool,
|
||||
|
||||
/// Whether or not this glyph store contains only a single glyph for a single
|
||||
/// preserved newline.
|
||||
is_single_preserved_newline: bool,
|
||||
|
@ -460,6 +465,7 @@ impl<'a> GlyphStore {
|
|||
pub fn new(
|
||||
length: usize,
|
||||
is_whitespace: bool,
|
||||
ends_with_whitespace: bool,
|
||||
is_single_preserved_newline: bool,
|
||||
is_rtl: bool,
|
||||
) -> GlyphStore {
|
||||
|
@ -472,6 +478,7 @@ impl<'a> GlyphStore {
|
|||
total_word_separators: 0,
|
||||
has_detailed_glyphs: false,
|
||||
is_whitespace,
|
||||
ends_with_whitespace,
|
||||
is_single_preserved_newline,
|
||||
is_rtl,
|
||||
}
|
||||
|
@ -492,6 +499,11 @@ impl<'a> GlyphStore {
|
|||
self.is_whitespace
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn ends_with_whitespace(&self) -> bool {
|
||||
self.ends_with_whitespace
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn total_word_separators(&self) -> usize {
|
||||
self.total_word_separators
|
||||
|
|
|
@ -2275,11 +2275,14 @@ struct ContentSizesComputation<'layout_data> {
|
|||
containing_block: &'layout_data IndefiniteContainingBlock<'layout_data>,
|
||||
paragraph: ContentSizes,
|
||||
current_line: ContentSizes,
|
||||
/// Size for whitepsace pending to be added to this line.
|
||||
pending_whitespace: Au,
|
||||
/// Size for whitespace pending to be added to this line.
|
||||
pending_whitespace: ContentSizes,
|
||||
/// Whether or not the current line has seen any content (excluding collapsed whitespace),
|
||||
/// when sizing under a min-content constraint.
|
||||
had_content_yet_for_min_content: bool,
|
||||
/// Whether or not the current line has seen any content (excluding collapsed whitespace),
|
||||
/// when sizing under a max-content constraint.
|
||||
had_content_yet: bool,
|
||||
had_content_yet_for_max_content: bool,
|
||||
/// Stack of ending padding, margin, and border to add to the length
|
||||
/// when an inline box finishes.
|
||||
ending_inline_pbm_stack: Vec<Au>,
|
||||
|
@ -2345,6 +2348,8 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
|
|||
|
||||
for run in segment.runs.iter() {
|
||||
let advance = run.glyph_store.total_advance();
|
||||
let style_text = text_run.parent_style.get_inherited_text();
|
||||
let can_wrap = style_text.text_wrap_mode == TextWrapMode::Wrap;
|
||||
|
||||
if run.glyph_store.is_whitespace() {
|
||||
// If this run is a forced line break, we *must* break the line
|
||||
|
@ -2354,31 +2359,38 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
|
|||
self.current_line = ContentSizes::zero();
|
||||
continue;
|
||||
}
|
||||
|
||||
let style_text = text_run.parent_style.get_inherited_text();
|
||||
if style_text.white_space_collapse != WhiteSpaceCollapse::Preserve {
|
||||
// TODO: need to handle TextWrapMode::Nowrap.
|
||||
self.line_break_opportunity();
|
||||
// Discard any leading whitespace in the line. This will always be trimmed.
|
||||
if self.had_content_yet {
|
||||
// Wait to take into account other whitespace until we see more content.
|
||||
// Whitespace at the end of the line will always be trimmed.
|
||||
self.pending_whitespace += advance;
|
||||
if !matches!(
|
||||
style_text.white_space_collapse,
|
||||
WhiteSpaceCollapse::Preserve | WhiteSpaceCollapse::BreakSpaces
|
||||
) {
|
||||
if can_wrap {
|
||||
self.line_break_opportunity();
|
||||
} else if self.had_content_yet_for_min_content {
|
||||
self.pending_whitespace.min_content += advance;
|
||||
}
|
||||
if self.had_content_yet_for_max_content {
|
||||
self.pending_whitespace.max_content += advance;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if style_text.text_wrap_mode == TextWrapMode::Wrap {
|
||||
if can_wrap {
|
||||
self.pending_whitespace.max_content += advance;
|
||||
self.commit_pending_whitespace();
|
||||
self.line_break_opportunity();
|
||||
self.current_line.max_content += advance;
|
||||
self.had_content_yet = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
self.commit_pending_whitespace();
|
||||
self.add_inline_size(advance);
|
||||
self.had_content_yet = true;
|
||||
|
||||
// Typically whitespace glyphs are placed in a separate store,
|
||||
// but for `white-space: break-spaces` we place the first whitespace
|
||||
// with the preceding text. That prevents a line break before that
|
||||
// first space, but we still need to allow a line break after it.
|
||||
if can_wrap && run.glyph_store.ends_with_whitespace() {
|
||||
self.line_break_opportunity();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2405,7 +2417,6 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
|
|||
|
||||
self.commit_pending_whitespace();
|
||||
self.current_line += outer;
|
||||
self.had_content_yet = true;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
@ -2417,9 +2428,14 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
|
|||
}
|
||||
|
||||
fn line_break_opportunity(&mut self) {
|
||||
// Clear the pending whitespace, assuming that at the end of the line
|
||||
// it needs to either hang or be removed. If that isn't the case,
|
||||
// `commit_pending_whitespace()` should be called first.
|
||||
self.pending_whitespace.min_content = Au::zero();
|
||||
self.paragraph.min_content =
|
||||
std::cmp::max(self.paragraph.min_content, self.current_line.min_content);
|
||||
self.current_line.min_content = Au::zero();
|
||||
self.had_content_yet_for_min_content = false;
|
||||
}
|
||||
|
||||
fn forced_line_break(&mut self) {
|
||||
|
@ -2427,15 +2443,14 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
|
|||
self.paragraph.max_content =
|
||||
std::cmp::max(self.paragraph.max_content, self.current_line.max_content);
|
||||
self.current_line.max_content = Au::zero();
|
||||
self.had_content_yet = false;
|
||||
self.had_content_yet_for_min_content = false;
|
||||
self.had_content_yet_for_max_content = false;
|
||||
}
|
||||
|
||||
fn commit_pending_whitespace(&mut self) {
|
||||
// Only add the pending whitespace to the max-content size, because for the min-content
|
||||
// we should wrap lines wherever is possible, so wrappable spaces shouldn't increase
|
||||
// the length of the line (they will just be removed or hang at the end of the line).
|
||||
self.current_line.max_content += self.pending_whitespace;
|
||||
self.pending_whitespace = Au::zero();
|
||||
self.current_line += mem::take(&mut self.pending_whitespace);
|
||||
self.had_content_yet_for_min_content = true;
|
||||
self.had_content_yet_for_max_content = true;
|
||||
}
|
||||
|
||||
/// Compute the [`ContentSizes`] of the given [`InlineFormattingContext`].
|
||||
|
@ -2449,8 +2464,9 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
|
|||
containing_block,
|
||||
paragraph: ContentSizes::zero(),
|
||||
current_line: ContentSizes::zero(),
|
||||
pending_whitespace: Au::zero(),
|
||||
had_content_yet: false,
|
||||
pending_whitespace: ContentSizes::zero(),
|
||||
had_content_yet_for_min_content: false,
|
||||
had_content_yet_for_max_content: false,
|
||||
ending_inline_pbm_stack: Vec::new(),
|
||||
}
|
||||
.traverse(inline_formatting_context)
|
||||
|
|
|
@ -217,6 +217,8 @@ impl TextRunSegment {
|
|||
continue;
|
||||
}
|
||||
|
||||
let mut options = *shaping_options;
|
||||
|
||||
// Extend the slice to the next UAX#14 line break opportunity.
|
||||
let mut slice = last_slice.end..*break_index;
|
||||
let word = &formatting_context_text[slice.clone()];
|
||||
|
@ -247,6 +249,9 @@ impl TextRunSegment {
|
|||
!can_break_anywhere
|
||||
{
|
||||
whitespace.start += first_white_space_character.len_utf8();
|
||||
options
|
||||
.flags
|
||||
.insert(ShapingFlags::ENDS_WITH_WHITESPACE_SHAPING_FLAG);
|
||||
}
|
||||
|
||||
slice.end = whitespace.start;
|
||||
|
@ -267,17 +272,17 @@ impl TextRunSegment {
|
|||
|
||||
// Push the non-whitespace part of the range.
|
||||
if !slice.is_empty() {
|
||||
self.shape_and_push_range(&slice, formatting_context_text, &font, shaping_options);
|
||||
self.shape_and_push_range(&slice, formatting_context_text, &font, &options);
|
||||
}
|
||||
|
||||
if whitespace.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut options = *shaping_options;
|
||||
options
|
||||
.flags
|
||||
.insert(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG);
|
||||
options.flags.insert(
|
||||
ShapingFlags::IS_WHITESPACE_SHAPING_FLAG |
|
||||
ShapingFlags::ENDS_WITH_WHITESPACE_SHAPING_FLAG,
|
||||
);
|
||||
|
||||
// If `white-space-collapse: break-spaces` is active, insert a line breaking opportunity
|
||||
// between each white space character in the white space that we trimmed off.
|
||||
|
|
7
tests/wpt/meta/MANIFEST.json
vendored
7
tests/wpt/meta/MANIFEST.json
vendored
|
@ -566837,6 +566837,13 @@
|
|||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"white-space-intrinsic-size-021.html": [
|
||||
"a209f72c30a5a48ed4c185f9d3962abeb68399fb",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
]
|
||||
},
|
||||
"word-break": {
|
||||
|
|
2
tests/wpt/meta/css/css-flexbox/flexbox_flex-formatting-interop.html.ini
vendored
Normal file
2
tests/wpt/meta/css/css-flexbox/flexbox_flex-formatting-interop.html.ini
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
[flexbox_flex-formatting-interop.html]
|
||||
expected: FAIL
|
|
@ -2,8 +2,5 @@
|
|||
[table 1]
|
||||
expected: FAIL
|
||||
|
||||
[table 3]
|
||||
expected: FAIL
|
||||
|
||||
[table 6]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-intrinsic-size-002.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white_space_intrinsic_sizes_a.html]
|
||||
expected: FAIL
|
266
tests/wpt/tests/css/css-text/white-space/white-space-intrinsic-size-021.html
vendored
Normal file
266
tests/wpt/tests/css/css-text/white-space/white-space-intrinsic-size-021.html
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Text level 4 Test: intrinsic sizes of block containers with various 'white-space' values</title>
|
||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-text-4/#white-space-property">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
|
||||
|
||||
<link rel="stylesheet" href="/fonts/ahem.css">
|
||||
<style>
|
||||
.container {
|
||||
font: 10px / 1 Ahem;
|
||||
color: gray;
|
||||
}
|
||||
.container.narrow {
|
||||
float: left;
|
||||
width: 0;
|
||||
margin-right: 50px;
|
||||
}
|
||||
.container.wide {
|
||||
width: 800px;
|
||||
}
|
||||
.container > div {
|
||||
display: inline-block;
|
||||
border: solid black;
|
||||
}
|
||||
hr {
|
||||
clear: both;
|
||||
}
|
||||
.collapse.wrap {
|
||||
white-space: normal;
|
||||
}
|
||||
.collapse.nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.preserve.wrap {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.preserve.nowrap {
|
||||
white-space: pre;
|
||||
}
|
||||
.preserve-breaks.wrap {
|
||||
white-space: preserve-breaks;
|
||||
}
|
||||
.preserve-breaks.nowrap {
|
||||
white-space: preserve-breaks nowrap;
|
||||
}
|
||||
.break-spaces.wrap {
|
||||
white-space: break-spaces;
|
||||
}
|
||||
.break-spaces.nowrap {
|
||||
white-space: break-spaces nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container narrow">
|
||||
<div class="collapse wrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="collapse nowrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="preserve wrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="preserve nowrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="break-spaces wrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
</div>
|
||||
<div class="container narrow">
|
||||
<div class="collapse wrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="collapse nowrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="preserve wrap" data-expected-client-width= "0" data-expected-client-height="10"> </div>
|
||||
<div class="preserve nowrap" data-expected-client-width="10" data-expected-client-height="10"> </div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="10" data-expected-client-height="10"> </div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="10" data-expected-client-height="10"> </div>
|
||||
</div>
|
||||
<div class="container narrow">
|
||||
<div class="collapse wrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="collapse nowrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="preserve wrap" data-expected-client-width= "0" data-expected-client-height="10"> </div>
|
||||
<div class="preserve nowrap" data-expected-client-width="20" data-expected-client-height="10"> </div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="10" data-expected-client-height="20"> </div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="20" data-expected-client-height="10"> </div>
|
||||
</div>
|
||||
<div class="container narrow">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="collapse nowrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="preserve wrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="preserve nowrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
</div>
|
||||
<div class="container narrow">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="collapse nowrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve wrap" data-expected-client-width="10" data-expected-client-height="20"> X</div>
|
||||
<div class="preserve nowrap" data-expected-client-width="20" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="10" data-expected-client-height="20"> X</div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="20" data-expected-client-height="10"> X</div>
|
||||
</div>
|
||||
<div class="container narrow">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="collapse nowrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve wrap" data-expected-client-width="10" data-expected-client-height="20"> X</div>
|
||||
<div class="preserve nowrap" data-expected-client-width="30" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="10" data-expected-client-height="30"> X</div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="30" data-expected-client-height="10"> X</div>
|
||||
</div>
|
||||
<div class="container narrow">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="collapse nowrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="preserve wrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="preserve nowrap" data-expected-client-width="20" data-expected-client-height="10">X </div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="20" data-expected-client-height="10">X </div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="20" data-expected-client-height="10">X </div>
|
||||
</div>
|
||||
<div class="container narrow">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="collapse nowrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="preserve wrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="preserve nowrap" data-expected-client-width="30" data-expected-client-height="10">X </div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="20" data-expected-client-height="20">X </div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="30" data-expected-client-height="10">X </div>
|
||||
</div>
|
||||
<div class="container narrow">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="20">X É</div>
|
||||
<div class="collapse nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve wrap" data-expected-client-width="10" data-expected-client-height="20">X É</div>
|
||||
<div class="preserve nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="20">X É</div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="20" data-expected-client-height="20">X É</div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
</div>
|
||||
<div class="container narrow">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="20">X É</div>
|
||||
<div class="collapse nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve wrap" data-expected-client-width="10" data-expected-client-height="20">X É</div>
|
||||
<div class="preserve nowrap" data-expected-client-width="40" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="20">X É</div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="20" data-expected-client-height="20">X É</div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="40" data-expected-client-height="10">X É</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="container wide">
|
||||
<div class="collapse wrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="collapse nowrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="preserve wrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="preserve nowrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="break-spaces wrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width= "0" data-expected-client-height= "0"></div>
|
||||
</div>
|
||||
<div class="container wide">
|
||||
<div class="collapse wrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="collapse nowrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="preserve wrap" data-expected-client-width="10" data-expected-client-height="10"> </div>
|
||||
<div class="preserve nowrap" data-expected-client-width="10" data-expected-client-height="10"> </div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="10" data-expected-client-height="10"> </div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="10" data-expected-client-height="10"> </div>
|
||||
</div>
|
||||
<div class="container wide">
|
||||
<div class="collapse wrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="collapse nowrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="preserve wrap" data-expected-client-width="20" data-expected-client-height="10"> </div>
|
||||
<div class="preserve nowrap" data-expected-client-width="20" data-expected-client-height="10"> </div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width= "0" data-expected-client-height= "0"> </div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="20" data-expected-client-height="10"> </div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="20" data-expected-client-height="10"> </div>
|
||||
</div>
|
||||
<div class="container wide">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="collapse nowrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="preserve wrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="preserve nowrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="10" data-expected-client-height="10">X</div>
|
||||
</div>
|
||||
<div class="container wide">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="collapse nowrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve wrap" data-expected-client-width="20" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve nowrap" data-expected-client-width="20" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="20" data-expected-client-height="10"> X</div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="20" data-expected-client-height="10"> X</div>
|
||||
</div>
|
||||
<div class="container wide">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="collapse nowrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve wrap" data-expected-client-width="30" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve nowrap" data-expected-client-width="30" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="10" data-expected-client-height="10"> X</div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="30" data-expected-client-height="10"> X</div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="30" data-expected-client-height="10"> X</div>
|
||||
</div>
|
||||
<div class="container wide">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="collapse nowrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="preserve wrap" data-expected-client-width="20" data-expected-client-height="10">X </div>
|
||||
<div class="preserve nowrap" data-expected-client-width="20" data-expected-client-height="10">X </div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="20" data-expected-client-height="10">X </div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="20" data-expected-client-height="10">X </div>
|
||||
</div>
|
||||
<div class="container wide">
|
||||
<div class="collapse wrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="collapse nowrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="preserve wrap" data-expected-client-width="30" data-expected-client-height="10">X </div>
|
||||
<div class="preserve nowrap" data-expected-client-width="30" data-expected-client-height="10">X </div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="10" data-expected-client-height="10">X </div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="30" data-expected-client-height="10">X </div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="30" data-expected-client-height="10">X </div>
|
||||
</div>
|
||||
<div class="container wide">
|
||||
<div class="collapse wrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="collapse nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve wrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
</div>
|
||||
<div class="container wide">
|
||||
<div class="collapse wrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="collapse nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve wrap" data-expected-client-width="40" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve nowrap" data-expected-client-width="40" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve-breaks wrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="preserve-breaks nowrap" data-expected-client-width="30" data-expected-client-height="10">X É</div>
|
||||
<div class="break-spaces wrap" data-expected-client-width="40" data-expected-client-height="10">X É</div>
|
||||
<div class="break-spaces nowrap" data-expected-client-width="40" data-expected-client-height="10">X É</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/check-layout-th.js"></script>
|
||||
<script>
|
||||
checkLayout(".container > div");
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue