зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1665657 - Whitespace that will hang should not contribute to the min inline-size of a textframe. r=emilio
This affects a few of the examples in the text/white-space-2 reftest, but the changes look sensible; more significantly from an interop point of view, there are specific web-platform reftests that are currently failing, but will pass after the patch. Differential Revision: https://phabricator.services.mozilla.com/D95811
This commit is contained in:
Родитель
810bc229cc
Коммит
0e3cf9687e
|
@ -801,12 +801,13 @@ static bool IsTrimmableSpace(char aCh) {
|
|||
}
|
||||
|
||||
static bool IsTrimmableSpace(const nsTextFragment* aFrag, uint32_t aPos,
|
||||
const nsStyleText* aStyleText) {
|
||||
const nsStyleText* aStyleText,
|
||||
bool aAllowHangingWS = false) {
|
||||
NS_ASSERTION(aPos < aFrag->GetLength(), "No text for IsSpace!");
|
||||
|
||||
switch (aFrag->CharAt(aPos)) {
|
||||
case ' ':
|
||||
return !aStyleText->WhiteSpaceIsSignificant() &&
|
||||
return (!aStyleText->WhiteSpaceIsSignificant() || aAllowHangingWS) &&
|
||||
!IsSpaceCombiningSequenceTail(aFrag, aPos + 1);
|
||||
case '\n':
|
||||
return !aStyleText->NewlineIsSignificantStyle() &&
|
||||
|
@ -814,7 +815,7 @@ static bool IsTrimmableSpace(const nsTextFragment* aFrag, uint32_t aPos,
|
|||
case '\t':
|
||||
case '\r':
|
||||
case '\f':
|
||||
return !aStyleText->WhiteSpaceIsSignificant();
|
||||
return !aStyleText->WhiteSpaceIsSignificant() || aAllowHangingWS;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -3049,11 +3050,13 @@ gfxSkipCharsIterator nsTextFrame::EnsureTextRun(
|
|||
static uint32_t GetEndOfTrimmedText(const nsTextFragment* aFrag,
|
||||
const nsStyleText* aStyleText,
|
||||
uint32_t aStart, uint32_t aEnd,
|
||||
gfxSkipCharsIterator* aIterator) {
|
||||
gfxSkipCharsIterator* aIterator,
|
||||
bool aAllowHangingWS = false) {
|
||||
aIterator->SetSkippedOffset(aEnd);
|
||||
while (aIterator->GetSkippedOffset() > aStart) {
|
||||
aIterator->AdvanceSkipped(-1);
|
||||
if (!IsTrimmableSpace(aFrag, aIterator->GetOriginalOffset(), aStyleText))
|
||||
if (!IsTrimmableSpace(aFrag, aIterator->GetOriginalOffset(), aStyleText,
|
||||
aAllowHangingWS))
|
||||
return aIterator->GetSkippedOffset() + 1;
|
||||
}
|
||||
return aStart;
|
||||
|
@ -8348,6 +8351,7 @@ void nsTextFrame::AddInlineMinISizeForFlow(gfxContext* aRenderingContext,
|
|||
bool collapseWhitespace = !textStyle->WhiteSpaceIsSignificant();
|
||||
bool preformatNewlines = textStyle->NewlineIsSignificant(this);
|
||||
bool preformatTabs = textStyle->WhiteSpaceIsSignificant();
|
||||
bool whitespaceCanHang = textStyle->WhiteSpaceCanHangOrVisuallyCollapse();
|
||||
gfxFloat tabWidth = -1;
|
||||
uint32_t start = FindStartAfterSkippingWhitespace(&provider, aData, textStyle,
|
||||
&iter, flowEndInTextRun);
|
||||
|
@ -8408,9 +8412,9 @@ void nsTextFrame::AddInlineMinISizeForFlow(gfxContext* aRenderingContext,
|
|||
aData->mCurrentLine = NSCoordSaturatingAdd(aData->mCurrentLine, width);
|
||||
aData->mAtStartOfLine = false;
|
||||
|
||||
if (collapseWhitespace) {
|
||||
if (collapseWhitespace || whitespaceCanHang) {
|
||||
uint32_t trimStart =
|
||||
GetEndOfTrimmedText(frag, textStyle, wordStart, i, &iter);
|
||||
GetEndOfTrimmedText(frag, textStyle, wordStart, i, &iter, whitespaceCanHang);
|
||||
if (trimStart == start) {
|
||||
// This is *all* trimmable whitespace, so whatever trailingWhitespace
|
||||
// we saw previously is still trailing...
|
||||
|
@ -9275,9 +9279,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
|
|||
|
||||
bool isBreakSpaces = textStyle->mWhiteSpace == StyleWhiteSpace::BreakSpaces;
|
||||
// allow whitespace to overflow the container
|
||||
bool whitespaceCanHang = !isBreakSpaces &&
|
||||
textStyle->WhiteSpaceCanWrapStyle() &&
|
||||
textStyle->WhiteSpaceIsSignificant();
|
||||
bool whitespaceCanHang = textStyle->WhiteSpaceCanHangOrVisuallyCollapse();
|
||||
gfxBreakPriority breakPriority = aLineLayout.LastOptionalBreakPriority();
|
||||
gfxTextRun::SuppressBreak suppressBreak = gfxTextRun::eNoSuppressBreak;
|
||||
bool shouldSuppressLineBreak = ShouldSuppressLineBreak();
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
<head>
|
||||
<!-- Reference -->
|
||||
<style>
|
||||
div { border:1px solid black; }
|
||||
div { font:16px sans-serif; border:1px solid black; }
|
||||
.container { float:left; width:20%; border-color:cyan; }
|
||||
p { width:0; }
|
||||
b { font-weight:normal; background-color:yellow; white-space:pre; }
|
||||
.cell { display:table-cell; border:1px solid green; }
|
||||
.hang { display:inline-block; width:0; overflow:visible; }
|
||||
.hang span { display:inline; background-color:yellow; }
|
||||
.clip { overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -17,7 +20,7 @@ b { font-weight:normal; background-color:yellow; white-space:pre; }
|
|||
Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello
|
||||
<p><span class="cell"><b>Hello
|
||||
Kitty</b></span>
|
||||
</div>
|
||||
|
||||
|
@ -28,7 +31,7 @@ Kitty</b></span>
|
|||
Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello
|
||||
Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello
|
||||
<p><span class="cell"><b>Hello
|
||||
Kitty</b></span>
|
||||
</div>
|
||||
|
||||
|
@ -37,7 +40,7 @@ Kitty</b></span>
|
|||
Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello
|
||||
<p><span class="cell clip"><b>Hello<span class="hang"><span> </span></span>
|
||||
Kitty</b></span>
|
||||
</div>
|
||||
|
||||
|
@ -46,18 +49,18 @@ Kitty</b></span>
|
|||
Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello
|
||||
<p><span class="cell"><b>Hello
|
||||
Kitty</b></span>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<p><span class="cell"><b>Hello
|
||||
<p><span class="cell"><b>Hello<span class="hang"><span> </span></span>
|
||||
Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello
|
||||
<p><span class="cell"><b>Hello
|
||||
Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello
|
||||
<p><span class="cell"><b>Hello<span class="hang"><span> </span></span>
|
||||
Kitty</b></span>
|
||||
<p><span class="cell"><b>Hello
|
||||
<p><span class="cell"><b>Hello
|
||||
Kitty</b></span>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<!-- Wrapping tests in table-cell to test min-width computation -->
|
||||
<style>
|
||||
div { border:1px solid black; }
|
||||
div { font:16px sans-serif; border:1px solid black; }
|
||||
.container { float:left; width:20%; border-color:cyan; }
|
||||
p { width:0; }
|
||||
b { font-weight:normal; background-color:yellow; }
|
||||
|
|
|
@ -963,6 +963,15 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText {
|
|||
mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace;
|
||||
}
|
||||
|
||||
bool WhiteSpaceCanHangOrVisuallyCollapse() const {
|
||||
// This was originally expressed in nsTextFrame in terms of:
|
||||
// mWhiteSpace != StyleWhiteSpace::BreakSpaces &&
|
||||
// WhiteSpaceCanWrapStyle() &&
|
||||
// WhiteSpaceIsSignificant()
|
||||
// which simplifies to:
|
||||
return mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap;
|
||||
}
|
||||
|
||||
bool NewlineIsSignificantStyle() const {
|
||||
return mWhiteSpace == mozilla::StyleWhiteSpace::Pre ||
|
||||
mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap ||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-intrinsic-size-003.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-intrinsic-size-013.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-intrinsic-size-014.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[white-space-pre-wrap-trailing-spaces-003.html]
|
||||
expected: FAIL
|
Загрузка…
Ссылка в новой задаче