Bug 1661544 - Ensure initial viewport is computed before reporting innerWidth. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D88947
This commit is contained in:
Botond Ballo
2020-09-09 21:14:31 +00:00
parent 6f140f0ffc
commit 8c28bf105c
5 changed files with 37 additions and 11 deletions

View File

@@ -161,6 +161,7 @@
#include "nsBlockFrame.h" #include "nsBlockFrame.h"
#include "DOMMatrix.h" #include "DOMMatrix.h"
#include "MobileViewportManager.h"
#ifdef ACCESSIBILITY #ifdef ACCESSIBILITY
# include "nsAccessibilityService.h" # include "nsAccessibilityService.h"
@@ -845,13 +846,17 @@ nsRect Element::GetClientAreaRect() {
// We will always have a pres shell if we have a pres context, and we will // We will always have a pres shell if we have a pres context, and we will
// only get here if we have a pres context from the root content document // only get here if we have a pres context from the root content document
// check // check
PresShell* presShell = doc->GetPresShell(); RefPtr<PresShell> presShell = doc->GetPresShell();
// Ensure up to date dimensions, but don't reflow // Ensure up to date dimensions, but don't reflow
RefPtr<nsViewManager> viewManager = presShell->GetViewManager(); RefPtr<nsViewManager> viewManager = presShell->GetViewManager();
if (viewManager) { if (viewManager) {
viewManager->FlushDelayedResize(false); viewManager->FlushDelayedResize(false);
} }
if (RefPtr<MobileViewportManager> mvm =
presShell->GetMobileViewportManager()) {
mvm->EnsureInitialViewportSet();
}
return nsRect(nsPoint(), presContext->GetVisibleArea().Size()); return nsRect(nsPoint(), presContext->GetVisibleArea().Size());
} }

View File

@@ -246,6 +246,7 @@
#include "mozilla/dom/WebIDLGlobalNameHash.h" #include "mozilla/dom/WebIDLGlobalNameHash.h"
#include "mozilla/dom/Worklet.h" #include "mozilla/dom/Worklet.h"
#include "AccessCheck.h" #include "AccessCheck.h"
#include "MobileViewportManager.h"
#ifdef HAVE_SIDEBAR #ifdef HAVE_SIDEBAR
# include "mozilla/dom/ExternalBinding.h" # include "mozilla/dom/ExternalBinding.h"
@@ -3549,7 +3550,7 @@ nsresult nsGlobalWindowOuter::GetInnerSize(CSSIntSize& aSize) {
NS_ENSURE_STATE(mDocShell); NS_ENSURE_STATE(mDocShell);
RefPtr<nsPresContext> presContext = mDocShell->GetPresContext(); RefPtr<nsPresContext> presContext = mDocShell->GetPresContext();
PresShell* presShell = mDocShell->GetPresShell(); RefPtr<PresShell> presShell = mDocShell->GetPresShell();
if (!presContext || !presShell) { if (!presContext || !presShell) {
aSize = CSSIntSize(0, 0); aSize = CSSIntSize(0, 0);
@@ -3563,6 +3564,14 @@ nsresult nsGlobalWindowOuter::GetInnerSize(CSSIntSize& aSize) {
viewManager->FlushDelayedResize(false); viewManager->FlushDelayedResize(false);
} }
// If this is called before the usual triggers for MVM to compute
// an initial viewport (load, DOMMetaAdded, first paint), compute
// one now.
if (RefPtr<MobileViewportManager> mvm =
presShell->GetMobileViewportManager()) {
mvm->EnsureInitialViewportSet();
}
// FIXME: Bug 1598487 - Return the layout viewport instead of the ICB. // FIXME: Bug 1598487 - Return the layout viewport instead of the ICB.
nsSize viewportSize = presContext->GetVisibleArea().Size(); nsSize viewportSize = presContext->GetVisibleArea().Size();
if (presContext->GetDynamicToolbarState() == DynamicToolbarState::Collapsed) { if (presContext->GetDynamicToolbarState() == DynamicToolbarState::Collapsed) {

View File

@@ -183,6 +183,16 @@ MobileViewportManager::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK; return NS_OK;
} }
void MobileViewportManager::EnsureInitialViewportSet() {
if (!mPainted) {
mIsFirstPaint = true;
// Do not set mPainted=true because we may not have a frame
// tree yet and we want to make sure SetInitialViewport()
// gets called once we have a frame tree.
RefreshViewportSize(false);
}
}
void MobileViewportManager::SetInitialViewport() { void MobileViewportManager::SetInitialViewport() {
MVM_LOG("%p: setting initial viewport\n", this); MVM_LOG("%p: setting initial viewport\n", this);
mIsFirstPaint = true; mIsFirstPaint = true;

View File

@@ -89,6 +89,17 @@ class MobileViewportManager final : public nsIDOMEventListener,
* updated, and the visual viewport size needs to be updated. */ * updated, and the visual viewport size needs to be updated. */
void ResolutionUpdated(mozilla::ResolutionChangeOrigin aOrigin); void ResolutionUpdated(mozilla::ResolutionChangeOrigin aOrigin);
/* Ensure that the initial viewport has been set based on the meta viewport
tag. There are two important differences between this and
SetInitialViewport():
1. This may be called before page load or before-first-paint, if
e.g. page content queries innerWidth early on.
2. This has no effect if SetInitialViewport() has already been
called, and thus will not clobber a viewport that has
previously been set (and perhaps modified since then).
*/
void EnsureInitialViewportSet();
/* Called to compute the initial viewport on page load or before-first-paint, /* Called to compute the initial viewport on page load or before-first-paint,
* whichever happens first. Also called directly if we are created after the * whichever happens first. Also called directly if we are created after the
* presShell is initialized. */ * presShell is initialized. */

View File

@@ -1,9 +0,0 @@
[noopener-noreferrer-sizing.window.html]
[window.open() with noreferrer should have equal viewport width and height]
expected:
if os == "android": FAIL
[window.open() with noopener should have equal viewport width and height]
expected:
if os == "android": FAIL