зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1663722: Make nsPageSequenceFrame gracefully handle SizeToContent calls. r=emilio
nsPageSequenceFrame does a thing where it grows its desired size to fit the AvailableISize and ComputedBSize (under the assumption that those are the actual dimensions of our scrollport, which it wants to make maximal use of). This behavior causes trouble when it's reflowed under the privileged 'sizeToContent' JS API. That API makes us reflow with nscoord_MAX as the viewport's ComputedBSize(), and this nscoord_MAX value gets passed down to be the nsPageSequenceFrame's ComputedBSize as well. When we reach the code in question, we dutifully grow the desired size to that bogus huge value, which is clearly wrong. This patch addresses this issue by simply declining to grow the desired size in the scenario where ComputedBSize() is unconstrained. This leaves us with reasonable values for our desired size (which are actually based on the content, which makes it the right thing to do for the purpose of a SizeToContent() call). Differential Revision: https://phabricator.services.mozilla.com/D135762
This commit is contained in:
Родитель
288e47841c
Коммит
080e18fa47
|
@ -190,10 +190,21 @@ void nsPageSequenceFrame::PopulateReflowOutput(
|
|||
nscoord iSize = wm.IsVertical() ? mSize.Height() : mSize.Width();
|
||||
nscoord bSize = wm.IsVertical() ? mSize.Width() : mSize.Height();
|
||||
|
||||
nscoord availableISize = aReflowInput.AvailableISize();
|
||||
nscoord computedBSize = aReflowInput.ComputedBSize();
|
||||
if (MOZ_UNLIKELY(computedBSize == NS_UNCONSTRAINEDSIZE)) {
|
||||
// We have unconstrained BSize, which should only happen if someone calls
|
||||
// SizeToContent() on our window (which we don't expect to happen for
|
||||
// actual user flows, but is possible for fuzzers to trigger). We just nerf
|
||||
// the ReflowInput's contributions to the std::max() expressions below,
|
||||
// which does indeed make us "size to content", via letting std::max()
|
||||
// choose the scaled iSize/bSize expressions.
|
||||
availableISize = computedBSize = 0;
|
||||
}
|
||||
aReflowOutput.ISize(wm) =
|
||||
std::max(NSToCoordFloor(iSize * scale), aReflowInput.AvailableISize());
|
||||
std::max(NSToCoordFloor(iSize * scale), availableISize);
|
||||
aReflowOutput.BSize(wm) =
|
||||
std::max(NSToCoordFloor(bSize * scale), aReflowInput.ComputedBSize());
|
||||
std::max(NSToCoordFloor(bSize * scale), computedBSize);
|
||||
aReflowOutput.SetOverflowAreasToDesiredBounds();
|
||||
}
|
||||
|
||||
|
@ -275,6 +286,9 @@ void nsPageSequenceFrame::Reflow(nsPresContext* aPresContext,
|
|||
// When we're displayed on-screen, the computed size that we're given is
|
||||
// the size of our scrollport. We need to save this for use in
|
||||
// GetPrintPreviewScale.
|
||||
// (NOTE: It's possible but unlikely that we have an unconstrained BSize
|
||||
// here, if we're being sized to content. GetPrintPreviewScale() checks
|
||||
// for and handles this, when making use of this member-var.)
|
||||
mScrollportSize = aReflowInput.ComputedSize();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const proxy = SpecialPowers.wrap(self).printPreview();
|
||||
proxy.sizeToContent();
|
||||
document.documentElement.className = "";
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
</html>
|
|
@ -3,4 +3,5 @@ load 509839-2.html
|
|||
load 576878.xhtml
|
||||
asserts-if(Android,0-1) load 793844.html
|
||||
skip-if(Android) load 1662259.html
|
||||
skip-if(Android) load 1663722.html
|
||||
skip-if(Android) load 1671503.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче