mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Allow breaking line after space with white-space: break-spaces
(#33376)
`white-space: break-spaces` should allow a soft wrap opportunity *after* every preserved white space. Then, to avoid breaking before the first white space, `TextRunSegment::shape_text()` has some logic to separate it from the following spaces and put it with the preceding text instead. The problem was that, when combined with `word-break: keep-all`, we were then only checking whether there were more white spaces afterwards, ignoring the soft wrap opportunity after the first one. Also removing a duplicated `can_break_anywhere` variable. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
6d6cd0f2dc
commit
9d3d009895
3 changed files with 40 additions and 4 deletions
|
@ -225,6 +225,7 @@ impl TextRunSegment {
|
||||||
let mut whitespace = slice.end..slice.end;
|
let mut whitespace = slice.end..slice.end;
|
||||||
let mut rev_char_indices = word.char_indices().rev().peekable();
|
let mut rev_char_indices = word.char_indices().rev().peekable();
|
||||||
|
|
||||||
|
let mut ends_with_whitespace = false;
|
||||||
let ends_with_newline = rev_char_indices
|
let ends_with_newline = rev_char_indices
|
||||||
.peek()
|
.peek()
|
||||||
.map_or(false, |&(_, character)| character == '\n');
|
.map_or(false, |&(_, character)| character == '\n');
|
||||||
|
@ -232,6 +233,7 @@ impl TextRunSegment {
|
||||||
.take_while(|&(_, character)| char_is_whitespace(character))
|
.take_while(|&(_, character)| char_is_whitespace(character))
|
||||||
.last()
|
.last()
|
||||||
{
|
{
|
||||||
|
ends_with_whitespace = true;
|
||||||
whitespace.start = slice.start + first_white_space_index;
|
whitespace.start = slice.start + first_white_space_index;
|
||||||
|
|
||||||
// If line breaking for a piece of text that has `white-space-collapse: break-spaces` there
|
// If line breaking for a piece of text that has `white-space-collapse: break-spaces` there
|
||||||
|
@ -252,10 +254,7 @@ impl TextRunSegment {
|
||||||
|
|
||||||
// If there's no whitespace and `word-break` is set to `keep-all`, try increasing the slice.
|
// If there's no whitespace and `word-break` is set to `keep-all`, try increasing the slice.
|
||||||
// TODO: This should only happen for CJK text.
|
// TODO: This should only happen for CJK text.
|
||||||
let can_break_anywhere = text_style.word_break == WordBreak::BreakAll ||
|
if !ends_with_whitespace &&
|
||||||
text_style.overflow_wrap == OverflowWrap::Anywhere ||
|
|
||||||
text_style.overflow_wrap == OverflowWrap::BreakWord;
|
|
||||||
if whitespace.is_empty() &&
|
|
||||||
*break_index != self.range.end &&
|
*break_index != self.range.end &&
|
||||||
text_style.word_break == WordBreak::KeepAll &&
|
text_style.word_break == WordBreak::KeepAll &&
|
||||||
!can_break_anywhere
|
!can_break_anywhere
|
||||||
|
|
13
tests/wpt/meta/MANIFEST.json
vendored
13
tests/wpt/meta/MANIFEST.json
vendored
|
@ -254546,6 +254546,19 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"break-spaces-with-word-break-001.html": [
|
||||||
|
"ee31fd627130eeb40fd22d0b9bc4fa6e9eb3aca7",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/css/reference/ref-filled-green-100px-square.xht",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"control-chars-000.html": [
|
"control-chars-000.html": [
|
||||||
"b038fe9a90d3b8b9cb3bde7fd46396c7121688c9",
|
"b038fe9a90d3b8b9cb3bde7fd46396c7121688c9",
|
||||||
[
|
[
|
||||||
|
|
24
tests/wpt/tests/css/css-text/white-space/break-spaces-with-word-break-001.html
vendored
Normal file
24
tests/wpt/tests/css/css-text/white-space/break-spaces-with-word-break-001.html
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Text Test: white-space:break-spaces + word-break:keep-all</title>
|
||||||
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-text-4/#valdef-white-space-collapse-break-spaces">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-text-4/#valdef-word-break-keep-all">
|
||||||
|
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
|
||||||
|
<meta name="assert" content="break-spaces + keep-all does allow a break after space.">
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
font: 50px/1 Ahem;
|
||||||
|
white-space: break-spaces;
|
||||||
|
word-break: keep-all;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: red;
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||||
|
<div>XX XX</div>
|
Loading…
Add table
Add a link
Reference in a new issue