Bug 1856640: Ensure layout flush for as-of-yet reflowed frames when querying computed style of elements potentially matching container query. r=firefox-style-system-reviewers,emilio
Differential Revision: https://phabricator.services.mozilla.com/D202619
This commit is contained in:
@@ -11562,6 +11562,26 @@ nsIFrame::PhysicalAxes nsIFrame::ShouldApplyOverflowClipping(
|
||||
return clip ? PhysicalAxes::Both : PhysicalAxes::None;
|
||||
}
|
||||
|
||||
bool nsIFrame::HasUnreflowedContainerQueryAncestor() const {
|
||||
// If this frame has done the first reflow, its ancestors are guaranteed to
|
||||
// have as well.
|
||||
if (!HasAnyStateBits(NS_FRAME_FIRST_REFLOW) ||
|
||||
!PresContext()->HasContainerQueryFrames()) {
|
||||
return false;
|
||||
}
|
||||
for (nsIFrame* cur = GetInFlowParent(); cur; cur = cur->GetInFlowParent()) {
|
||||
if (!cur->HasAnyStateBits(NS_FRAME_FIRST_REFLOW)) {
|
||||
// Done first reflow from this ancestor up, including query containers.
|
||||
return false;
|
||||
}
|
||||
if (cur->StyleDisplay()->IsQueryContainer()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// No query container from this frame up to root.
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void GetTagName(nsIFrame* aFrame, nsIContent* aContent, int aResultSize,
|
||||
char* aResult) {
|
||||
|
||||
@@ -1380,6 +1380,8 @@ class nsIFrame : public nsQueryFrame {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool HasUnreflowedContainerQueryAncestor() const;
|
||||
|
||||
private:
|
||||
// The value that the CSS page-name "auto" keyword resolves to for children
|
||||
// of this frame.
|
||||
|
||||
@@ -990,6 +990,19 @@ bool nsComputedDOMStyle::NeedsToFlushLayout(nsCSSPropertyID aPropID) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool nsComputedDOMStyle::NeedsToFlushLayoutForContainerQuery() const {
|
||||
const auto* outerFrame = GetOuterFrame();
|
||||
if (!outerFrame) {
|
||||
return false;
|
||||
}
|
||||
const auto* innerFrame = nsLayoutUtils::GetStyleFrame(outerFrame);
|
||||
MOZ_ASSERT(innerFrame, "No valid inner frame?");
|
||||
// It's possible that potential containers are styled but not yet reflowed,
|
||||
// i.e. They don't have a correct size, which makes any container query
|
||||
// evaluation against them invalid.
|
||||
return innerFrame->HasUnreflowedContainerQueryAncestor();
|
||||
}
|
||||
|
||||
void nsComputedDOMStyle::Flush(Document& aDocument, FlushType aFlushType) {
|
||||
MOZ_ASSERT(mElement->IsInComposedDoc());
|
||||
MOZ_ASSERT(mDocumentWeak == &aDocument);
|
||||
@@ -1051,8 +1064,9 @@ void nsComputedDOMStyle::UpdateCurrentStyleSources(nsCSSPropertyID aPropID) {
|
||||
Flush(*document, FlushType::Frames);
|
||||
}
|
||||
|
||||
if (NeedsToFlushLayout(aPropID)) {
|
||||
MOZ_ASSERT(MayNeedToFlushLayout(aPropID));
|
||||
const bool needsToFlushLayoutForProp = NeedsToFlushLayout(aPropID);
|
||||
if (needsToFlushLayoutForProp || NeedsToFlushLayoutForContainerQuery()) {
|
||||
MOZ_ASSERT_IF(needsToFlushLayoutForProp, MayNeedToFlushLayout(aPropID));
|
||||
didFlush = true;
|
||||
Flush(*document, FlushType::Layout);
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -312,6 +312,10 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration,
|
||||
// Find out if we need to flush layout of the document, depending on the
|
||||
// property that was requested.
|
||||
bool NeedsToFlushLayout(nsCSSPropertyID) const;
|
||||
// Find out if we need to flush layout of the document due to container
|
||||
// query being made before relevant query containers are reflowed at least
|
||||
// once.
|
||||
bool NeedsToFlushLayoutForContainerQuery() const;
|
||||
// Flushes the given document, which must be our document, and potentially the
|
||||
// mElement's document.
|
||||
void Flush(Document&, mozilla::FlushType);
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
[font-relative-units.html]
|
||||
[lh relative inline-size]
|
||||
expected:
|
||||
if (os == "linux") and not debug and not asan and not tsan: [FAIL, PASS]
|
||||
if (os == "win") and debug and (processor == "x86"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86_64"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86"): PASS
|
||||
if (os == "android") and debug: [FAIL, PASS]
|
||||
if (os == "android") and not debug: [FAIL, PASS]
|
||||
[PASS, FAIL]
|
||||
|
||||
[rex relative inline-size]
|
||||
expected: FAIL
|
||||
|
||||
@@ -18,75 +8,5 @@
|
||||
[ric relative inline-size]
|
||||
expected: FAIL
|
||||
|
||||
[rlh relative inline-size]
|
||||
expected:
|
||||
if (os == "linux") and not debug and not asan and not tsan: [FAIL, PASS]
|
||||
if (os == "win") and debug and (processor == "x86"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86_64"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86"): PASS
|
||||
if (os == "android") and debug: [FAIL, PASS]
|
||||
if (os == "android") and not debug: [FAIL, PASS]
|
||||
[PASS, FAIL]
|
||||
|
||||
[em relative inline-size]
|
||||
expected:
|
||||
if (os == "linux") and not debug and not asan and not tsan: [FAIL, PASS]
|
||||
if (os == "win") and debug and (processor == "x86"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86_64"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86"): PASS
|
||||
if (os == "android") and debug: [FAIL, PASS]
|
||||
if (os == "android") and not debug: [FAIL, PASS]
|
||||
[PASS, FAIL]
|
||||
|
||||
[rem relative inline-size]
|
||||
expected:
|
||||
if (os == "linux") and not debug and not asan and not tsan: [FAIL, PASS]
|
||||
if (os == "win") and debug and (processor == "x86"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86_64"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86"): PASS
|
||||
if (os == "android") and debug: [FAIL, PASS]
|
||||
if (os == "android") and not debug: [FAIL, PASS]
|
||||
[PASS, FAIL]
|
||||
|
||||
[ex relative inline-size]
|
||||
expected:
|
||||
if (os == "linux") and not debug and not asan and not tsan: [FAIL, PASS]
|
||||
if (os == "win") and debug and (processor == "x86"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86_64"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86"): PASS
|
||||
if (os == "android") and debug: [FAIL, PASS]
|
||||
if (os == "android") and not debug: [FAIL, PASS]
|
||||
[PASS, FAIL]
|
||||
|
||||
[ch relative inline-size]
|
||||
expected:
|
||||
if (os == "linux") and not debug and not asan and not tsan: [FAIL, PASS]
|
||||
if (os == "win") and debug and (processor == "x86"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86_64"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86"): PASS
|
||||
if (os == "android") and debug: [FAIL, PASS]
|
||||
if (os == "android") and not debug: [FAIL, PASS]
|
||||
[PASS, FAIL]
|
||||
|
||||
[ic relative inline-size]
|
||||
expected:
|
||||
if (os == "linux") and not debug and not asan and not tsan: [FAIL, PASS]
|
||||
if (os == "win") and debug and (processor == "x86"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86_64"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86"): PASS
|
||||
if (os == "android") and debug: [FAIL, PASS]
|
||||
if (os == "android") and not debug: [FAIL, PASS]
|
||||
[PASS, FAIL]
|
||||
|
||||
[cap relative inline-size]
|
||||
expected:
|
||||
if (os == "linux") and not debug and not asan and not tsan: [FAIL, PASS]
|
||||
if (os == "win") and debug and (processor == "x86"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86_64"): PASS
|
||||
if (os == "win") and not debug and (processor == "x86"): PASS
|
||||
if (os == "android") and debug: [FAIL, PASS]
|
||||
if (os == "android") and not debug: [FAIL, PASS]
|
||||
[PASS, FAIL]
|
||||
|
||||
[rcap relative inline-size]
|
||||
expected: FAIL
|
||||
|
||||
Reference in New Issue
Block a user