forked from mirrors/gecko-dev
Bug 1351432 - Implement the break-spaces value of the white-space property r=jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D34499 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
f7f51ced95
commit
d5bbf998dd
28 changed files with 37 additions and 55 deletions
|
|
@ -10459,6 +10459,7 @@ exports.CSS_PROPERTIES = {
|
||||||
"supports": [],
|
"supports": [],
|
||||||
"values": [
|
"values": [
|
||||||
"-moz-pre-space",
|
"-moz-pre-space",
|
||||||
|
"break-spaces",
|
||||||
"inherit",
|
"inherit",
|
||||||
"initial",
|
"initial",
|
||||||
"normal",
|
"normal",
|
||||||
|
|
|
||||||
|
|
@ -864,7 +864,7 @@ uint32_t gfxTextRun::BreakAndMeasureText(
|
||||||
gfxFloat* aTrimWhitespace, bool aWhitespaceCanHang, Metrics* aMetrics,
|
gfxFloat* aTrimWhitespace, bool aWhitespaceCanHang, Metrics* aMetrics,
|
||||||
gfxFont::BoundingBoxType aBoundingBoxType, DrawTarget* aRefDrawTarget,
|
gfxFont::BoundingBoxType aBoundingBoxType, DrawTarget* aRefDrawTarget,
|
||||||
bool* aUsedHyphenation, uint32_t* aLastBreak, bool aCanWordWrap,
|
bool* aUsedHyphenation, uint32_t* aLastBreak, bool aCanWordWrap,
|
||||||
gfxBreakPriority* aBreakPriority) {
|
bool aCanWhitespaceWrap, gfxBreakPriority* aBreakPriority) {
|
||||||
aMaxLength = std::min(aMaxLength, GetLength() - aStart);
|
aMaxLength = std::min(aMaxLength, GetLength() - aStart);
|
||||||
|
|
||||||
NS_ASSERTION(aStart + aMaxLength <= GetLength(), "Substring out of range");
|
NS_ASSERTION(aStart + aMaxLength <= GetLength(), "Substring out of range");
|
||||||
|
|
@ -984,7 +984,16 @@ uint32_t gfxTextRun::BreakAndMeasureText(
|
||||||
mCharacterGlyphs[i].IsClusterStart() &&
|
mCharacterGlyphs[i].IsClusterStart() &&
|
||||||
*aBreakPriority <= gfxBreakPriority::eWordWrapBreak;
|
*aBreakPriority <= gfxBreakPriority::eWordWrapBreak;
|
||||||
|
|
||||||
if (atBreak || wordWrapping) {
|
bool whitespaceWrapping = false;
|
||||||
|
if (i > aStart) {
|
||||||
|
// The spec says the breaking opportunity is *after* whitespace.
|
||||||
|
auto const& g = mCharacterGlyphs[i - 1];
|
||||||
|
whitespaceWrapping =
|
||||||
|
aCanWhitespaceWrap &&
|
||||||
|
(g.CharIsSpace() || g.CharIsTab() || g.CharIsNewline());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atBreak || wordWrapping || whitespaceWrapping) {
|
||||||
gfxFloat hyphenatedAdvance = advance;
|
gfxFloat hyphenatedAdvance = advance;
|
||||||
if (atHyphenationBreak) {
|
if (atHyphenationBreak) {
|
||||||
hyphenatedAdvance += aProvider->GetHyphenWidth();
|
hyphenatedAdvance += aProvider->GetHyphenWidth();
|
||||||
|
|
@ -997,8 +1006,9 @@ uint32_t gfxTextRun::BreakAndMeasureText(
|
||||||
lastBreakTrimmableChars = trimmableChars;
|
lastBreakTrimmableChars = trimmableChars;
|
||||||
lastBreakTrimmableAdvance = trimmableAdvance;
|
lastBreakTrimmableAdvance = trimmableAdvance;
|
||||||
lastBreakUsedHyphenation = atHyphenationBreak;
|
lastBreakUsedHyphenation = atHyphenationBreak;
|
||||||
*aBreakPriority = atBreak ? gfxBreakPriority::eNormalBreak
|
*aBreakPriority = (atBreak || whitespaceWrapping)
|
||||||
: gfxBreakPriority::eWordWrapBreak;
|
? gfxBreakPriority::eNormalBreak
|
||||||
|
: gfxBreakPriority::eWordWrapBreak;
|
||||||
}
|
}
|
||||||
|
|
||||||
width += advance;
|
width += advance;
|
||||||
|
|
|
||||||
|
|
@ -444,7 +444,7 @@ class gfxTextRun : public gfxShapedText {
|
||||||
gfxFont::BoundingBoxType aBoundingBoxType,
|
gfxFont::BoundingBoxType aBoundingBoxType,
|
||||||
DrawTarget* aDrawTargetForTightBoundingBox,
|
DrawTarget* aDrawTargetForTightBoundingBox,
|
||||||
bool* aUsedHyphenation, uint32_t* aLastBreak,
|
bool* aUsedHyphenation, uint32_t* aLastBreak,
|
||||||
bool aCanWordWrap,
|
bool aCanWordWrap, bool aCanWhitespaceWrap,
|
||||||
gfxBreakPriority* aBreakPriority);
|
gfxBreakPriority* aBreakPriority);
|
||||||
|
|
||||||
// Utility getters
|
// Utility getters
|
||||||
|
|
|
||||||
|
|
@ -1171,6 +1171,7 @@ static nsTextFrameUtils::CompressionMode GetCSSWhitespaceToCompressionMode(
|
||||||
return nsTextFrameUtils::COMPRESS_WHITESPACE_NEWLINE;
|
return nsTextFrameUtils::COMPRESS_WHITESPACE_NEWLINE;
|
||||||
case StyleWhiteSpace::Pre:
|
case StyleWhiteSpace::Pre:
|
||||||
case StyleWhiteSpace::PreWrap:
|
case StyleWhiteSpace::PreWrap:
|
||||||
|
case StyleWhiteSpace::BreakSpaces:
|
||||||
if (!aStyleText->NewlineIsSignificant(aFrame)) {
|
if (!aStyleText->NewlineIsSignificant(aFrame)) {
|
||||||
// If newline is set to be preserved, but then suppressed,
|
// If newline is set to be preserved, but then suppressed,
|
||||||
// transform newline to space.
|
// transform newline to space.
|
||||||
|
|
@ -8979,8 +8980,11 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
||||||
}
|
}
|
||||||
bool canTrimTrailingWhitespace = !textStyle->WhiteSpaceIsSignificant() ||
|
bool canTrimTrailingWhitespace = !textStyle->WhiteSpaceIsSignificant() ||
|
||||||
(GetStateBits() & TEXT_IS_IN_TOKEN_MATHML);
|
(GetStateBits() & TEXT_IS_IN_TOKEN_MATHML);
|
||||||
|
|
||||||
|
bool isBreakSpaces = textStyle->mWhiteSpace == StyleWhiteSpace::BreakSpaces;
|
||||||
// allow whitespace to overflow the container
|
// allow whitespace to overflow the container
|
||||||
bool whitespaceCanHang = textStyle->WhiteSpaceCanWrapStyle() &&
|
bool whitespaceCanHang = !isBreakSpaces &&
|
||||||
|
textStyle->WhiteSpaceCanWrapStyle() &&
|
||||||
textStyle->WhiteSpaceIsSignificant();
|
textStyle->WhiteSpaceIsSignificant();
|
||||||
gfxBreakPriority breakPriority = aLineLayout.LastOptionalBreakPriority();
|
gfxBreakPriority breakPriority = aLineLayout.LastOptionalBreakPriority();
|
||||||
gfxTextRun::SuppressBreak suppressBreak = gfxTextRun::eNoSuppressBreak;
|
gfxTextRun::SuppressBreak suppressBreak = gfxTextRun::eNoSuppressBreak;
|
||||||
|
|
@ -8996,7 +9000,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
||||||
suppressBreak, canTrimTrailingWhitespace ? &trimmedWidth : nullptr,
|
suppressBreak, canTrimTrailingWhitespace ? &trimmedWidth : nullptr,
|
||||||
whitespaceCanHang, &textMetrics, boundingBoxType, aDrawTarget,
|
whitespaceCanHang, &textMetrics, boundingBoxType, aDrawTarget,
|
||||||
&usedHyphenation, &transformedLastBreak, textStyle->WordCanWrap(this),
|
&usedHyphenation, &transformedLastBreak, textStyle->WordCanWrap(this),
|
||||||
&breakPriority);
|
isBreakSpaces, &breakPriority);
|
||||||
if (!length && !textMetrics.mAscent && !textMetrics.mDescent) {
|
if (!length && !textMetrics.mAscent && !textMetrics.mDescent) {
|
||||||
// If we're measuring a zero-length piece of text, update
|
// If we're measuring a zero-length piece of text, update
|
||||||
// the height manually.
|
// the height manually.
|
||||||
|
|
|
||||||
|
|
@ -566,6 +566,7 @@ enum class StyleWhiteSpace : uint8_t {
|
||||||
PreWrap,
|
PreWrap,
|
||||||
PreLine,
|
PreLine,
|
||||||
PreSpace,
|
PreSpace,
|
||||||
|
BreakSpaces,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ruby-align, see nsStyleText
|
// ruby-align, see nsStyleText
|
||||||
|
|
|
||||||
|
|
@ -1295,30 +1295,35 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText {
|
||||||
bool WhiteSpaceIsSignificant() const {
|
bool WhiteSpaceIsSignificant() const {
|
||||||
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
|
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
|
||||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
|
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
|
||||||
|
mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
|
||||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
|
mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NewlineIsSignificantStyle() const {
|
bool NewlineIsSignificantStyle() const {
|
||||||
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
|
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
|
||||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
|
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
|
||||||
|
mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
|
||||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
|
mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WhiteSpaceOrNewlineIsSignificant() const {
|
bool WhiteSpaceOrNewlineIsSignificant() const {
|
||||||
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
|
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
|
||||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
|
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
|
||||||
|
mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
|
||||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreLine ||
|
mWhiteSpace == mozilla::StyleWhiteSpace::PreLine ||
|
||||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
|
mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TabIsSignificant() const {
|
bool TabIsSignificant() const {
|
||||||
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
|
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
|
||||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap;
|
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
|
||||||
|
mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WhiteSpaceCanWrapStyle() const {
|
bool WhiteSpaceCanWrapStyle() const {
|
||||||
return mWhiteSpace == mozilla::StyleWhiteSpace::Normal ||
|
return mWhiteSpace == mozilla::StyleWhiteSpace::Normal ||
|
||||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
|
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
|
||||||
|
mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces ||
|
||||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
|
mWhiteSpace == mozilla::StyleWhiteSpace::PreLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4978,7 +4978,7 @@ var gCSSProperties = {
|
||||||
type: CSS_TYPE_LONGHAND,
|
type: CSS_TYPE_LONGHAND,
|
||||||
applies_to_placeholder: true,
|
applies_to_placeholder: true,
|
||||||
initial_values: [ "normal" ],
|
initial_values: [ "normal" ],
|
||||||
other_values: [ "pre", "nowrap", "pre-wrap", "pre-line", "-moz-pre-space" ],
|
other_values: [ "pre", "nowrap", "pre-wrap", "pre-line", "-moz-pre-space", "break-spaces" ],
|
||||||
invalid_values: []
|
invalid_values: []
|
||||||
},
|
},
|
||||||
"width": {
|
"width": {
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ ${helpers.predefined_type(
|
||||||
|
|
||||||
<%helpers:single_keyword
|
<%helpers:single_keyword
|
||||||
name="white-space"
|
name="white-space"
|
||||||
values="normal pre nowrap pre-wrap pre-line"
|
values="normal pre nowrap pre-wrap pre-line break-spaces"
|
||||||
extra_gecko_values="-moz-pre-space"
|
extra_gecko_values="-moz-pre-space"
|
||||||
gecko_enum_prefix="StyleWhiteSpace"
|
gecko_enum_prefix="StyleWhiteSpace"
|
||||||
needs_conversion="True"
|
needs_conversion="True"
|
||||||
|
|
@ -193,7 +193,8 @@ ${helpers.predefined_type(
|
||||||
SpecifiedValue::Pre => false,
|
SpecifiedValue::Pre => false,
|
||||||
SpecifiedValue::Normal |
|
SpecifiedValue::Normal |
|
||||||
SpecifiedValue::PreWrap |
|
SpecifiedValue::PreWrap |
|
||||||
SpecifiedValue::PreLine => true,
|
SpecifiedValue::PreLine |
|
||||||
|
SpecifiedValue::BreakSpaces => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,7 +204,8 @@ ${helpers.predefined_type(
|
||||||
SpecifiedValue::Nowrap => false,
|
SpecifiedValue::Nowrap => false,
|
||||||
SpecifiedValue::Pre |
|
SpecifiedValue::Pre |
|
||||||
SpecifiedValue::PreWrap |
|
SpecifiedValue::PreWrap |
|
||||||
SpecifiedValue::PreLine => true,
|
SpecifiedValue::PreLine |
|
||||||
|
SpecifiedValue::BreakSpaces => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,7 +215,8 @@ ${helpers.predefined_type(
|
||||||
SpecifiedValue::Nowrap |
|
SpecifiedValue::Nowrap |
|
||||||
SpecifiedValue::PreLine => false,
|
SpecifiedValue::PreLine => false,
|
||||||
SpecifiedValue::Pre |
|
SpecifiedValue::Pre |
|
||||||
SpecifiedValue::PreWrap => true,
|
SpecifiedValue::PreWrap |
|
||||||
|
SpecifiedValue::BreakSpaces => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[overflow-wrap-anywhere-002.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[overflow-wrap-anywhere-003.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[overflow-wrap-break-word-002.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[overflow-wrap-break-word-003.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[overflow-wrap-break-word-006.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[overflow-wrap-break-word-008.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
[white-space-valid.html]
|
|
||||||
[e.style['white-space'\] = "break-spaces" should set the property value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[break-spaces-001.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[break-spaces-003.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[break-spaces-004.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[break-spaces-005.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[break-spaces-006.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[break-spaces-007.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[break-spaces-009.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[tab-stop-threshold-005.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[tab-stop-threshold-006.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[textarea-break-spaces-001.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[white-space-intrinsic-size-002.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[word-break-break-all-012.html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[word-break-break-all-013.html]
|
|
||||||
expected: FAIL
|
|
||||||
Loading…
Reference in a new issue