Bug 1906132 - Propagate BResize flag from viewport frame to root scroll frame. r=dholbert a=RyanVM

The regression range is baffling, but it just shows a missing
invalidation.

The extension has worked around this upstream:

  a48ff54cf6

But the root cause is a bug in Firefox. The popup here had styles much
like:

```
html, body, #root {
  height: 100%;
  min-height: 100%;
  width: auto;
  min-width: 320px;
}
```

The popup starts off zero-sized, but then gets re-measured async at some
point by the extension code.

Main issue here is that, due to the bresize, we reflow the viewport,
then the html, but the html loses the bresize flag. So we don't reflow
the body element to give it the right height.

Before my patch, the body was reflowed because there was a BFC under it,
so it had the NS_BLOCK_HAS_CLEAR_CHILDREN flag, which ended up papering
over this bug.

I think this can only happen with the special shrink-wrap resize mode,
because it's the only thing that can turn a percentage bsize like 100%
from behaving like a percentage to behave like auto... So I haven't been
able to reproduce outside of our extension popup usage. Otherwise the
percentages resolving to different things would set the bresize flag
appropriately.

Differential Revision: https://phabricator.services.mozilla.com/D215842
This commit is contained in:
Emilio Cobos Álvarez 2024-07-05 17:50:41 +00:00
parent e8ccb33478
commit ff5baf3e9e
3 changed files with 65 additions and 0 deletions

View file

@ -363,6 +363,8 @@ https_first_disabled = true
["browser_ext_popup_background.js"] ["browser_ext_popup_background.js"]
["browser_ext_popup_bug1906132.js"]
["browser_ext_popup_corners.js"] ["browser_ext_popup_corners.js"]
["browser_ext_popup_focus.js"] ["browser_ext_popup_focus.js"]

View file

@ -0,0 +1,57 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function test_bug_1906132() {
let extension = ExtensionTestUtils.loadExtension({
background() {},
manifest: {
browser_action: {
default_popup: "popup.html",
default_area: "navbar",
browser_style: false,
},
},
files: {
"popup.html": `
<!doctype html>
<style>
:root, body, #root {
margin: 0;
height: 100%;
min-height: 100%;
width: auto;
min-width: 320px;
}
:root {
background: red;
}
body {
background: green;
}
#content {
height: 200px;
}
</style>
<div id="root">
<div id="content">
some content
</div>
</div>
`,
},
});
await extension.startup();
clickBrowserAction(extension);
let browser = await awaitExtensionPanel(extension);
is(browser.getBoundingClientRect().height, 200, "Should be the right height");
await closeBrowserAction(extension);
await extension.unload();
});

View file

@ -353,6 +353,12 @@ void ViewportFrame::Reflow(nsPresContext* aPresContext,
// Reflow the frame // Reflow the frame
kidReflowInput.SetComputedBSize(aReflowInput.ComputedBSize()); kidReflowInput.SetComputedBSize(aReflowInput.ComputedBSize());
if (aReflowInput.IsBResizeForWM(kidWM)) {
kidReflowInput.SetBResize(true);
}
if (aReflowInput.IsBResizeForPercentagesForWM(kidWM)) {
kidReflowInput.mFlags.mIsBResizeForPercentages = true;
}
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowInput, 0, 0, ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowInput, 0, 0,
ReflowChildFlags::Default, aStatus); ReflowChildFlags::Default, aStatus);
kidBSize = kidDesiredSize.BSize(wm); kidBSize = kidDesiredSize.BSize(wm);