Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Layout 2020: Implement basic white-space: pre support #26447

Merged
merged 2 commits into from Jul 29, 2020
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Implement basic white-space: pre support for layout 2020.

  • Loading branch information
jdm committed Jul 28, 2020
commit d8b4dab4e38c2928f034248e158e8bf9b5ad60d6
@@ -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,20 +325,37 @@ where
if leading_whitespace {
output.push(' ')
}
loop {
if let Some(i) = input.bytes().position(|b| b.is_ascii_whitespace()) {
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()) {
input = &rest[i..];

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() || (preserve_newlines && b == b'\n')
}) {
input = &rest[i..];
} else {
break;
}
} else {
output.push_str(input);
break;
}
} else {
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 advance_width > ifc.containing_block.inline_size - ifc.inline_position {
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 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"

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

@@ -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

This file was deleted.

@@ -0,0 +1,2 @@
[content-173.xht]
expected: FAIL

This file was deleted.

@@ -0,0 +1,2 @@
[content-white-space-002.xht]
expected: FAIL

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

@@ -0,0 +1,2 @@
[table-anonymous-objects-009.xht]
expected: FAIL
@@ -0,0 +1,2 @@
[table-anonymous-objects-010.xht]
expected: FAIL

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

@@ -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

This file was deleted.

@@ -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

This file was deleted.

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.