Skip to content

Commit

Permalink
[css-text] New value 'break-spaces' for the white-space property
Browse files Browse the repository at this point in the history
Finally the CSS WG decided [1] to move back the 'break-spaces' value to
the 'white-space' property. This makes the parsing logic easier than
the previous approach of using the 'overflow-wrap' property.

This new value prevents the white-space sequence to collapse and gives
breaking opportunities after every preserved white-space.

https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces

Additionally, unlike 'pre-wrap', non-collapsible spaces or tabs at the
end of a line cannot be hung or visually collapsed, since we want them
to be preserved and broken.

[1] w3c/csswg-drafts#2841

Bug: 767634
Change-Id: I55e888d4472de11c64c4b14e2710c6e3d1832e67
Reviewed-on: https://chromium-review.googlesource.com/c/1136543
Reviewed-by: Koji Ishii <kojii@chromium.org>
Commit-Queue: Javier Fernandez <jfernandez@igalia.com>
Cr-Commit-Position: refs/heads/master@{#623324}
  • Loading branch information
javifernandez authored and Commit Bot committed Jan 16, 2019
1 parent 6e8e26d commit a076426
Show file tree
Hide file tree
Showing 26 changed files with 418 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace blink {
{% for enum in enums %}
enum class {{enum.type_name}} : unsigned {
{% for value in enum.values %}
{{value}}{{print_if(enum.is_set, " = " ~ (0 if loop.first else 2**loop.index0))}},
{{value}}{{print_if(enum.is_set, " = " ~ (0 if loop.first else 2**(loop.index0 - 1)))}},
{% endfor %}
};

Expand Down
4 changes: 2 additions & 2 deletions third_party/blink/renderer/core/css/css_properties.json5
Original file line number Diff line number Diff line change
Expand Up @@ -3961,9 +3961,9 @@
property_methods: ["CSSValueFromComputedStyleInternal"],
independent: true,
inherited: true,
field_template: "keyword",
field_template: "multi_keyword", // We use a bitflag field due peformance issues
keywords: [
"normal", "pre", "pre-wrap", "pre-line", "nowrap", "-webkit-nowrap"
"none", "normal", "pre", "pre-wrap", "pre-line", "nowrap", "-webkit-nowrap", "break-spaces"
],
typedom_types: ["Keyword"],
default_value: "normal",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@
"bidi-override",
"blink",
"both",
"break-spaces",
"close-quote",
"embed",
"fixed",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,9 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
case CSSPropertyWhiteSpace:
return value_id == CSSValueNormal || value_id == CSSValuePre ||
value_id == CSSValuePreWrap || value_id == CSSValuePreLine ||
value_id == CSSValueNowrap;
value_id == CSSValueNowrap ||
(RuntimeEnabledFeatures::CSS3TextBreakSpacesEnabled() &&
value_id == CSSValueBreakSpaces);
case CSSPropertyWordBreak:
return value_id == CSSValueNormal || value_id == CSSValueBreakAll ||
value_id == CSSValueKeepAll || value_id == CSSValueBreakWord;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class BreakingContext {
const Font&,
bool apply_word_spacing,
float word_spacing);
void TrailingSpacesHang(bool can_break_mid_word);
bool TrailingSpaceExceedsAvailableWidth(bool can_break_mid_word,
const LineLayoutText&,
WordMeasurement&,
Expand Down Expand Up @@ -205,6 +206,7 @@ class BreakingContext {
bool at_start_;
bool ignoring_spaces_;
bool current_character_is_space_;
bool previous_character_is_space_;
bool single_leading_space_;
unsigned current_start_offset_; // initial offset for the current text
bool applied_start_width_;
Expand Down Expand Up @@ -1044,7 +1046,7 @@ inline bool BreakingContext::HandleText(WordMeasurements& word_measurements,
layout_text_info_.line_break_iterator_.SecondToLastCharacter();
for (; current_.Offset() < layout_text.TextLength();
current_.FastIncrementInTextNode()) {
bool previous_character_is_space = current_character_is_space_;
previous_character_is_space_ = current_character_is_space_;
UChar c = current_.Current();
SetCurrentCharacterIsSpace(c);

Expand Down Expand Up @@ -1106,7 +1108,7 @@ inline bool BreakingContext::HandleText(WordMeasurements& word_measurements,
}

PrepareForNextCharacter(layout_text, prohibit_break_inside,
previous_character_is_space);
previous_character_is_space_);
at_start_ = false;
NextCharacter(c, last_character, second_to_last_character);
continue;
Expand Down Expand Up @@ -1146,7 +1148,7 @@ inline bool BreakingContext::HandleText(WordMeasurements& word_measurements,
// We keep track of the total width contributed by trailing space as we
// often want to exclude it when determining
// if a run fits on a line.
if (collapse_white_space_ && previous_character_is_space &&
if (collapse_white_space_ && previous_character_is_space_ &&
current_character_is_space_ && last_width_measurement)
width_.SetTrailingWhitespaceWidth(last_width_measurement);

Expand Down Expand Up @@ -1210,7 +1212,7 @@ inline bool BreakingContext::HandleText(WordMeasurements& word_measurements,
if (CanBreakAtWhitespace(
break_words, word_measurement, stopped_ignoring_spaces, char_width,
hyphenated, disable_soft_hyphen, hyphen_width, between_words,
mid_word_break, can_break_mid_word, previous_character_is_space,
mid_word_break, can_break_mid_word, previous_character_is_space_,
last_width_measurement, layout_text, font, apply_word_spacing,
word_spacing))
return false;
Expand Down Expand Up @@ -1250,7 +1252,7 @@ inline bool BreakingContext::HandleText(WordMeasurements& word_measurements,
// go ahead and break up this run and enter a mode where we start collapsing
// spaces.
if (!ignoring_spaces_ && current_style_->CollapseWhiteSpace()) {
if (current_character_is_space_ && previous_character_is_space) {
if (current_character_is_space_ && previous_character_is_space_) {
ignoring_spaces_ = true;

// We just entered a mode where we are ignoring spaces. Create a
Expand All @@ -1263,7 +1265,7 @@ inline bool BreakingContext::HandleText(WordMeasurements& word_measurements,
}

PrepareForNextCharacter(layout_text, prohibit_break_inside,
previous_character_is_space);
previous_character_is_space_);
at_start_ = false;
is_line_empty = line_info_.IsEmpty();
NextCharacter(c, last_character, second_to_last_character);
Expand Down Expand Up @@ -1417,6 +1419,22 @@ inline WordMeasurement& BreakingContext::CalculateWordWidth(
return word_measurement;
}

inline void BreakingContext::TrailingSpacesHang(bool can_break_mid_word) {
DCHECK(curr_ws_ == EWhiteSpace::kBreakSpaces);
// Avoid breaking before the first white-space after a word if there is a
// breaking opportunity before.
if (single_leading_space_ && !previous_character_is_space_)
return;

line_break_.MoveTo(current_.GetLineLayoutItem(), current_.Offset(),
current_.NextBreakablePosition());

// Avoid breaking before the first white-space after a word, unless
// overflow-wrap or word-break allow to.
if (!previous_character_is_space_ && !can_break_mid_word)
line_break_.Increment();
}

inline bool BreakingContext::TrailingSpaceExceedsAvailableWidth(
bool can_break_mid_word,
const LineLayoutText& layout_text,
Expand All @@ -1439,8 +1457,13 @@ inline bool BreakingContext::TrailingSpaceExceedsAvailableWidth(
// then move the line break to the space and skip all
// additional whitespace.
if (!width_.FitsOnLine(char_width)) {
if (curr_ws_ == EWhiteSpace::kBreakSpaces) {
TrailingSpacesHang(can_break_mid_word);
return true;
}
line_break_.MoveTo(current_.GetLineLayoutItem(), current_.Offset(),
current_.NextBreakablePosition());

SkipTrailingWhitespace(line_break_, line_info_);
return true;
}
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/style/computed_style.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ ASSERT_SIZE(BorderValue, SameSizeAsBorderValue);
// Since different compilers/architectures pack ComputedStyle differently,
// re-create the same structure for an accurate size comparison.
struct SameSizeAsComputedStyle : public RefCounted<SameSizeAsComputedStyle> {
unsigned extra_;
struct ComputedStyleBase {
void* data_refs[7];
unsigned bitfields_[4];
Expand Down
15 changes: 10 additions & 5 deletions third_party/blink/renderer/core/style/computed_style.h
Original file line number Diff line number Diff line change
Expand Up @@ -2129,9 +2129,13 @@ class ComputedStyle : public ComputedStyleBase,
}

// Whitespace utility functions.
static bool Is(EWhiteSpace a, EWhiteSpace b) {
return static_cast<unsigned>(a) & static_cast<unsigned>(b);
}
static bool IsNot(EWhiteSpace a, EWhiteSpace b) { return !Is(a, b); }
static bool AutoWrap(EWhiteSpace ws) {
// Nowrap and pre don't automatically wrap.
return ws != EWhiteSpace::kNowrap && ws != EWhiteSpace::kPre;
return IsNot(ws, EWhiteSpace::kNowrap | EWhiteSpace::kPre);
}

bool AutoWrap() const { return AutoWrap(WhiteSpace()); }
Expand All @@ -2149,7 +2153,8 @@ class ComputedStyle : public ComputedStyleBase,

static bool CollapseWhiteSpace(EWhiteSpace ws) {
// Pre and prewrap do not collapse whitespace.
return ws != EWhiteSpace::kPre && ws != EWhiteSpace::kPreWrap;
return IsNot(ws, EWhiteSpace::kPre | EWhiteSpace::kPreWrap |
EWhiteSpace::kBreakSpaces);
}

bool CollapseWhiteSpace() const { return CollapseWhiteSpace(WhiteSpace()); }
Expand All @@ -2165,15 +2170,15 @@ class ComputedStyle : public ComputedStyleBase,
return false;
}
bool BreakOnlyAfterWhiteSpace() const {
return WhiteSpace() == EWhiteSpace::kPreWrap ||
return Is(WhiteSpace(),
EWhiteSpace::kPreWrap | EWhiteSpace::kBreakSpaces) ||
GetLineBreak() == LineBreak::kAfterWhiteSpace;
}

bool BreakWords() const {
return (WordBreak() == EWordBreak::kBreakWord ||
OverflowWrap() == EOverflowWrap::kBreakWord) &&
WhiteSpace() != EWhiteSpace::kPre &&
WhiteSpace() != EWhiteSpace::kNowrap;
IsNot(WhiteSpace(), EWhiteSpace::kPre | EWhiteSpace::kNowrap);
}

// Text direction utility functions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@
name: "CSS3Text",
status: "experimental",
},
{
name: "CSS3TextBreakSpaces",
status: "experimental",
},
{
name: "CSSAdditiveAnimations",
depends_on: ["StackedCSSPropertyAnimations"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,29 @@ crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftest
crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/sizing/vert-block-size-small-or-larger-than-container-with-min-or-max-content-2a.html [ Pass ]
crbug.com/613663 external/wpt/quirks/table-cell-width-calculation.html [ Failure ]

# The new 'break-spaces' value is not implemented yet in LayoutNG
crbug.com/922437 external/wpt/css/css-text/white-space/break-spaces-001.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/break-spaces-002.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/break-spaces-003.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/break-spaces-004.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/break-spaces-005.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/break-spaces-006.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/break-spaces-007.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/break-spaces-008.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/textarea-break-spaces-001.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/textarea-break-spaces-002.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/tab-stop-threshold-005.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/tab-stop-threshold-006.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/white-space-intrinsic-size-001.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/white-space/white-space-intrinsic-size-002.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/word-break/word-break-break-all-012.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/word-break/word-break-break-all-013.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/overflow-wrap/overflow-wrap-anywhere-002.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/overflow-wrap/overflow-wrap-anywhere-003.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/overflow-wrap/overflow-wrap-break-word-002.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/overflow-wrap/overflow-wrap-break-word-003.html [ Skip ]
crbug.com/922437 external/wpt/css/css-text/overflow-wrap/overflow-wrap-break-word-006.html [ Skip ]

# New failures are appended below by the script.
crbug.com/591099 css3/filters/backdrop-filter-rendering.html [ Pass ]
crbug.com/591099 css3/filters/composited-layer-child-bounds-after-composited-to-sw-shadow-change.html [ Failure ]
Expand Down
9 changes: 0 additions & 9 deletions third_party/blink/web_tests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -2203,7 +2203,6 @@ crbug.com/626703 external/wpt/css/css-text/word-break/word-break-break-all-007.h
crbug.com/626703 external/wpt/css/css-text/word-break/word-break-break-all-004.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/word-break/word-break-break-all-006.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/word-break/word-break-break-all-008.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/word-break/word-break-keep-all-003.html [ Failure ]
crbug.com/626703 [ Linux ] external/wpt/css/css-text/word-break/word-break-normal-bo-000.html [ Failure ]
crbug.com/626703 [ Win ] external/wpt/css/css-text/word-break/word-break-normal-km-000.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/word-break/word-break-normal-my-000.html [ Failure ]
Expand Down Expand Up @@ -3104,7 +3103,6 @@ crbug.com/626703 [ Win ] external/wpt/css/CSS2/text/white-space-bidirectionality
crbug.com/626703 external/wpt/css/css-text/text-transform/text-transform-shaping-002.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/white-space/pre-wrap-012.html [ Failure ]
crbug.com/626703 external/wpt/css/CSS2/text/white-space-pre-element-001.xht [ Failure ]
crbug.com/626703 external/wpt/css/css-text/overflow-wrap/overflow-wrap-anywhere-002.html [ Failure ]
crbug.com/626703 external/wpt/css/CSS2/text/white-space-003.xht [ Failure ]
crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/sizing/hori-block-size-small-or-larger-than-container-with-min-or-max-content-2b.html [ Failure ]
crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/sizing/block-size-with-min-or-max-content-1a.html [ Failure ]
Expand All @@ -3115,7 +3113,6 @@ crbug.com/626703 [ Mac ] external/wpt/css/css-text/overflow-wrap/overflow-wrap-m
crbug.com/626703 external/wpt/css/css-text/white-space/pre-wrap-013.html [ Failure ]
crbug.com/626703 external/wpt/css/CSS2/text/white-space-processing-040.xht [ Failure ]
crbug.com/626703 external/wpt/css/css-text/text-transform/text-transform-shaping-003.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/white-space/tab-stop-threshold-006.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/white-space/white-space-intrinsic-size-003.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/overflow-wrap/overflow-wrap-anywhere-001.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/overflow-wrap/overflow-wrap-anywhere-003.html [ Failure ]
Expand All @@ -3132,9 +3129,7 @@ crbug.com/626703 [ Win7 ] external/wpt/css/vendor-imports/mozilla/mozilla-centra
crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/sizing/block-size-with-min-or-max-content-1b.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/text-transform/text-transform-shaping-001.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/boundary-shaping/boundary-shaping-001.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/white-space/white-space-intrinsic-size-002.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/text-indent/text-indent-percentage-004.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/white-space/tab-stop-threshold-005.html [ Failure ]
crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/sizing/vert-block-size-small-or-larger-than-container-with-min-or-max-content-1.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/boundary-shaping/boundary-shaping-004.html [ Failure ]
crbug.com/626703 external/wpt/css/css-sizing/range-percent-intrinsic-size-2.html [ Failure ]
Expand Down Expand Up @@ -3544,15 +3539,13 @@ crbug.com/626703 external/wpt/content-security-policy/securitypolicyviolation/in
crbug.com/626703 external/wpt/content-security-policy/securitypolicyviolation/inside-dedicated-worker.html [ Timeout ]
crbug.com/626703 external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-002.html [ Failure ]
crbug.com/626703 external/wpt/content-security-policy/securitypolicyviolation/targeting.html [ Timeout ]
crbug.com/626703 external/wpt/css/css-text/white-space/textarea-break-spaces-001.html [ Failure ]
crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-column-row-gap-003.html [ Failure ]
crbug.com/863355 [ Mac ] external/wpt/svg/shapes/reftests/pathlength-002.svg [ Failure ]
crbug.com/366559 external/wpt/svg/shapes/reftests/pathlength-003.svg [ Failure ]
crbug.com/366559 external/wpt/svg/text/reftests/textpath-side-001.svg [ Failure ]
crbug.com/366559 external/wpt/svg/text/reftests/textpath-shape-001.svg [ Failure ]
crbug.com/626703 external/wpt/svg/rendering/order/z-index.svg [ Failure ]
crbug.com/626703 external/wpt/web-animations/timing-model/timelines/update-and-send-events.html [ Timeout ]
crbug.com/626703 external/wpt/css/css-text/white-space/break-spaces-001.html [ Failure ]
crbug.com/626703 [ Mac10.12 ] external/wpt/compat/webkit-text-fill-color-property-002.html [ Failure ]
crbug.com/626703 [ Mac10.13 ] external/wpt/compat/webkit-text-fill-color-property-002.html [ Failure ]
crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-column-row-gap-001.html [ Failure ]
Expand Down Expand Up @@ -3685,8 +3678,6 @@ crbug.com/626703 [ Linux ] external/wpt/fetch/api/redirect/redirect-count.any.ht
crbug.com/626703 [ Win10 ] external/wpt/fetch/api/redirect/redirect-count.any.html [ Timeout ]

crbug.com/626703 external/wpt/css/cssom-view/scroll-behavior-smooth.html [ Timeout ]
crbug.com/626703 external/wpt/css/css-text/overflow-wrap/overflow-wrap-break-word-003.html [ Failure ]
crbug.com/626703 external/wpt/css/css-text/overflow-wrap/overflow-wrap-break-word-002.html [ Failure ]
crbug.com/626703 external/wpt/websockets/Create-Secure-extensions-empty.any.html [ Timeout ]
crbug.com/626703 external/wpt/websockets/Create-Secure-extensions-empty.any.worker.html [ Timeout ]
crbug.com/626703 external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/string-compilation-integrity-classic.sub.html [ Skip ]
Expand Down
4 changes: 0 additions & 4 deletions third_party/blink/web_tests/W3CImportExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,6 @@ external/wpt/css/css-text/text-transform/text-transform-fullwidth-001.xht [ Skip
external/wpt/css/css-text/text-transform/text-transform-fullwidth-002.xht [ Skip ]
external/wpt/css/css-text/text-transform/text-transform-fullwidth-004.xht [ Skip ]
external/wpt/css/css-text/text-transform/text-transform-fullwidth-005.xht [ Skip ]
external/wpt/css/css-text/white-space/pre-wrap-008.html [ Skip ]
external/wpt/css/css-text/white-space/pre-wrap-010.html [ Skip ]
external/wpt/css/css-text/white-space/textarea-pre-wrap-010.html [ Skip ]
external/wpt/css/css-text/white-space/textarea-pre-wrap-008.html [ Skip ]
external/wpt/css/css-text/white-space/white-space-collapsing-discard-001.xht [ Skip ]
external/wpt/css/css-text/white-space/white-space-collapsing-preserve-breaks-001.xht [ Skip ]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</style>

<p>This test passes if there is nothing below this sentence.
<div> FAIL <div>
<div> FAIL </div>
<!--
white-space:break-spaces should cause the spaces at the end of the line to be preserved.
Since there is an allowed break point between the first space and the F,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
</style>

<p>This test passes if the word FAIL does not appear below.
<div>PASS FAIL<div>
<div>PASS FAIL</div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<title>CSS Text Test: overflow-wrap: break-word</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-overflow-wrap-break-word">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-pre-wrap">
<meta name="flags" content="ahem">
<link rel="match" href="reference/overflow-wrap-break-word-001-ref.html">
<meta name="assert" content="A Single leading white-space constitutes a soft breaking opportunity, honoring the 'white-space: pre-wrap' property, that must prevent the word to be broken.">
Expand Down
Loading

0 comments on commit a076426

Please sign in to comment.