Backed out 5 changesets (bug 1926015) for causing crashtest failures @1730506.html. CLOSED TREE
Backed out changeset 7df628ab162c (bug 1926015) Backed out changeset a3524c96da73 (bug 1926015) Backed out changeset cfbf0fa7bf8d (bug 1926015) Backed out changeset 2c2f56268bd7 (bug 1926015) Backed out changeset 55175ed82058 (bug 1926015)
This commit is contained in:
@@ -151,10 +151,17 @@ void ColumnSetWrapperFrame::MarkIntrinsicISizesDirty() {
|
|||||||
|
|
||||||
nscoord ColumnSetWrapperFrame::IntrinsicISize(const IntrinsicSizeInput& aInput,
|
nscoord ColumnSetWrapperFrame::IntrinsicISize(const IntrinsicSizeInput& aInput,
|
||||||
IntrinsicISizeType aType) {
|
IntrinsicISizeType aType) {
|
||||||
return mCachedIntrinsics.GetOrSet(*this, aType, aInput, [&] {
|
if (aType == IntrinsicISizeType::MinISize) {
|
||||||
return aType == IntrinsicISizeType::MinISize ? MinISize(aInput)
|
if (mCachedMinISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||||
: PrefISize(aInput);
|
mCachedMinISize = MinISize(aInput);
|
||||||
});
|
}
|
||||||
|
return mCachedMinISize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCachedPrefISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||||
|
mCachedPrefISize = PrefISize(aInput);
|
||||||
|
}
|
||||||
|
return mCachedPrefISize;
|
||||||
}
|
}
|
||||||
|
|
||||||
nscoord ColumnSetWrapperFrame::MinISize(const IntrinsicSizeInput& aInput) {
|
nscoord ColumnSetWrapperFrame::MinISize(const IntrinsicSizeInput& aInput) {
|
||||||
|
|||||||
@@ -1,160 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_IntrinsicISizesCache_h
|
|
||||||
#define mozilla_IntrinsicISizesCache_h
|
|
||||||
|
|
||||||
#include "nsIFrame.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
|
|
||||||
// Some frame classes keep a cache of intrinsic inline sizes. This class
|
|
||||||
// encapsulates the logic for caching them depending on the IntrinsicSizeInput.
|
|
||||||
//
|
|
||||||
// The cache is intended to take as little space as possible
|
|
||||||
// (max(sizeof(nscoord) * 2, sizeof(void*))), when there are no percentage-size
|
|
||||||
// dependencies.
|
|
||||||
struct IntrinsicISizesCache final {
|
|
||||||
IntrinsicISizesCache() {
|
|
||||||
new (&mInline) InlineCache();
|
|
||||||
MOZ_ASSERT(IsInline());
|
|
||||||
}
|
|
||||||
|
|
||||||
~IntrinsicISizesCache() { delete GetOutOfLine(); }
|
|
||||||
|
|
||||||
template <typename Compute>
|
|
||||||
nscoord GetOrSet(nsIFrame& aFrame, IntrinsicISizeType aType,
|
|
||||||
const IntrinsicSizeInput& aInput, Compute aCompute) {
|
|
||||||
bool dependentOnPercentBSize = aFrame.HasAnyStateBits(
|
|
||||||
NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE);
|
|
||||||
nscoord value = Get(dependentOnPercentBSize, aType, aInput);
|
|
||||||
if (value != kNotFound) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
value = aCompute();
|
|
||||||
// Inside of aCompute(), we might have newly discovered that we do have a
|
|
||||||
// descendant whose intrinsic isize depends on our bsize; so we check that
|
|
||||||
// state bit again before updating the cache.
|
|
||||||
dependentOnPercentBSize = aFrame.HasAnyStateBits(
|
|
||||||
NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE);
|
|
||||||
Set(dependentOnPercentBSize, aType, aInput, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear() {
|
|
||||||
if (auto* ool = GetOutOfLine()) {
|
|
||||||
ool->mCacheWithPercentageBasis.Clear();
|
|
||||||
ool->mCacheWithoutPercentageBasis.Clear();
|
|
||||||
ool->mLastPercentageBasis.reset();
|
|
||||||
} else {
|
|
||||||
mInline.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// We use nscoord_MAX rather than NS_INTRINSIC_ISIZE_UNKNOWN as our sentinel
|
|
||||||
// value so that our high bit is always free.
|
|
||||||
static constexpr nscoord kNotFound = nscoord_MAX;
|
|
||||||
|
|
||||||
nscoord Get(bool aDependentOnPercentBSize, IntrinsicISizeType aType,
|
|
||||||
const IntrinsicSizeInput& aInput) const {
|
|
||||||
if (!aDependentOnPercentBSize ||
|
|
||||||
!aInput.HasSomePercentageBasisForChildren()) {
|
|
||||||
if (auto* ool = GetOutOfLine()) {
|
|
||||||
return ool->mCacheWithoutPercentageBasis.Get(aType);
|
|
||||||
}
|
|
||||||
return mInline.Get(aType);
|
|
||||||
}
|
|
||||||
if (auto* ool = GetOutOfLine()) {
|
|
||||||
if (ool->mLastPercentageBasis == aInput.mPercentageBasisForChildren) {
|
|
||||||
return ool->mCacheWithPercentageBasis.Get(aType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return kNotFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Set(bool aDependentOnPercentBSize, IntrinsicISizeType aType,
|
|
||||||
const IntrinsicSizeInput& aInput, nscoord aValue) {
|
|
||||||
// Intrinsic sizes should be nonnegative, so this std::max clamping should
|
|
||||||
// rarely be necessary except in cases of integer overflow. We have to be
|
|
||||||
// strict about it, though, because of how we (ab)use the high bit
|
|
||||||
// (see kHighBit)
|
|
||||||
aValue = std::max(aValue, 0);
|
|
||||||
const bool usePercentAwareCache =
|
|
||||||
aDependentOnPercentBSize && aInput.HasSomePercentageBasisForChildren();
|
|
||||||
if (usePercentAwareCache) {
|
|
||||||
auto* ool = EnsureOutOfLine();
|
|
||||||
ool->mLastPercentageBasis = aInput.mPercentageBasisForChildren;
|
|
||||||
ool->mCacheWithPercentageBasis.Set(aType, aValue);
|
|
||||||
} else if (auto* ool = GetOutOfLine()) {
|
|
||||||
ool->mCacheWithoutPercentageBasis.Set(aType, aValue);
|
|
||||||
} else {
|
|
||||||
mInline.Set(aType, aValue);
|
|
||||||
// No inline value should be able to cause us to misinterpret our
|
|
||||||
// representation as out-of-line, because intrinsic isizes should always
|
|
||||||
// be non-negative.
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(IsInline());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct InlineCache {
|
|
||||||
nscoord mCachedMinISize = kNotFound;
|
|
||||||
nscoord mCachedPrefISize = kNotFound;
|
|
||||||
|
|
||||||
nscoord Get(IntrinsicISizeType aType) const {
|
|
||||||
return aType == IntrinsicISizeType::MinISize ? mCachedMinISize
|
|
||||||
: mCachedPrefISize;
|
|
||||||
}
|
|
||||||
void Set(IntrinsicISizeType aType, nscoord aValue) {
|
|
||||||
MOZ_ASSERT(aValue >= 0);
|
|
||||||
if (aType == IntrinsicISizeType::MinISize) {
|
|
||||||
mCachedMinISize = aValue;
|
|
||||||
} else {
|
|
||||||
mCachedPrefISize = aValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear() { *this = {}; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OutOfLineCache {
|
|
||||||
InlineCache mCacheWithoutPercentageBasis;
|
|
||||||
InlineCache mCacheWithPercentageBasis;
|
|
||||||
Maybe<LogicalSize> mLastPercentageBasis;
|
|
||||||
};
|
|
||||||
|
|
||||||
// If the high bit of mOutOfLine is 1, then it points to an OutOfLineCache.
|
|
||||||
union {
|
|
||||||
InlineCache mInline;
|
|
||||||
uintptr_t mOutOfLine = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr uintptr_t kHighBit = uintptr_t(1)
|
|
||||||
<< (sizeof(void*) * CHAR_BIT - 1);
|
|
||||||
|
|
||||||
bool IsOutOfLine() const { return mOutOfLine & kHighBit; }
|
|
||||||
bool IsInline() const { return !IsOutOfLine(); }
|
|
||||||
OutOfLineCache* EnsureOutOfLine() {
|
|
||||||
if (auto* ool = GetOutOfLine()) {
|
|
||||||
return ool;
|
|
||||||
}
|
|
||||||
auto inlineCache = mInline;
|
|
||||||
auto* ool = new OutOfLineCache();
|
|
||||||
ool->mCacheWithoutPercentageBasis = inlineCache;
|
|
||||||
MOZ_ASSERT((reinterpret_cast<uintptr_t>(ool) & kHighBit) == 0);
|
|
||||||
mOutOfLine = reinterpret_cast<uintptr_t>(ool) | kHighBit;
|
|
||||||
return ool;
|
|
||||||
}
|
|
||||||
|
|
||||||
OutOfLineCache* GetOutOfLine() const {
|
|
||||||
return IsOutOfLine()
|
|
||||||
? reinterpret_cast<OutOfLineCache*>(mOutOfLine & ~kHighBit)
|
|
||||||
: nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -58,28 +58,26 @@ void MiddleCroppingBlockFrame::UpdateDisplayedValueToUncroppedValue(
|
|||||||
|
|
||||||
nscoord MiddleCroppingBlockFrame::IntrinsicISize(
|
nscoord MiddleCroppingBlockFrame::IntrinsicISize(
|
||||||
const IntrinsicSizeInput& aInput, IntrinsicISizeType aType) {
|
const IntrinsicSizeInput& aInput, IntrinsicISizeType aType) {
|
||||||
auto* first = FirstContinuation();
|
nsAutoString prevValue;
|
||||||
if (this != first) {
|
bool restoreOldValue = false;
|
||||||
return first->IntrinsicISize(aInput, aType);
|
|
||||||
|
// Make sure we measure with the uncropped value.
|
||||||
|
if (mCropped && mCachedPrefISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||||
|
mTextNode->GetNodeValue(prevValue);
|
||||||
|
restoreOldValue = true;
|
||||||
|
UpdateDisplayedValueToUncroppedValue(false);
|
||||||
}
|
}
|
||||||
return mCachedIntrinsics.GetOrSet(*this, aType, aInput, [&] {
|
|
||||||
nsAutoString prevValue;
|
// Our min inline size is the same as our pref inline size, so we always
|
||||||
bool restoreOldValue = false;
|
// delegate to nsBlockFrame's pref inline size.
|
||||||
if (mCropped) {
|
nscoord result =
|
||||||
// Make sure we measure with the uncropped value, if we're currently
|
nsBlockFrame::IntrinsicISize(aInput, IntrinsicISizeType::PrefISize);
|
||||||
// cropped.
|
|
||||||
mTextNode->GetNodeValue(prevValue);
|
if (restoreOldValue) {
|
||||||
UpdateDisplayedValueToUncroppedValue(false);
|
UpdateDisplayedValue(prevValue, /* aIsCropped = */ true, false);
|
||||||
restoreOldValue = true;
|
}
|
||||||
}
|
|
||||||
// Our min inline size is the same as our pref inline size, so we always
|
return result;
|
||||||
// delegate to nsBlockFrame's pref inline size.
|
|
||||||
const nscoord result = nsBlockFrame::PrefISize(aInput);
|
|
||||||
if (restoreOldValue) {
|
|
||||||
UpdateDisplayedValue(prevValue, /* aIsCropped = */ true, false);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MiddleCroppingBlockFrame::CropTextToWidth(gfxContext& aRenderingContext,
|
bool MiddleCroppingBlockFrame::CropTextToWidth(gfxContext& aRenderingContext,
|
||||||
@@ -179,9 +177,8 @@ void MiddleCroppingBlockFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
aStatus.Reset();
|
aStatus.Reset();
|
||||||
MarkSubtreeDirty();
|
MarkSubtreeDirty();
|
||||||
AddStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
|
AddStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
|
||||||
// FIXME(emilio): Why do we need to clear cached intrinsics, if they are
|
mCachedMinISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
// always based off our uncropped value?
|
mCachedPrefISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
mCachedIntrinsics.Clear();
|
|
||||||
cropped = true;
|
cropped = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -969,10 +969,7 @@ class LogicalSize {
|
|||||||
/**
|
/**
|
||||||
* Test if a size is (0, 0).
|
* Test if a size is (0, 0).
|
||||||
*/
|
*/
|
||||||
bool IsAllZero() const { return IsAllValues(0); }
|
bool IsAllZero() const { return ISize() == 0 && BSize() == 0; }
|
||||||
bool IsAllValues(nscoord aValue) const {
|
|
||||||
return ISize() == aValue && BSize() == aValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Various binary operators on LogicalSize. These are valid ONLY for operands
|
* Various binary operators on LogicalSize. These are valid ONLY for operands
|
||||||
|
|||||||
@@ -700,7 +700,7 @@ load 1474768.html
|
|||||||
load 1478178.html
|
load 1478178.html
|
||||||
load 1483972.html
|
load 1483972.html
|
||||||
load 1486457.html
|
load 1486457.html
|
||||||
load 1488762-1.html
|
asserts(1-4) load 1488762-1.html # asserts from integer overflow & bogus sizes
|
||||||
load 1488910-1.html
|
load 1488910-1.html
|
||||||
load 1488910-2.html
|
load 1488910-2.html
|
||||||
load 1489287.html
|
load 1489287.html
|
||||||
@@ -803,7 +803,7 @@ load 1682032.html
|
|||||||
load 1699263.html
|
load 1699263.html
|
||||||
load 1699468.html
|
load 1699468.html
|
||||||
load 1728319.html
|
load 1728319.html
|
||||||
load 1730506.html
|
asserts(2-8) load 1730506.html # asserts from integer overflow & bogus sizes
|
||||||
asserts(1-4) load 1730570.html # asserts from integer overflow & bogus sizes
|
asserts(1-4) load 1730570.html # asserts from integer overflow & bogus sizes
|
||||||
load 1734015.html
|
load 1734015.html
|
||||||
skip-if(Android) load 1741488-1.html # printPreview doesn't work on android
|
skip-if(Android) load 1741488-1.html # printPreview doesn't work on android
|
||||||
|
|||||||
@@ -142,7 +142,6 @@ EXPORTS.mozilla += [
|
|||||||
"ColumnUtils.h",
|
"ColumnUtils.h",
|
||||||
"CSSAlignUtils.h",
|
"CSSAlignUtils.h",
|
||||||
"CSSOrderAwareFrameIterator.h",
|
"CSSOrderAwareFrameIterator.h",
|
||||||
"IntrinsicISizesCache.h",
|
|
||||||
"LayoutMessageUtils.h",
|
"LayoutMessageUtils.h",
|
||||||
"nsVideoFrame.h",
|
"nsVideoFrame.h",
|
||||||
"PrintedSheetFrame.h",
|
"PrintedSheetFrame.h",
|
||||||
|
|||||||
@@ -765,7 +765,8 @@ static bool RemoveFirstLine(nsLineList& aFromLines, nsFrameList& aFromFrames,
|
|||||||
/* virtual */
|
/* virtual */
|
||||||
void nsBlockFrame::MarkIntrinsicISizesDirty() {
|
void nsBlockFrame::MarkIntrinsicISizesDirty() {
|
||||||
nsBlockFrame* dirtyBlock = static_cast<nsBlockFrame*>(FirstContinuation());
|
nsBlockFrame* dirtyBlock = static_cast<nsBlockFrame*>(FirstContinuation());
|
||||||
dirtyBlock->mCachedIntrinsics.Clear();
|
dirtyBlock->mCachedMinISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
|
dirtyBlock->mCachedPrefISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
if (!HasAnyStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION)) {
|
if (!HasAnyStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION)) {
|
||||||
for (nsIFrame* frame = dirtyBlock; frame;
|
for (nsIFrame* frame = dirtyBlock; frame;
|
||||||
frame = frame->GetNextContinuation()) {
|
frame = frame->GetNextContinuation()) {
|
||||||
@@ -783,7 +784,8 @@ void nsBlockFrame::CheckIntrinsicCacheAgainstShrinkWrapState() {
|
|||||||
}
|
}
|
||||||
bool inflationEnabled = !presContext->mInflationDisabledForShrinkWrap;
|
bool inflationEnabled = !presContext->mInflationDisabledForShrinkWrap;
|
||||||
if (inflationEnabled != HasAnyStateBits(NS_BLOCK_INTRINSICS_INFLATED)) {
|
if (inflationEnabled != HasAnyStateBits(NS_BLOCK_INTRINSICS_INFLATED)) {
|
||||||
mCachedIntrinsics.Clear();
|
mCachedMinISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
|
mCachedPrefISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
AddOrRemoveStateBits(NS_BLOCK_INTRINSICS_INFLATED, inflationEnabled);
|
AddOrRemoveStateBits(NS_BLOCK_INTRINSICS_INFLATED, inflationEnabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -821,10 +823,17 @@ nscoord nsBlockFrame::IntrinsicISize(const IntrinsicSizeInput& aInput,
|
|||||||
|
|
||||||
CheckIntrinsicCacheAgainstShrinkWrapState();
|
CheckIntrinsicCacheAgainstShrinkWrapState();
|
||||||
|
|
||||||
return mCachedIntrinsics.GetOrSet(*this, aType, aInput, [&] {
|
if (aType == IntrinsicISizeType::MinISize) {
|
||||||
return aType == IntrinsicISizeType::MinISize ? MinISize(aInput)
|
if (mCachedMinISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||||
: PrefISize(aInput);
|
mCachedMinISize = MinISize(aInput);
|
||||||
});
|
}
|
||||||
|
return mCachedMinISize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCachedPrefISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||||
|
mCachedPrefISize = PrefISize(aInput);
|
||||||
|
}
|
||||||
|
return mCachedPrefISize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */
|
/* virtual */
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
#include "nsLineBox.h"
|
#include "nsLineBox.h"
|
||||||
#include "nsCSSPseudoElements.h"
|
#include "nsCSSPseudoElements.h"
|
||||||
#include "nsFloatManager.h"
|
#include "nsFloatManager.h"
|
||||||
#include "mozilla/IntrinsicISizesCache.h"
|
|
||||||
|
|
||||||
enum class LineReflowStatus {
|
enum class LineReflowStatus {
|
||||||
// The line was completely reflowed and fit in available width, and we should
|
// The line was completely reflowed and fit in available width, and we should
|
||||||
@@ -274,7 +273,6 @@ class nsBlockFrame : public nsContainerFrame {
|
|||||||
BaselineSharingGroup aBaselineGroup,
|
BaselineSharingGroup aBaselineGroup,
|
||||||
BaselineExportContext aExportContext) const;
|
BaselineExportContext aExportContext) const;
|
||||||
|
|
||||||
protected:
|
|
||||||
// MinISize() and PrefISize() are helpers to implement IntrinsicISize().
|
// MinISize() and PrefISize() are helpers to implement IntrinsicISize().
|
||||||
nscoord MinISize(const mozilla::IntrinsicSizeInput& aInput);
|
nscoord MinISize(const mozilla::IntrinsicSizeInput& aInput);
|
||||||
nscoord PrefISize(const mozilla::IntrinsicSizeInput& aInput);
|
nscoord PrefISize(const mozilla::IntrinsicSizeInput& aInput);
|
||||||
@@ -1036,7 +1034,8 @@ class nsBlockFrame : public nsContainerFrame {
|
|||||||
int32_t GetDepth() const;
|
int32_t GetDepth() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mozilla::IntrinsicISizesCache mCachedIntrinsics;
|
nscoord mCachedMinISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
|
nscoord mCachedPrefISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
|
|
||||||
nsLineList mLines;
|
nsLineList mLines;
|
||||||
|
|
||||||
|
|||||||
@@ -2062,7 +2062,9 @@ const CachedBAxisMeasurement& nsFlexContainerFrame::MeasureBSizeForFlexItem(
|
|||||||
|
|
||||||
/* virtual */
|
/* virtual */
|
||||||
void nsFlexContainerFrame::MarkIntrinsicISizesDirty() {
|
void nsFlexContainerFrame::MarkIntrinsicISizesDirty() {
|
||||||
mCachedIntrinsicSizes.Clear();
|
mCachedMinISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
|
mCachedPrefISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
|
|
||||||
nsContainerFrame::MarkIntrinsicISizesDirty();
|
nsContainerFrame::MarkIntrinsicISizesDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2476,16 +2478,8 @@ bool FlexItem::CanMainSizeInfluenceCrossSize() const {
|
|||||||
|
|
||||||
if (IsInlineAxisCrossAxis()) {
|
if (IsInlineAxisCrossAxis()) {
|
||||||
// If we get here, this function is really asking: "can changes to this
|
// If we get here, this function is really asking: "can changes to this
|
||||||
// item's block size have an influence on its inline size"?
|
// item's block size have an influence on its inline size"? For blocks and
|
||||||
|
// tables, the answer is "no".
|
||||||
// If a flex item's intrinsic inline size or its descendants' inline size
|
|
||||||
// contributions depend on the item's block size, the answer is "yes".
|
|
||||||
if (mFrame->HasAnyStateBits(
|
|
||||||
NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// For blocks and tables, the answer is "no" (aside from the above special
|
|
||||||
// case).
|
|
||||||
if (mFrame->IsBlockFrame() || mFrame->IsTableWrapperFrame()) {
|
if (mFrame->IsBlockFrame() || mFrame->IsTableWrapperFrame()) {
|
||||||
// XXXdholbert (Maybe use an IsFrameOfType query or something more
|
// XXXdholbert (Maybe use an IsFrameOfType query or something more
|
||||||
// general to test this across all frame types? For now, I'm just
|
// general to test this across all frame types? For now, I'm just
|
||||||
@@ -6557,9 +6551,13 @@ nscoord nsFlexContainerFrame::ComputeIntrinsicISize(
|
|||||||
|
|
||||||
nscoord nsFlexContainerFrame::IntrinsicISize(const IntrinsicSizeInput& aInput,
|
nscoord nsFlexContainerFrame::IntrinsicISize(const IntrinsicSizeInput& aInput,
|
||||||
IntrinsicISizeType aType) {
|
IntrinsicISizeType aType) {
|
||||||
return mCachedIntrinsicSizes.GetOrSet(*this, aType, aInput, [&] {
|
nscoord& cachedISize = aType == IntrinsicISizeType::MinISize
|
||||||
return ComputeIntrinsicISize(aInput, aType);
|
? mCachedMinISize
|
||||||
});
|
: mCachedPrefISize;
|
||||||
|
if (cachedISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||||
|
cachedISize = ComputeIntrinsicISize(aInput, aType);
|
||||||
|
}
|
||||||
|
return cachedISize;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t nsFlexContainerFrame::GetNumLines() const {
|
int32_t nsFlexContainerFrame::GetNumLines() const {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include "mozilla/dom/FlexBinding.h"
|
#include "mozilla/dom/FlexBinding.h"
|
||||||
#include "mozilla/IntrinsicISizesCache.h"
|
|
||||||
#include "nsContainerFrame.h"
|
#include "nsContainerFrame.h"
|
||||||
#include "nsILineIterator.h"
|
#include "nsILineIterator.h"
|
||||||
|
|
||||||
@@ -657,7 +656,8 @@ class nsFlexContainerFrame final : public nsContainerFrame,
|
|||||||
/**
|
/**
|
||||||
* Cached values to optimize IntrinsicISize().
|
* Cached values to optimize IntrinsicISize().
|
||||||
*/
|
*/
|
||||||
mozilla::IntrinsicISizesCache mCachedIntrinsicSizes;
|
nscoord mCachedMinISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
|
nscoord mCachedPrefISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached baselines computed in our last reflow to optimize
|
* Cached baselines computed in our last reflow to optimize
|
||||||
|
|||||||
@@ -9697,13 +9697,19 @@ nscoord nsGridContainerFrame::IntrinsicISize(const IntrinsicSizeInput& aInput,
|
|||||||
if (firstCont != this) {
|
if (firstCont != this) {
|
||||||
return firstCont->IntrinsicISize(aInput, aType);
|
return firstCont->IntrinsicISize(aInput, aType);
|
||||||
}
|
}
|
||||||
return mCachedIntrinsicSizes.GetOrSet(*this, aType, aInput, [&] {
|
|
||||||
return ComputeIntrinsicISize(aInput, aType);
|
nscoord& cachedISize = aType == IntrinsicISizeType::MinISize
|
||||||
});
|
? mCachedMinISize
|
||||||
|
: mCachedPrefISize;
|
||||||
|
if (cachedISize == NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||||
|
cachedISize = ComputeIntrinsicISize(aInput, aType);
|
||||||
|
}
|
||||||
|
return cachedISize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsGridContainerFrame::MarkIntrinsicISizesDirty() {
|
void nsGridContainerFrame::MarkIntrinsicISizesDirty() {
|
||||||
mCachedIntrinsicSizes.Clear();
|
mCachedMinISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
|
mCachedPrefISize = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
for (auto& perAxisBaseline : mBaseline) {
|
for (auto& perAxisBaseline : mBaseline) {
|
||||||
for (auto& baseline : perAxisBaseline) {
|
for (auto& baseline : perAxisBaseline) {
|
||||||
baseline = NS_INTRINSIC_ISIZE_UNKNOWN;
|
baseline = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#define nsGridContainerFrame_h___
|
#define nsGridContainerFrame_h___
|
||||||
|
|
||||||
#include "mozilla/CSSOrderAwareFrameIterator.h"
|
#include "mozilla/CSSOrderAwareFrameIterator.h"
|
||||||
#include "mozilla/IntrinsicISizesCache.h"
|
|
||||||
#include "mozilla/MathAlgorithms.h"
|
#include "mozilla/MathAlgorithms.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/HashTable.h"
|
#include "mozilla/HashTable.h"
|
||||||
@@ -334,7 +333,9 @@ class nsGridContainerFrame final : public nsContainerFrame,
|
|||||||
mozilla::PresShell* aPresShell, ComputedStyle* aStyle);
|
mozilla::PresShell* aPresShell, ComputedStyle* aStyle);
|
||||||
explicit nsGridContainerFrame(ComputedStyle* aStyle,
|
explicit nsGridContainerFrame(ComputedStyle* aStyle,
|
||||||
nsPresContext* aPresContext)
|
nsPresContext* aPresContext)
|
||||||
: nsContainerFrame(aStyle, aPresContext, kClassID) {
|
: nsContainerFrame(aStyle, aPresContext, kClassID),
|
||||||
|
mCachedMinISize(NS_INTRINSIC_ISIZE_UNKNOWN),
|
||||||
|
mCachedPrefISize(NS_INTRINSIC_ISIZE_UNKNOWN) {
|
||||||
for (auto& perAxisBaseline : mBaseline) {
|
for (auto& perAxisBaseline : mBaseline) {
|
||||||
for (auto& baseline : perAxisBaseline) {
|
for (auto& baseline : perAxisBaseline) {
|
||||||
baseline = NS_INTRINSIC_ISIZE_UNKNOWN;
|
baseline = NS_INTRINSIC_ISIZE_UNKNOWN;
|
||||||
@@ -531,7 +532,11 @@ class nsGridContainerFrame final : public nsContainerFrame,
|
|||||||
void AddImplicitNamedAreasInternal(LineNameList& aNameList,
|
void AddImplicitNamedAreasInternal(LineNameList& aNameList,
|
||||||
ImplicitNamedAreas*& aAreas);
|
ImplicitNamedAreas*& aAreas);
|
||||||
|
|
||||||
mozilla::IntrinsicISizesCache mCachedIntrinsicSizes;
|
/**
|
||||||
|
* Cached values to optimize IntrinsicISize().
|
||||||
|
*/
|
||||||
|
nscoord mCachedMinISize;
|
||||||
|
nscoord mCachedPrefISize;
|
||||||
|
|
||||||
// Our baselines, one per BaselineSharingGroup per axis.
|
// Our baselines, one per BaselineSharingGroup per axis.
|
||||||
PerLogicalAxis<PerBaseline<nscoord>> mBaseline;
|
PerLogicalAxis<PerBaseline<nscoord>> mBaseline;
|
||||||
|
|||||||
@@ -6577,13 +6577,9 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
|
|||||||
result.ISize(aWM) = std::min(maxISize, result.ISize(aWM));
|
result.ISize(aWM) = std::min(maxISize, result.ISize(aWM));
|
||||||
}
|
}
|
||||||
|
|
||||||
const nscoord bSizeAsPercentageBasis = ComputeBSizeValueAsPercentageBasis(
|
const IntrinsicSizeInput input(aRenderingContext,
|
||||||
styleBSize, minBSizeCoord, maxBSizeCoord, aCBSize.BSize(aWM),
|
Some(aCBSize.ConvertTo(GetWritingMode(), aWM)),
|
||||||
boxSizingAdjust.BSize(aWM));
|
Nothing());
|
||||||
const IntrinsicSizeInput input(
|
|
||||||
aRenderingContext, Some(aCBSize.ConvertTo(GetWritingMode(), aWM)),
|
|
||||||
Some(LogicalSize(aWM, NS_UNCONSTRAINEDSIZE, bSizeAsPercentageBasis)
|
|
||||||
.ConvertTo(GetWritingMode(), aWM)));
|
|
||||||
const auto& minISizeCoord = stylePos->MinISize(aWM);
|
const auto& minISizeCoord = stylePos->MinISize(aWM);
|
||||||
nscoord minISize;
|
nscoord minISize;
|
||||||
if (!minISizeCoord.IsAuto() && !shouldIgnoreMinMaxISize) {
|
if (!minISizeCoord.IsAuto() && !shouldIgnoreMinMaxISize) {
|
||||||
|
|||||||
@@ -449,11 +449,6 @@ struct MOZ_STACK_CLASS IntrinsicSizeInput final {
|
|||||||
// to NS_UNCONSTRAINEDSIZE.
|
// to NS_UNCONSTRAINEDSIZE.
|
||||||
Maybe<LogicalSize> mPercentageBasisForChildren;
|
Maybe<LogicalSize> mPercentageBasisForChildren;
|
||||||
|
|
||||||
bool HasSomePercentageBasisForChildren() const {
|
|
||||||
return mPercentageBasisForChildren &&
|
|
||||||
!mPercentageBasisForChildren->IsAllValues(NS_UNCONSTRAINEDSIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
IntrinsicSizeInput(gfxContext* aContext,
|
IntrinsicSizeInput(gfxContext* aContext,
|
||||||
const Maybe<LogicalSize>& aContainingBlockSize,
|
const Maybe<LogicalSize>& aContainingBlockSize,
|
||||||
const Maybe<LogicalSize>& aPercentageBasisForChildren)
|
const Maybe<LogicalSize>& aPercentageBasisForChildren)
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
[grid-item-inline-contribution-002.html]
|
||||||
|
expected: FAIL
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[intrinsic-percent-replaced-017.html]
|
||||||
|
expected: FAIL
|
||||||
|
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1910290
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
[intrinsic-percent-replaced-026.html]
|
|
||||||
expected: FAIL
|
|
||||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1888262
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
[intrinsic-percent-replaced-dynamic-007.html]
|
||||||
|
expected: FAIL
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
|
|
||||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
|
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
|
|
||||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1926015">
|
|
||||||
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
|
|
||||||
<meta name="assert" content="This test verifies that the inner flex container's cross-size (height) serves as a percentage basis for its descendants. The img can transfer its height through the aspect-ratio to the inline axis when computing its intrinsic inline size contribution. This determines the .test div's intrinsic inline size.">
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.outer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.inner {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
.test {
|
|
||||||
height: 100%;
|
|
||||||
background: red;
|
|
||||||
}
|
|
||||||
.test > img {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
|
||||||
<div class="outer">
|
|
||||||
<div class="inner">
|
|
||||||
<div class="test">
|
|
||||||
<img src="aspect-ratio/support/200x200-green.png">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
|
|
||||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
|
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
|
|
||||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1926015">
|
|
||||||
<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
|
|
||||||
<meta name="assert" content="This test verifies that the inner flex container's cross-size (height) serves as a percentage basis for its descendants. The canvas can transfer its height through the aspect-ratio to the inline axis when computing its intrinsic inline size contribution. This determines the .test div's intrinsic inline size.">
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.outer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.inner {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
.test {
|
|
||||||
height: 100%;
|
|
||||||
background: green;
|
|
||||||
}
|
|
||||||
.test > canvas {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<p>Test passes if there is a filled green square.</p>
|
|
||||||
<div class="outer">
|
|
||||||
<div class="inner">
|
|
||||||
<div class="test">
|
|
||||||
<canvas width="10" height="10"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
|
|
||||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
|
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
|
|
||||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1888262">
|
|
||||||
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
|
|
||||||
<meta name="assert" content="This test verifies that the inner div's stretched main size (height) serves as a percentage basis for the img's height. The img can transfer its height through the aspect-ratio to the inline axis when computing its intrinsic inline size contribution. This determines the inner div's main-size (width).">
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.outer {
|
|
||||||
display: flex;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
.inner {
|
|
||||||
background: red;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
|
||||||
<div class="outer">
|
|
||||||
<div class="inner">
|
|
||||||
<img src="aspect-ratio/support/200x200-green.png">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
|
|
||||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
|
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
|
|
||||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1931491">
|
|
||||||
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
|
|
||||||
<meta name="assert" content="This test verifies that the inner flex container's main-size (height) serves as a percentage basis for its descendants. The canvas can transfer its height through the aspect-ratio to the inline axis when computing its intrinsic inline size contribution. This determines the .test div's intrinsic inline size.">
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.outer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.inner {
|
|
||||||
display: flex;
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
.test {
|
|
||||||
aspect-ratio: 1 / 1;
|
|
||||||
height: 100%;
|
|
||||||
background: red;
|
|
||||||
}
|
|
||||||
.test > canvas {
|
|
||||||
height: 100%;
|
|
||||||
background: green;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
|
||||||
<div class="outer">
|
|
||||||
<div class="inner">
|
|
||||||
<div class="test">
|
|
||||||
<canvas width="200" height="200"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
Reference in New Issue
Block a user