mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Implement basic white-space: pre support for layout 2020.
This commit is contained in:
parent
c7bdb1bcc0
commit
d8b4dab4e3
55 changed files with 167 additions and 113 deletions
|
@ -20,6 +20,7 @@ use rayon_croissant::ParallelIteratorExt;
|
|||
use servo_arc::Arc;
|
||||
use std::borrow::Cow;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use style::computed_values::white_space::T as WhiteSpace;
|
||||
use style::properties::longhands::list_style_position::computed_value::T as ListStylePosition;
|
||||
use style::properties::ComputedValues;
|
||||
use style::selector_parser::PseudoElement;
|
||||
|
@ -293,7 +294,8 @@ where
|
|||
}
|
||||
|
||||
fn handle_text(&mut self, info: &NodeAndStyleInfo<Node>, input: Cow<'dom, str>) {
|
||||
let (leading_whitespace, mut input) = self.handle_leading_whitespace(&input);
|
||||
let white_space = info.style.get_inherited_text().white_space;
|
||||
let (leading_whitespace, mut input) = self.handle_leading_whitespace(&input, white_space);
|
||||
if leading_whitespace || !input.is_empty() {
|
||||
// This text node should be pushed either to the next ongoing
|
||||
// inline level box with the parent style of that inline level box
|
||||
|
@ -323,12 +325,28 @@ where
|
|||
if leading_whitespace {
|
||||
output.push(' ')
|
||||
}
|
||||
loop {
|
||||
if let Some(i) = input.bytes().position(|b| b.is_ascii_whitespace()) {
|
||||
|
||||
match (
|
||||
white_space.preserve_spaces(),
|
||||
white_space.preserve_newlines(),
|
||||
) {
|
||||
(true, true) => {
|
||||
output.push_str(input);
|
||||
},
|
||||
|
||||
(true, false) => unreachable!(),
|
||||
|
||||
(false, preserve_newlines) => loop {
|
||||
if let Some(i) = input.bytes().position(|b| {
|
||||
b.is_ascii_whitespace() && (!preserve_newlines || b != b'\n')
|
||||
}) {
|
||||
let (non_whitespace, rest) = input.split_at(i);
|
||||
output.push_str(non_whitespace);
|
||||
output.push(' ');
|
||||
if let Some(i) = rest.bytes().position(|b| !b.is_ascii_whitespace()) {
|
||||
|
||||
if let Some(i) = rest.bytes().position(|b| {
|
||||
!b.is_ascii_whitespace() || (preserve_newlines && b == b'\n')
|
||||
}) {
|
||||
input = &rest[i..];
|
||||
} else {
|
||||
break;
|
||||
|
@ -337,6 +355,7 @@ where
|
|||
output.push_str(input);
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,10 +378,14 @@ where
|
|||
///
|
||||
/// * Whether this text run has preserved (non-collapsible) leading whitespace
|
||||
/// * The contents starting at the first non-whitespace character (or the empty string)
|
||||
fn handle_leading_whitespace<'text>(&mut self, text: &'text str) -> (bool, &'text str) {
|
||||
fn handle_leading_whitespace<'text>(
|
||||
&mut self,
|
||||
text: &'text str,
|
||||
white_space: WhiteSpace,
|
||||
) -> (bool, &'text str) {
|
||||
// FIXME: this is only an approximation of
|
||||
// https://drafts.csswg.org/css2/text.html#white-space-model
|
||||
if !text.starts_with(|c: char| c.is_ascii_whitespace()) {
|
||||
if !text.starts_with(|c: char| c.is_ascii_whitespace()) || white_space.preserve_spaces() {
|
||||
return (false, text);
|
||||
}
|
||||
|
||||
|
|
|
@ -756,13 +756,15 @@ impl TextRun {
|
|||
let mut glyphs = vec![];
|
||||
let mut advance_width = Length::zero();
|
||||
let mut last_break_opportunity = None;
|
||||
let mut force_line_break = false;
|
||||
loop {
|
||||
let next = runs.next();
|
||||
if next
|
||||
.as_ref()
|
||||
.map_or(true, |run| run.glyph_store.is_whitespace())
|
||||
if next.as_ref().map_or(true, |run| {
|
||||
run.glyph_store.is_whitespace() || force_line_break
|
||||
}) {
|
||||
if advance_width > ifc.containing_block.inline_size - ifc.inline_position ||
|
||||
force_line_break
|
||||
{
|
||||
if advance_width > ifc.containing_block.inline_size - ifc.inline_position {
|
||||
if let Some((len, width, iter)) = last_break_opportunity.take() {
|
||||
glyphs.truncate(len);
|
||||
advance_width = width;
|
||||
|
@ -774,6 +776,14 @@ impl TextRun {
|
|||
if let Some(run) = next {
|
||||
if run.glyph_store.is_whitespace() {
|
||||
last_break_opportunity = Some((glyphs.len(), advance_width, runs.clone()));
|
||||
if self.text.as_bytes().get(run.range.end().to_usize() - 1) == Some(&b'\n')
|
||||
{
|
||||
force_line_break = self
|
||||
.parent_style
|
||||
.get_inherited_text()
|
||||
.white_space
|
||||
.preserve_newlines();
|
||||
}
|
||||
}
|
||||
glyphs.push(run.glyph_store.clone());
|
||||
advance_width += Length::from(run.glyph_store.total_advance());
|
||||
|
@ -812,7 +822,7 @@ impl TextRun {
|
|||
glyphs,
|
||||
text_decoration_line: ifc.current_nesting_level.text_decoration_line,
|
||||
}));
|
||||
if runs.as_slice().is_empty() {
|
||||
if runs.as_slice().is_empty() && !force_line_break {
|
||||
break;
|
||||
} else {
|
||||
// New line
|
||||
|
|
|
@ -186,7 +186,6 @@ ${helpers.predefined_type(
|
|||
name="white-space"
|
||||
values="normal pre nowrap pre-wrap pre-line"
|
||||
engines="gecko servo-2013 servo-2020",
|
||||
servo_2020_pref="layout.2020.unimplemented",
|
||||
extra_gecko_values="break-spaces -moz-pre-space"
|
||||
gecko_enum_prefix="StyleWhiteSpace"
|
||||
needs_conversion="True"
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[hypothetical-inline-alone-on-second-line.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[color-applies-to-008.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[color-applies-to-015.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[c562-white-sp-000.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[float-003.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[float-no-content-beside-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[floats-placement-vertical-004.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,4 @@
|
|||
[hit-test-floats-004.html]
|
||||
[Miss float below something else]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[content-171.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[content-173.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[content-newline-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[content-white-space-002.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[padding-percentage-inherit-001.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[block-replaced-width-006.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[inline-replaced-width-001.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[inline-replaced-width-006.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[inlines-016.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[absolute-non-replaced-height-008.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[position-static-001.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[table-anonymous-objects-009.xht]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[table-anonymous-objects-010.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-004.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-applies-to-003.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-processing-013.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-processing-016.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-processing-017.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-processing-018.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-processing-046.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-processing-047.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-processing-052.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[anonymous-boxes-001b.xht]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[background-size-027.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[background-size-028.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[background-size-030.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[background-size-031.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[anonymous-flex-item-004.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[anonymous-flex-item-005.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[anonymous-flex-item-006.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[text-decoration-subelements-001.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,85 @@
|
|||
[offsetTopLeft-border-box.html]
|
||||
[container: 11]
|
||||
expected: FAIL
|
||||
|
||||
[container: 10]
|
||||
expected: FAIL
|
||||
|
||||
[container: 13]
|
||||
expected: FAIL
|
||||
|
||||
[container: 12]
|
||||
expected: FAIL
|
||||
|
||||
[container: 15]
|
||||
expected: FAIL
|
||||
|
||||
[container: 14]
|
||||
expected: FAIL
|
||||
|
||||
[container: 17]
|
||||
expected: FAIL
|
||||
|
||||
[container: 16]
|
||||
expected: FAIL
|
||||
|
||||
[container: 19]
|
||||
expected: FAIL
|
||||
|
||||
[container: 18]
|
||||
expected: FAIL
|
||||
|
||||
[container: 9]
|
||||
expected: FAIL
|
||||
|
||||
[container: 8]
|
||||
expected: FAIL
|
||||
|
||||
[container: 1]
|
||||
expected: FAIL
|
||||
|
||||
[container: 0]
|
||||
expected: FAIL
|
||||
|
||||
[container: 3]
|
||||
expected: FAIL
|
||||
|
||||
[container: 2]
|
||||
expected: FAIL
|
||||
|
||||
[container: 5]
|
||||
expected: FAIL
|
||||
|
||||
[container: 4]
|
||||
expected: FAIL
|
||||
|
||||
[container: 7]
|
||||
expected: FAIL
|
||||
|
||||
[container: 6]
|
||||
expected: FAIL
|
||||
|
||||
[container: 20]
|
||||
expected: FAIL
|
||||
|
||||
[container: 21]
|
||||
expected: FAIL
|
||||
|
||||
[container: 22]
|
||||
expected: FAIL
|
||||
|
||||
[container: 23]
|
||||
expected: FAIL
|
||||
|
||||
[container: 24]
|
||||
expected: FAIL
|
||||
|
||||
[container: 25]
|
||||
expected: FAIL
|
||||
|
||||
[container: 26]
|
||||
expected: FAIL
|
||||
|
||||
[container: 27]
|
||||
expected: FAIL
|
||||
|
|
@ -23,15 +23,9 @@
|
|||
[page-break-before: always]
|
||||
expected: FAIL
|
||||
|
||||
[white-space: inherit]
|
||||
expected: FAIL
|
||||
|
||||
[page-break-after: inherit]
|
||||
expected: FAIL
|
||||
|
||||
[white-space: nowrap]
|
||||
expected: FAIL
|
||||
|
||||
[page-break-before: left]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -218,9 +212,6 @@
|
|||
[display: table-cell]
|
||||
expected: FAIL
|
||||
|
||||
[white-space: pre]
|
||||
expected: FAIL
|
||||
|
||||
[text-indent: 5%]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -263,7 +254,7 @@
|
|||
[clear: both]
|
||||
expected: FAIL
|
||||
|
||||
[white-space: pre-wrap]
|
||||
[list-style-image: url(http://localhost/)]
|
||||
expected: FAIL
|
||||
|
||||
[outline-width: 0px]
|
||||
|
@ -332,9 +323,6 @@
|
|||
[vertical-align: 1px]
|
||||
expected: FAIL
|
||||
|
||||
[white-space: pre-line]
|
||||
expected: FAIL
|
||||
|
||||
[display: table-column]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -395,9 +383,6 @@
|
|||
[float: none]
|
||||
expected: FAIL
|
||||
|
||||
[white-space: normal]
|
||||
expected: FAIL
|
||||
|
||||
[list-style-type: lower-roman]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[br.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[input_whitespace.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[line_breaking_whitespace_collapse_a.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[many_brs_a.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,2 @@
|
|||
[white-space-pre-line.htm]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white_space_intrinsic_sizes_a.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[whitespace_pre.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[word-break-keep-all-005.htm]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[word-break-keep-all-006.htm]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[word-break-keep-all-007.htm]
|
||||
expected: FAIL
|
|
@ -0,0 +1,4 @@
|
|||
[hit_test_multiple_sc.html]
|
||||
[Hit testing works for following stacking contexts]
|
||||
expected: FAIL
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue