Bug 1789255: Anonymous children of elements with content-visibility should not be skipped for layout r=emilio
Some anonymous children are important for properly sizing their parents even when those parents hide content with `content-visibility`. This is shown by regressions in the proper layout of some form elements with `content-visibility`. This change introduces a more conservative approach for avoiding layout of hidden content. Instead of leaving all children dirty during reflow, reflow anonymous frames (and nsComboboxDisplayFrame, a specialized kind of anonymous frame). This change means that frames may only lay out some of their children, so it must introduce some more changes to assumptions during line layout. In addition, this change renames `content-visibility` related methods in nsIFrame in order to make it more obvious what they do. Differential Revision: https://phabricator.services.mozilla.com/D157306
This commit is contained in:
@@ -1314,7 +1314,7 @@ void nsBlockFrame::ClearLineClampEllipsis() { ::ClearLineClampEllipsis(this); }
|
||||
void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
|
||||
const ReflowInput& aReflowInput,
|
||||
nsReflowStatus& aStatus) {
|
||||
if (GetInFlowParent() && GetInFlowParent()->IsContentHiddenForLayout()) {
|
||||
if (IsHiddenByContentVisibilityOfInFlowParentForLayout()) {
|
||||
FinishAndStoreOverflow(&aMetrics, aReflowInput.mStyleDisplay);
|
||||
return;
|
||||
}
|
||||
@@ -2579,10 +2579,6 @@ static bool LinesAreEmpty(const nsLineList& aList) {
|
||||
}
|
||||
|
||||
void nsBlockFrame::ReflowDirtyLines(BlockReflowState& aState) {
|
||||
if (IsContentHiddenForLayout()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool keepGoing = true;
|
||||
bool repositionViews = false; // should we really need this?
|
||||
bool foundAnyClears = aState.mFloatBreakType != StyleClear::None;
|
||||
@@ -3369,6 +3365,15 @@ void nsBlockFrame::ReflowLine(BlockReflowState& aState, LineIterator aLine,
|
||||
aLine->InvalidateCachedIsEmpty();
|
||||
aLine->ClearHadFloatPushed();
|
||||
|
||||
// If this line contains a single block that is hidden by `content-visibility`
|
||||
// don't reflow the line. If this line contains inlines and the first one is
|
||||
// hidden by `content-visibility`, all of them are, so avoid reflow in that
|
||||
// case as well.
|
||||
nsIFrame* firstChild = aLine->mFirstChild;
|
||||
if (firstChild->IsHiddenByContentVisibilityOfInFlowParentForLayout()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Now that we know what kind of line we have, reflow it
|
||||
if (aLine->IsBlock()) {
|
||||
ReflowBlockFrame(aState, aLine, aKeepReflowGoing);
|
||||
@@ -3577,6 +3582,10 @@ static inline bool IsNonAutoNonZeroBSize(const StyleSize& aCoord) {
|
||||
|
||||
/* virtual */
|
||||
bool nsBlockFrame::IsSelfEmpty() {
|
||||
if (IsHiddenByContentVisibilityOfInFlowParentForLayout()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Blocks which are margin-roots (including inline-blocks) cannot be treated
|
||||
// as empty for margin-collapsing and other purposes. They're more like
|
||||
// replaced elements.
|
||||
|
||||
Reference in New Issue
Block a user