mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1931466: Ensure inline elements in an empty linebox as having zero BSize and no baseline. r=layout-reviewers,dholbert,jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D229191
This commit is contained in:
parent
8f4f441cae
commit
429486d08f
@ -4990,7 +4990,10 @@ void nsBlockFrame::DoReflowInlineFrames(
|
||||
|
||||
aLineLayout.BeginLineReflow(
|
||||
iStart, aState.mBCoord, availISize, availBSize,
|
||||
aFloatAvailableSpace.HasFloats(), false, /*XXX isTopOfPage*/
|
||||
aFloatAvailableSpace.HasFloats(), false /*XXX isTopOfPage*/,
|
||||
HasOutsideMarker() || Style()->IsAnonBox()
|
||||
? CollapseEmptyInlineFramesInLine::Preserve
|
||||
: CollapseEmptyInlineFramesInLine::Collapse,
|
||||
lineWM, aState.mContainerSize, aState.mInsetForBalance);
|
||||
|
||||
aState.mFlags.mIsLineLayoutEmpty = false;
|
||||
|
@ -222,9 +222,11 @@ void nsFirstLetterFrame::Reflow(nsPresContext* aPresContext,
|
||||
ReflowInput rs(aPresContext, aReflowInput, kid, kidAvailSize);
|
||||
nsLineLayout ll(aPresContext, nullptr, aReflowInput, nullptr, nullptr);
|
||||
|
||||
// This frame does not get constructed for an empty inline frame, so
|
||||
// `CollapseEmptyInlineFramesInLine` should not matter.
|
||||
ll.BeginLineReflow(
|
||||
bp.IStart(wm), bp.BStart(wm), availSize.ISize(wm), NS_UNCONSTRAINEDSIZE,
|
||||
false, true, kidWritingMode,
|
||||
false, true, CollapseEmptyInlineFramesInLine::Collapse, kidWritingMode,
|
||||
nsSize(aReflowInput.AvailableWidth(), aReflowInput.AvailableHeight()));
|
||||
rs.mLineLayout = ≪
|
||||
ll.SetInFirstLetter(true);
|
||||
|
@ -850,6 +850,8 @@ Maybe<nscoord> nsInlineFrame::GetNaturalBaselineBOffset(
|
||||
if (aBaselineGroup == BaselineSharingGroup::Last) {
|
||||
return Nothing{};
|
||||
}
|
||||
// TODO(dshin): Some functions seem to rely on this returning
|
||||
// NS_INTRINSIC_ISIZE_UNKNOWN. e.g. /css/css-pseudo/target-text-008.html
|
||||
return Some(mBaseline);
|
||||
}
|
||||
|
||||
|
@ -91,12 +91,11 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
void nsLineLayout::BeginLineReflow(nscoord aICoord, nscoord aBCoord,
|
||||
nscoord aISize, nscoord aBSize,
|
||||
bool aImpactedByFloats, bool aIsTopOfPage,
|
||||
WritingMode aWritingMode,
|
||||
const nsSize& aContainerSize,
|
||||
nscoord aInset) {
|
||||
void nsLineLayout::BeginLineReflow(
|
||||
nscoord aICoord, nscoord aBCoord, nscoord aISize, nscoord aBSize,
|
||||
bool aImpactedByFloats, bool aIsTopOfPage,
|
||||
CollapseEmptyInlineFramesInLine aCollapseEmptyInlineFramesInLine,
|
||||
WritingMode aWritingMode, const nsSize& aContainerSize, nscoord aInset) {
|
||||
MOZ_ASSERT(nullptr == mRootSpan, "bad linelayout user");
|
||||
LAYOUT_WARN_IF_FALSE(aISize != NS_UNCONSTRAINEDSIZE,
|
||||
"have unconstrained width; this should only result from "
|
||||
@ -149,6 +148,9 @@ void nsLineLayout::BeginLineReflow(nscoord aICoord, nscoord aBCoord,
|
||||
psd->mIStart = aICoord;
|
||||
psd->mICoord = aICoord;
|
||||
psd->mIEnd = aICoord + aISize;
|
||||
psd->mDoCollapseEmptyInlineFramesInLine =
|
||||
aCollapseEmptyInlineFramesInLine ==
|
||||
CollapseEmptyInlineFramesInLine::Collapse;
|
||||
// Set up inset to be used for text-wrap:balance implementation, but only if
|
||||
// the available size is greater than inset.
|
||||
psd->mInset = aISize > aInset ? aInset : 0;
|
||||
@ -354,6 +356,7 @@ nsLineLayout::PerSpanData* nsLineLayout::NewPerSpanData() {
|
||||
psd->mContainsFloat = false;
|
||||
psd->mHasNonemptyContent = false;
|
||||
psd->mBaseline = nullptr;
|
||||
psd->mDoCollapseEmptyInlineFramesInLine = false;
|
||||
|
||||
#ifdef DEBUG
|
||||
outerLineLayout->mSpansAllocated++;
|
||||
@ -1490,6 +1493,34 @@ void nsLineLayout::VerticalAlignLine() {
|
||||
// this operation is set to zero so that the y coordinates for all
|
||||
// of the placed children will be relative to there.
|
||||
PerSpanData* psd = mRootSpan;
|
||||
if (mLineIsEmpty && psd->mDoCollapseEmptyInlineFramesInLine) {
|
||||
// This line is empty, and should be consisting of only inline elements.
|
||||
// (inline-block elements would make the line non-empty).
|
||||
WritingMode lineWM = psd->mWritingMode;
|
||||
for (PerFrameData* pfd = psd->mFirstFrame; pfd; pfd = pfd->mNext) {
|
||||
// Ideally, if the frame would collapse itself - but it depends on
|
||||
// knowing that the line is empty.
|
||||
if (!pfd->mFrame->IsInlineFrame() && !pfd->mFrame->IsRubyFrame()) {
|
||||
continue;
|
||||
}
|
||||
// Collapse the physical size to 0.
|
||||
pfd->mBounds.BStart(lineWM) = mBStartEdge;
|
||||
pfd->mBounds.BSize(lineWM) = 0;
|
||||
// Initialize mBlockDirAlign (though it doesn't make much difference
|
||||
// because we don't align empty boxes).
|
||||
pfd->mBlockDirAlign = VALIGN_OTHER;
|
||||
pfd->mFrame->SetRect(lineWM, pfd->mBounds, ContainerSize());
|
||||
}
|
||||
|
||||
mFinalLineBSize = 0;
|
||||
if (mGotLineBox) {
|
||||
mLineBox->SetBounds(psd->mWritingMode, psd->mIStart, mBStartEdge,
|
||||
psd->mICoord - psd->mIStart, 0, ContainerSize());
|
||||
|
||||
mLineBox->SetLogicalAscent(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
VerticalAlignFrames(psd);
|
||||
|
||||
// *** Note that comments here still use the anachronistic term
|
||||
|
@ -20,6 +20,18 @@
|
||||
class nsFloatManager;
|
||||
struct nsStyleText;
|
||||
|
||||
/**
|
||||
* Flag indicating if inline frames within a line should be collapsed
|
||||
* to zero block-size if all frames within it are empty.
|
||||
* Declared as typed enum for clearer semantics in function calls, though
|
||||
* it is reflected as a boolean in
|
||||
* PerSpanData::mDoCollapseEmptyInlineFramesInLine.
|
||||
*/
|
||||
enum class CollapseEmptyInlineFramesInLine {
|
||||
Preserve,
|
||||
Collapse,
|
||||
};
|
||||
|
||||
class nsLineLayout {
|
||||
using BlockReflowState = mozilla::BlockReflowState;
|
||||
using ReflowInput = mozilla::ReflowInput;
|
||||
@ -49,13 +61,14 @@ class nsLineLayout {
|
||||
|
||||
int32_t GetLineNumber() const { return mLineNumber; }
|
||||
|
||||
void BeginLineReflow(nscoord aICoord, nscoord aBCoord, nscoord aISize,
|
||||
nscoord aBSize, bool aImpactedByFloats,
|
||||
bool aIsTopOfPage, mozilla::WritingMode aWritingMode,
|
||||
const nsSize& aContainerSize,
|
||||
// aInset is used during text-wrap:balance to reduce
|
||||
// the effective available space on the line.
|
||||
nscoord aInset = 0);
|
||||
void BeginLineReflow(
|
||||
nscoord aICoord, nscoord aBCoord, nscoord aISize, nscoord aBSize,
|
||||
bool aImpactedByFloats, bool aIsTopOfPage,
|
||||
CollapseEmptyInlineFramesInLine aCollapseEmptyInlineFramesInLine,
|
||||
mozilla::WritingMode aWritingMode, const nsSize& aContainerSize,
|
||||
// aInset is used during text-wrap:balance to reduce
|
||||
// the effective available space on the line.
|
||||
nscoord aInset = 0);
|
||||
|
||||
/**
|
||||
* Returns true if the line had to use an overflow-wrap break position.
|
||||
@ -497,6 +510,7 @@ class nsLineLayout {
|
||||
mozilla::WritingMode mWritingMode;
|
||||
bool mContainsFloat;
|
||||
bool mHasNonemptyContent;
|
||||
bool mDoCollapseEmptyInlineFramesInLine;
|
||||
|
||||
nscoord mIStart;
|
||||
nscoord mICoord;
|
||||
|
@ -341,9 +341,9 @@ void nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext,
|
||||
// If the writing mode is vertical-rl, the horizontal position of
|
||||
// rt frames will be updated when reflowing this text container,
|
||||
// hence leave container size 0 here for now.
|
||||
lineLayout->BeginLineReflow(0, 0, reflowInput->ComputedISize(),
|
||||
NS_UNCONSTRAINEDSIZE, false, false, reflowWM,
|
||||
nsSize(0, 0));
|
||||
lineLayout->BeginLineReflow(
|
||||
0, 0, reflowInput->ComputedISize(), NS_UNCONSTRAINEDSIZE, false, false,
|
||||
CollapseEmptyInlineFramesInLine::Collapse, reflowWM, nsSize(0, 0));
|
||||
lineLayout->AttachRootFrameToBaseLineLayout();
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ div {
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
<div><span></span></div>
|
||||
<div><span> </span></div>
|
||||
<script>
|
||||
let $div = document.querySelector('div');
|
||||
let $span = document.querySelector('span');
|
||||
|
@ -10,7 +10,7 @@ div {
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
<div><span></span></div>
|
||||
<div><span> </span></div>
|
||||
<script>
|
||||
let $div = document.querySelector('div');
|
||||
let $span = document.querySelector('span');
|
||||
|
@ -2,5 +2,3 @@
|
||||
max-asserts: 3
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Blob URL fragment is implemented.]
|
||||
expected: FAIL
|
||||
|
@ -1,2 +0,0 @@
|
||||
[abspos-inline-008.xht]
|
||||
expected: FAIL
|
@ -1,2 +0,0 @@
|
||||
[toogle-abspos-on-relpos-inline-child.html]
|
||||
expected: FAIL
|
@ -1,2 +0,0 @@
|
||||
[out-of-flow-in-multicolumn-116.html]
|
||||
expected: FAIL
|
@ -1,5 +0,0 @@
|
||||
[position-absolute-in-inline-001.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[absolute inside inline container location should be correct.]
|
||||
expected: FAIL
|
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-inline-3/#invisible-line-boxes">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1931466">
|
||||
<style>
|
||||
.container {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
box-sizing: border-box;
|
||||
border-left: 1px solid;
|
||||
width: 1px;
|
||||
height: 11px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
</style>
|
||||
<div class="container"></div><br>
|
||||
<div class="container"><span style="border: 1px solid; border-right: 2px solid;"></span></div><br>
|
||||
<div class="container"><ul><li> </li><li> </li></ul></div><br>
|
||||
<div class="container"><div class="button"></div><span> </span></div><br>
|
@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-inline-3/#invisible-line-boxes">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1931466">
|
||||
<link rel="match" href="empty-span-size-001-ref.html">
|
||||
<style>
|
||||
.container, .has-height {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.inline {
|
||||
outline: 1px solid;
|
||||
}
|
||||
|
||||
input {
|
||||
outline: 1px solid;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
line-height: 10px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
width: 0;
|
||||
}
|
||||
</style>
|
||||
<!-- Empty inline element in empty line has a height of zero. -->
|
||||
<div class="container"><span class="inline"></span></div><br>
|
||||
<!-- ... But not if the line has a meaningful height. -->
|
||||
<div class="container"><span class="inline"></span><span class="has-height"></span><span class="inline"></span></div><br>
|
||||
<!-- ... Or if the line is present in some kind of context that gives a meaningful height. -->
|
||||
<div class="container"><ul><li></li><li></li></ul></div><br>
|
||||
<div class="container"><input type="button" value=""></div><br>
|
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-inline-3/#invisible-line-boxes">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1931466">
|
||||
<style>
|
||||
.container {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<div class="container"></div><br>
|
||||
<div class="container"><span style="border: 1px solid; border-right: 2px solid;"></span></div><br>
|
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-inline-3/#invisible-line-boxes">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1931466">
|
||||
<link rel="match" href="empty-span-size-002-ref.html">
|
||||
<style>
|
||||
.container, .has-height {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.inline {
|
||||
outline: 1px solid;
|
||||
}
|
||||
</style>
|
||||
<!-- Empty inline element in empty line has a height of zero. -->
|
||||
<div class="container"><ruby class="inline"></ruby></div><br>
|
||||
<!-- ... But not if the line has a meaningful height. -->
|
||||
<div class="container"><ruby class="inline"></ruby><ruby class="has-height"></ruby><ruby class="inline"></ruby></div><br>
|
Loading…
Reference in New Issue
Block a user