зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1159042 - p5. Add NS_FRAME_DYNAMIC_REFLOW_ROOT on frames that we can dynamically make reflow roots - r=dholbert
Differential Revision: https://phabricator.services.mozilla.com/D9491 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
16349625aa
Коммит
cabd72af5d
|
@ -403,6 +403,7 @@ void ReflowInput::Init(nsPresContext* aPresContext,
|
|||
InitConstraints(aPresContext, cbSize, aBorder, aPadding, type);
|
||||
|
||||
InitResizeFlags(aPresContext, type);
|
||||
InitDynamicReflowRoot();
|
||||
|
||||
nsIFrame* parent = mFrame->GetParent();
|
||||
if (parent && (parent->GetStateBits() & NS_FRAME_IN_CONSTRAINED_BSIZE) &&
|
||||
|
@ -795,6 +796,92 @@ void ReflowInput::InitResizeFlags(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool IsIntrinsicKeyword(const nsStyleCoord& aCoord) {
|
||||
if (aCoord.GetUnit() != eStyleUnit_Enumerated) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// All of the keywords except for '-moz-available' depend on intrinsic sizes.
|
||||
return aCoord.GetIntValue() != NS_STYLE_WIDTH_AVAILABLE;
|
||||
}
|
||||
|
||||
void ReflowInput::InitDynamicReflowRoot() {
|
||||
auto display = mStyleDisplay->mDisplay;
|
||||
if (mFrame->IsFrameOfType(nsIFrame::eLineParticipant) ||
|
||||
nsStyleDisplay::IsRubyDisplayType(display) ||
|
||||
mFrameType == NS_CSS_FRAME_TYPE_INTERNAL_TABLE ||
|
||||
display == StyleDisplay::Table || display == StyleDisplay::TableCaption ||
|
||||
display == StyleDisplay::InlineTable ||
|
||||
(mFrame->GetParent() && mFrame->GetParent()->IsXULBoxFrame())) {
|
||||
// We have a display type where 'width' and 'height' don't actually
|
||||
// set the width or height (i.e., the size depends on content).
|
||||
NS_ASSERTION(!(mFrame->GetStateBits() & NS_FRAME_DYNAMIC_REFLOW_ROOT),
|
||||
"should not have dynamic reflow root bit");
|
||||
return;
|
||||
}
|
||||
|
||||
bool canBeDynamicReflowRoot = true;
|
||||
|
||||
// We can't do this if our used 'width' and 'height' might be influenced by
|
||||
// content.
|
||||
// FIXME: For display:block, we should probably optimize inline-size
|
||||
// being auto.
|
||||
// FIXME: Other flex and grid cases?
|
||||
const nsStyleCoord& width = mStylePosition->mWidth;
|
||||
const nsStyleCoord& height = mStylePosition->mHeight;
|
||||
if (!width.IsCoordPercentCalcUnit() || width.HasPercent() ||
|
||||
!height.IsCoordPercentCalcUnit() || height.HasPercent() ||
|
||||
IsIntrinsicKeyword(mStylePosition->mMinWidth) ||
|
||||
IsIntrinsicKeyword(mStylePosition->mMaxWidth) ||
|
||||
IsIntrinsicKeyword(mStylePosition->mMinHeight) ||
|
||||
IsIntrinsicKeyword(mStylePosition->mMaxHeight) ||
|
||||
((mStylePosition->mMinWidth.GetUnit() == eStyleUnit_Auto ||
|
||||
mStylePosition->mMinHeight.GetUnit() == eStyleUnit_Auto) &&
|
||||
mFrame->IsFlexOrGridItem())) {
|
||||
canBeDynamicReflowRoot = false;
|
||||
}
|
||||
|
||||
if (mFrame->IsFlexItem()) {
|
||||
// If our flex-basis is 'auto', it'll defer to 'width' (or 'height') which
|
||||
// we've already checked. Otherwise, it preempts them, so we need to
|
||||
// perform the same "could-this-value-be-influenced-by-content" checks that
|
||||
// we performed for 'width' and 'height' above.
|
||||
const nsStyleCoord& flexBasis = mStylePosition->mFlexBasis;
|
||||
if (flexBasis.GetUnit() != eStyleUnit_Auto &&
|
||||
(!flexBasis.IsCoordPercentCalcUnit() || flexBasis.HasPercent())) {
|
||||
canBeDynamicReflowRoot = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mFrame->IsFixedPosContainingBlock()) {
|
||||
// We can't treat this frame as a reflow root, since dynamic changes
|
||||
// to absolutely-positioned frames inside of it require that we
|
||||
// reflow the placeholder before we reflow the absolutely positioned
|
||||
// frame.
|
||||
// FIXME: Alternatively, we could sort the reflow roots in
|
||||
// PresShell::ProcessReflowCommands by depth in the tree, from
|
||||
// deepest to least deep. However, for performance (FIXME) we
|
||||
// should really be sorting them in the opposite order!
|
||||
canBeDynamicReflowRoot = false;
|
||||
} else {
|
||||
MOZ_ASSERT(mFrame->IsAbsPosContainingBlock(),
|
||||
"we need the frame to be both an abs-pos and fixed-pos cb");
|
||||
}
|
||||
|
||||
// If we participate in a container's block reflow context, or margins
|
||||
// can collapse through us, we can't be a dynamic reflow root.
|
||||
if (canBeDynamicReflowRoot && mFrame->IsFrameOfType(nsIFrame::eBlockFrame) &&
|
||||
!mFrame->HasAllStateBits(NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT)) {
|
||||
canBeDynamicReflowRoot = false;
|
||||
}
|
||||
|
||||
if (canBeDynamicReflowRoot) {
|
||||
mFrame->AddStateBits(NS_FRAME_DYNAMIC_REFLOW_ROOT);
|
||||
} else {
|
||||
mFrame->RemoveStateBits(NS_FRAME_DYNAMIC_REFLOW_ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
nscoord ReflowInput::GetContainingBlockContentISize(
|
||||
WritingMode aWritingMode) const {
|
||||
if (!mCBReflowInput) {
|
||||
|
|
|
@ -982,6 +982,7 @@ struct ReflowInput : public SizeComputationInput {
|
|||
void InitCBReflowInput();
|
||||
void InitResizeFlags(nsPresContext* aPresContext,
|
||||
mozilla::LayoutFrameType aFrameType);
|
||||
void InitDynamicReflowRoot();
|
||||
|
||||
void InitConstraints(nsPresContext* aPresContext,
|
||||
const mozilla::LogicalSize& aContainingBlockSize,
|
||||
|
|
|
@ -248,8 +248,9 @@ FRAME_STATE_BIT(Generic, 43, NS_FRAME_SVG_LAYOUT)
|
|||
// ancestor.
|
||||
FRAME_STATE_BIT(Generic, 44, NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR)
|
||||
|
||||
// Bits 45 is currently unused, but be kind and check with bug 1465474
|
||||
// first please :-)
|
||||
// If this bit is set, then reflow may be dispatched from the current
|
||||
// frame instead of the root frame.
|
||||
FRAME_STATE_BIT(Generic, 45, NS_FRAME_DYNAMIC_REFLOW_ROOT)
|
||||
|
||||
// This bit indicates that we're tracking visibility for this frame, and that
|
||||
// the frame has a VisibilityStateProperty property.
|
||||
|
@ -309,7 +310,9 @@ FRAME_STATE_BIT(Generic, 59, NS_FRAME_IS_IN_SINGLE_CHAR_MI)
|
|||
// NOTE: Bits 20-31 and 60-63 of the frame state are reserved for specific
|
||||
// frame classes.
|
||||
|
||||
// NOTE: Currently unused and available bit(s): 45.
|
||||
// NOTE: No more unused bits. If needed, investigate removing obsolete bits by
|
||||
// adjusting logic, or moving infrequently-used bits elsewhere. If more space
|
||||
// for frame state is still needed, look for bit field gaps in nsIFrame.
|
||||
|
||||
// == Frame state bits that apply to box frames ===============================
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче