зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1586986 - Fire visual viewport resize events and flush position:fixed elements' layout in the same way what Chrome does. r=botond
On Chrome, visual viewport resize event is fired repeatedly during dynamic toolbar transitions and visual viewport height obtained by the VisualViewport API is also changed, but in terms of layout the height value is never used until the dynamic toolbar height reaches to zero or is changed from zero. The height used at the time is the height for vh units when the toolbar height reaches to zero and the ICB height when the toolbar height is changed from zero. To do so, we need to have another visual viewport size in parallel to the original one and use them depending on situations. Differential Revision: https://phabricator.services.mozilla.com/D52338 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1737c375d1
Коммит
7afdb8487c
|
@ -71,7 +71,12 @@ CSSSize VisualViewport::VisualViewportSize() const {
|
|||
// Fetch the pres shell after the layout flush, as it might have destroyed it.
|
||||
if (PresShell* presShell = GetPresShell()) {
|
||||
if (presShell->IsVisualViewportSizeSet()) {
|
||||
size = CSSRect::FromAppUnits(presShell->GetVisualViewportSize());
|
||||
DynamicToolbarState state = presShell->GetDynamicToolbarState();
|
||||
size = CSSRect::FromAppUnits(
|
||||
(state == DynamicToolbarState::InTransition ||
|
||||
state == DynamicToolbarState::Collapsed)
|
||||
? presShell->GetVisualViewportSizeUpdatedByDynamicToolbar()
|
||||
: presShell->GetVisualViewportSize());
|
||||
} else {
|
||||
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
|
||||
if (sf) {
|
||||
|
|
|
@ -39,6 +39,7 @@ class MockMVMContext : public MVMContext {
|
|||
MOCK_METHOD0(Destroy, void());
|
||||
|
||||
MOCK_METHOD1(SetVisualViewportSize, void(const CSSSize& aSize));
|
||||
MOCK_METHOD0(PostVisualViewportResizeEventByDynamicToolbar, void());
|
||||
MOCK_METHOD0(UpdateDisplayPortMargins, void());
|
||||
|
||||
void SetMVM(MobileViewportManager* aMVM) { mMVM = aMVM; }
|
||||
|
|
|
@ -150,6 +150,17 @@ void GeckoMVMContext::SetVisualViewportSize(const CSSSize& aSize) {
|
|||
nsLayoutUtils::SetVisualViewportSize(mPresShell, aSize);
|
||||
}
|
||||
|
||||
void GeckoMVMContext::PostVisualViewportResizeEventByDynamicToolbar() {
|
||||
MOZ_ASSERT(mDocument);
|
||||
|
||||
// We only fire visual viewport events and don't want to cause any explicit
|
||||
// reflows here since in general we don't use the up-to-date visual viewport
|
||||
// size for layout.
|
||||
if (auto* window = nsGlobalWindowInner::Cast(mDocument->GetInnerWindow())) {
|
||||
window->VisualViewport()->PostResizeEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void GeckoMVMContext::UpdateDisplayPortMargins() {
|
||||
MOZ_ASSERT(mPresShell);
|
||||
if (nsIFrame* root = mPresShell->GetRootScrollFrame()) {
|
||||
|
|
|
@ -53,6 +53,7 @@ class GeckoMVMContext : public MVMContext {
|
|||
void SetResolutionAndScaleTo(float aResolution,
|
||||
ResolutionChangeOrigin aOrigin) override;
|
||||
void SetVisualViewportSize(const CSSSize& aSize) override;
|
||||
void PostVisualViewportResizeEventByDynamicToolbar() override;
|
||||
void UpdateDisplayPortMargins() override;
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void Reflow(const CSSSize& aNewSize) override;
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ class MVMContext {
|
|||
virtual void SetResolutionAndScaleTo(float aResolution,
|
||||
ResolutionChangeOrigin aOrigin) = 0;
|
||||
virtual void SetVisualViewportSize(const CSSSize& aSize) = 0;
|
||||
virtual void PostVisualViewportResizeEventByDynamicToolbar() = 0;
|
||||
virtual void UpdateDisplayPortMargins() = 0;
|
||||
|
||||
virtual void Reflow(const CSSSize& aNewSize) = 0;
|
||||
|
|
|
@ -491,6 +491,30 @@ void MobileViewportManager::UpdateVisualViewportSize(
|
|||
mContext->SetVisualViewportSize(compSize);
|
||||
}
|
||||
|
||||
CSSToScreenScale MobileViewportManager::GetZoom() const {
|
||||
CSSToLayoutDeviceScale cssToDev = mContext->CSSToDevPixelScale();
|
||||
LayoutDeviceToLayerScale res(mContext->GetResolution());
|
||||
return ResolutionToZoom(res, cssToDev);
|
||||
}
|
||||
|
||||
void MobileViewportManager::UpdateVisualViewportSizeByDynamicToolbar(
|
||||
ScreenIntCoord aToolbarHeight) {
|
||||
if (!mContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||
displaySize.height += aToolbarHeight;
|
||||
CSSSize compSize = ScreenSize(GetCompositionSize(displaySize)) / GetZoom();
|
||||
|
||||
mVisualViewportSizeUpdatedByDynamicToolbar =
|
||||
nsSize(nsPresContext::CSSPixelsToAppUnits(compSize.width),
|
||||
nsPresContext::CSSPixelsToAppUnits(compSize.height));
|
||||
|
||||
mContext->PostVisualViewportResizeEventByDynamicToolbar();
|
||||
}
|
||||
|
||||
void MobileViewportManager::UpdateDisplayPortMargins() {
|
||||
if (!mContext) {
|
||||
return;
|
||||
|
@ -509,13 +533,7 @@ void MobileViewportManager::RefreshVisualViewportSize() {
|
|||
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||
|
||||
CSSToLayoutDeviceScale cssToDev = mContext->CSSToDevPixelScale();
|
||||
LayoutDeviceToLayerScale res(mContext->GetResolution());
|
||||
CSSToScreenScale zoom = ViewTargetAs<ScreenPixel>(
|
||||
cssToDev * res / ParentLayerToLayerScale(1),
|
||||
PixelCastJustification::ScreenIsParentLayerForRoot);
|
||||
|
||||
UpdateVisualViewportSize(displaySize, zoom);
|
||||
UpdateVisualViewportSize(displaySize, GetZoom());
|
||||
}
|
||||
|
||||
void MobileViewportManager::RefreshViewportSize(bool aForceAdjustResolution) {
|
||||
|
|
|
@ -87,6 +87,20 @@ class MobileViewportManager final : public nsIDOMEventListener,
|
|||
void ShrinkToDisplaySizeIfNeeded(nsViewportInfo& aViewportInfo,
|
||||
const mozilla::ScreenIntSize& aDisplaySize);
|
||||
|
||||
/*
|
||||
* Similar to UpdateVisualViewportSize but this should be called only when we
|
||||
* need to update visual viewport size in response to dynamic toolbar
|
||||
* transitions.
|
||||
* This function doesn't cause any reflows, just fires a visual viewport
|
||||
* resize event.
|
||||
*/
|
||||
void UpdateVisualViewportSizeByDynamicToolbar(
|
||||
mozilla::ScreenIntCoord aToolbarHeight);
|
||||
|
||||
nsSize GetVisualViewportSizeUpdatedByDynamicToolbar() const {
|
||||
return mVisualViewportSizeUpdatedByDynamicToolbar;
|
||||
}
|
||||
|
||||
private:
|
||||
~MobileViewportManager();
|
||||
|
||||
|
@ -145,6 +159,8 @@ class MobileViewportManager final : public nsIDOMEventListener,
|
|||
mozilla::ScreenIntSize GetCompositionSize(
|
||||
const mozilla::ScreenIntSize& aDisplaySize) const;
|
||||
|
||||
mozilla::CSSToScreenScale GetZoom() const;
|
||||
|
||||
RefPtr<mozilla::MVMContext> mContext;
|
||||
bool mIsFirstPaint;
|
||||
bool mPainted;
|
||||
|
@ -152,6 +168,14 @@ class MobileViewportManager final : public nsIDOMEventListener,
|
|||
mozilla::CSSSize mMobileViewportSize;
|
||||
mozilla::Maybe<float> mRestoreResolution;
|
||||
mozilla::Maybe<mozilla::ScreenIntSize> mRestoreDisplaySize;
|
||||
/*
|
||||
* The visual viewport size updated by the dynamic toolbar transitions. This
|
||||
* is typically used for the VisualViewport width/height APIs.
|
||||
* NOTE: If you want to use this value, you should make sure to flush
|
||||
* position:fixed elements layout and update
|
||||
* FrameMetrics.mFixedLayerMargins to conform with this value.
|
||||
*/
|
||||
nsSize mVisualViewportSizeUpdatedByDynamicToolbar;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10738,6 +10738,19 @@ nsSize PresShell::GetLayoutViewportSize() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
nsSize PresShell::GetVisualViewportSizeUpdatedByDynamicToolbar() const {
|
||||
NS_ASSERTION(mVisualViewportSizeSet,
|
||||
"asking for visual viewport size when its not set?");
|
||||
if (!mMobileViewportManager) {
|
||||
return mVisualViewportSize;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(GetDynamicToolbarState() == DynamicToolbarState::InTransition ||
|
||||
GetDynamicToolbarState() == DynamicToolbarState::Collapsed);
|
||||
|
||||
return mMobileViewportManager->GetVisualViewportSizeUpdatedByDynamicToolbar();
|
||||
}
|
||||
|
||||
void PresShell::RecomputeFontSizeInflationEnabled() {
|
||||
mFontSizeInflationEnabled = DetermineFontSizeInflationState();
|
||||
|
||||
|
|
|
@ -1500,6 +1500,18 @@ class PresShell final : public nsStubDocumentObserver,
|
|||
|
||||
nsPoint GetVisualViewportOffsetRelativeToLayoutViewport() const;
|
||||
|
||||
// Returns state of the dynamic toolbar.
|
||||
DynamicToolbarState GetDynamicToolbarState() const {
|
||||
if (!mPresContext) {
|
||||
return DynamicToolbarState::None;
|
||||
}
|
||||
|
||||
return mPresContext->GetDynamicToolbarState();
|
||||
}
|
||||
// Returns the visual viewport size during the dynamic toolbar is being
|
||||
// shown/hidden.
|
||||
nsSize GetVisualViewportSizeUpdatedByDynamicToolbar() const;
|
||||
|
||||
/* Enable/disable author style level. Disabling author style disables the
|
||||
* entire author level of the cascade, including the HTML preshint level.
|
||||
*/
|
||||
|
|
|
@ -218,6 +218,15 @@ enum class RenderingStateFlags : uint8_t {
|
|||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(RenderingStateFlags)
|
||||
|
||||
// The state of the dynamic toolbar on Mobile.
|
||||
enum class DynamicToolbarState {
|
||||
None, // No dynamic toolbar, i.e. the toolbar is static or there is
|
||||
// no available toolbar.
|
||||
Expanded, // The dynamic toolbar is expanded to the maximum height.
|
||||
InTransition, // The dynamic toolbar is being shown/hidden.
|
||||
Collapsed, // The dynamic toolbar is collapsed to zero height.
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
enum class VerifyReflowFlags {
|
||||
|
|
|
@ -9033,6 +9033,21 @@ ScrollMetadata nsLayoutUtils::ComputeScrollMetadata(
|
|||
viewport.SizeTo(nsLayoutUtils::ExpandHeightForViewportUnits(
|
||||
presContext, viewport.Size()));
|
||||
metrics.SetLayoutViewport(viewport);
|
||||
|
||||
// We need to set 'fixed margins' to adjust 'fixed margins' value on the
|
||||
// composiutor in the case where the dynamic toolbar is completely
|
||||
// hidden because the margin value on the compositor is offset from the
|
||||
// position where the dynamic toolbar is completely VISIBLE but now the
|
||||
// toolbar is completely HIDDEN we need to adjust the difference on the
|
||||
// compositor.
|
||||
if (presContext->GetDynamicToolbarState() ==
|
||||
DynamicToolbarState::Collapsed) {
|
||||
metrics.SetFixedLayerMargins(
|
||||
ScreenMargin(0, 0,
|
||||
presContext->GetDynamicToolbarHeight() -
|
||||
presContext->GetDynamicToolbarMaxHeight(),
|
||||
0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -169,6 +169,7 @@ nsPresContext::nsPresContext(dom::Document* aDocument, nsPresContextType aType)
|
|||
mCurAppUnitsPerDevPixel(0),
|
||||
mAutoQualityMinFontSizePixelsPref(0),
|
||||
mDynamicToolbarMaxHeight(0),
|
||||
mDynamicToolbarHeight(0),
|
||||
mPageSize(-1, -1),
|
||||
mPageScale(0.0),
|
||||
mPPScale(1.0f),
|
||||
|
@ -675,6 +676,7 @@ nsresult nsPresContext::Init(nsDeviceContext* aDeviceContext) {
|
|||
if (BrowserChild* browserChild =
|
||||
BrowserChild::GetFrom(mDocument->GetDocShell())) {
|
||||
mDynamicToolbarMaxHeight = browserChild->GetDynamicToolbarMaxHeight();
|
||||
mDynamicToolbarHeight = mDynamicToolbarMaxHeight;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2546,6 +2548,37 @@ void nsPresContext::UpdateDynamicToolbarOffset(ScreenIntCoord aOffset) {
|
|||
}
|
||||
|
||||
MOZ_ASSERT(-mDynamicToolbarMaxHeight <= aOffset && aOffset <= 0);
|
||||
if (mDynamicToolbarHeight == mDynamicToolbarMaxHeight + aOffset) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Forcibly flush position:fixed elements in the case where the dynamic
|
||||
// toolbar is going to be completely hidden or starts to be visible so that
|
||||
// %-based style values will be recomputed with the visual viewport size which
|
||||
// is including the area covered by the dynamic toolbar.
|
||||
if (mDynamicToolbarHeight == 0 || aOffset == -mDynamicToolbarMaxHeight) {
|
||||
mPresShell->MarkFixedFramesForReflow(IntrinsicDirty::Resize);
|
||||
}
|
||||
|
||||
mDynamicToolbarHeight = mDynamicToolbarMaxHeight + aOffset;
|
||||
|
||||
if (RefPtr<MobileViewportManager> mvm =
|
||||
mPresShell->GetMobileViewportManager()) {
|
||||
mvm->UpdateVisualViewportSizeByDynamicToolbar(-aOffset);
|
||||
}
|
||||
}
|
||||
|
||||
DynamicToolbarState nsPresContext::GetDynamicToolbarState() const {
|
||||
if (!IsRootContentDocumentCrossProcess() || !HasDynamicToolbar()) {
|
||||
return DynamicToolbarState::None;
|
||||
}
|
||||
|
||||
if (mDynamicToolbarMaxHeight == mDynamicToolbarHeight) {
|
||||
return DynamicToolbarState::Expanded;
|
||||
} else if (mDynamicToolbarHeight == 0) {
|
||||
return DynamicToolbarState::Collapsed;
|
||||
}
|
||||
return DynamicToolbarState::InTransition;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/AppUnits.h"
|
||||
#include "mozilla/MediaEmulationData.h"
|
||||
#include "mozilla/PresShellForwards.h"
|
||||
#include "prclist.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIMessageManager.h"
|
||||
|
@ -396,6 +397,15 @@ class nsPresContext : public nsISupports,
|
|||
* |aOffset| must be offset from the bottom edge of the ICB and it's negative.
|
||||
*/
|
||||
void UpdateDynamicToolbarOffset(mozilla::ScreenIntCoord aOffset);
|
||||
mozilla::ScreenIntCoord GetDynamicToolbarHeight() const {
|
||||
MOZ_ASSERT(IsRootContentDocumentCrossProcess());
|
||||
return mDynamicToolbarHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state of the dynamic toolbar.
|
||||
*/
|
||||
mozilla::DynamicToolbarState GetDynamicToolbarState() const;
|
||||
|
||||
/**
|
||||
* Return true if this presentation context is a paginated
|
||||
|
@ -1195,6 +1205,7 @@ class nsPresContext : public nsISupports,
|
|||
nsSize mSizeForViewportUnits;
|
||||
// The maximum height of the dynamic toolbar on mobile.
|
||||
mozilla::ScreenIntCoord mDynamicToolbarMaxHeight;
|
||||
mozilla::ScreenIntCoord mDynamicToolbarHeight;
|
||||
nsSize mPageSize;
|
||||
float mPageScale;
|
||||
float mPPScale;
|
||||
|
|
|
@ -387,9 +387,15 @@ nsSize ViewportFrame::AdjustViewportSizeForFixedPosition(
|
|||
// Layout fixed position elements to the visual viewport size if and only if
|
||||
// it has been set and it is larger than the computed size, otherwise use the
|
||||
// computed size.
|
||||
if (presShell->IsVisualViewportSizeSet() &&
|
||||
result < presShell->GetVisualViewportSize()) {
|
||||
result = presShell->GetVisualViewportSize();
|
||||
if (presShell->IsVisualViewportSizeSet()) {
|
||||
if (presShell->GetDynamicToolbarState() == DynamicToolbarState::Collapsed &&
|
||||
result < presShell->GetVisualViewportSizeUpdatedByDynamicToolbar()) {
|
||||
// We need to use the viewport size updated by the dynamic toolbar in the
|
||||
// case where the dynamic toolbar is completely hidden.
|
||||
result = presShell->GetVisualViewportSizeUpdatedByDynamicToolbar();
|
||||
} else if (result < presShell->GetVisualViewportSize()) {
|
||||
result = presShell->GetVisualViewportSize();
|
||||
}
|
||||
}
|
||||
// Expand the size to the layout viewport size if necessary.
|
||||
const nsSize layoutViewportSize = presShell->GetLayoutViewportSize();
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=0.5">
|
||||
<style>
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
body {
|
||||
width: 200%;
|
||||
height: 2000px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#fixed-element {
|
||||
width: 100%;
|
||||
height: 200%;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
<div id="fixed-element"></div>
|
|
@ -60,6 +60,7 @@ open class BaseSessionTest(noErrorCollector: Boolean = false) {
|
|||
const val COLORS_HTML_PATH = "/assets/www/colors.html"
|
||||
const val FIXED_BOTTOM = "/assets/www/fixedbottom.html"
|
||||
const val FIXED_VH = "/assets/www/fixedvh.html"
|
||||
const val FIXED_PERCENT = "/assets/www/fixedpercent.html"
|
||||
const val STORAGE_TITLE_HTML_PATH = "/assets/www/reflect_local_storage_into_title.html"
|
||||
const val HUNG_SCRIPT = "/assets/www/hungScript.html"
|
||||
const val PUSH_HTML_PATH = "/assets/www/push/push.html"
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.junit.Test
|
|||
import org.junit.runner.RunWith
|
||||
import org.mozilla.geckoview.GeckoResult
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDisplay
|
||||
import org.hamcrest.Matchers.closeTo
|
||||
import org.hamcrest.Matchers.equalTo
|
||||
|
||||
private const val SCREEN_WIDTH = 100
|
||||
|
@ -133,4 +134,73 @@ class DynamicToolbarTest : BaseSessionTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
|
||||
@Test
|
||||
fun visualViewportEvents() {
|
||||
val dynamicToolbarMaxHeight = SCREEN_HEIGHT / 2
|
||||
sessionRule.display?.run { setDynamicToolbarMaxHeight(dynamicToolbarMaxHeight) }
|
||||
|
||||
// Set active since setVerticalClipping call affects only for forground tab.
|
||||
mainSession.setActive(true)
|
||||
|
||||
mainSession.loadTestPath(BaseSessionTest.FIXED_VH)
|
||||
mainSession.waitForPageStop()
|
||||
|
||||
val pixelRatio = sessionRule.session.evaluateJS("window.devicePixelRatio") as Double
|
||||
val scale = sessionRule.session.evaluateJS("window.visualViewport.scale") as Double
|
||||
|
||||
for (i in 1..dynamicToolbarMaxHeight) {
|
||||
// Simulate the dynamic toolbar is going to be hidden.
|
||||
sessionRule.display?.run { setVerticalClipping(-i) }
|
||||
|
||||
val expectedViewportHeight = (SCREEN_HEIGHT - dynamicToolbarMaxHeight + i) / scale / pixelRatio
|
||||
val promise = sessionRule.session.evaluatePromiseJS("""
|
||||
new Promise(resolve => {
|
||||
window.visualViewport.addEventListener('resize', resolve(window.visualViewport.height));
|
||||
});
|
||||
""".trimIndent())
|
||||
|
||||
assertThat("The visual viewport height should be changed in response to the dynamc toolbar transition",
|
||||
promise.value as Double, closeTo(expectedViewportHeight, .01))
|
||||
}
|
||||
}
|
||||
|
||||
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
|
||||
@Test
|
||||
fun percentBaseValueOnPositionFixedElement() {
|
||||
val dynamicToolbarMaxHeight = SCREEN_HEIGHT / 2
|
||||
sessionRule.display?.run { setDynamicToolbarMaxHeight(dynamicToolbarMaxHeight) }
|
||||
|
||||
// Set active since setVerticalClipping call affects only for forground tab.
|
||||
mainSession.setActive(true)
|
||||
|
||||
mainSession.loadTestPath(BaseSessionTest.FIXED_PERCENT)
|
||||
mainSession.waitForPageStop()
|
||||
|
||||
val originalHeight = mainSession.evaluateJS("""
|
||||
getComputedStyle(document.querySelector('#fixed-element')).height
|
||||
""".trimIndent()) as String
|
||||
|
||||
// Set the vertical clipping value to the middle of toolbar transition.
|
||||
sessionRule.display?.run { setVerticalClipping(-dynamicToolbarMaxHeight / 2) }
|
||||
|
||||
var height = mainSession.evaluateJS("""
|
||||
getComputedStyle(document.querySelector('#fixed-element')).height
|
||||
""".trimIndent()) as String
|
||||
|
||||
assertThat("The %-based height should be the static in the middle of toolbar tansition",
|
||||
height, equalTo(originalHeight))
|
||||
|
||||
// Set the vertical clipping value to hide the toolbar completely.
|
||||
sessionRule.display?.run { setVerticalClipping(-dynamicToolbarMaxHeight) }
|
||||
height = mainSession.evaluateJS("""
|
||||
getComputedStyle(document.querySelector('#fixed-element')).height
|
||||
""".trimIndent()) as String
|
||||
|
||||
val scale = sessionRule.session.evaluateJS("window.visualViewport.scale") as Double
|
||||
val expectedHeight = (SCREEN_HEIGHT / scale).toInt()
|
||||
assertThat("The %-based height should be now recomputed based on the screen height",
|
||||
height, equalTo(expectedHeight.toString() + "px"))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче