1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef MobileViewportManager_h_
8 #define MobileViewportManager_h_
10 #include "mozilla/Logging.h"
11 #include "mozilla/Maybe.h"
12 #include "mozilla/MVMContext.h"
13 #include "mozilla/PresShellForwards.h"
15 #include "nsIDOMEventListener.h"
16 #include "nsIObserver.h"
27 } // namespace mozilla
29 class MobileViewportManager final
: public nsIDOMEventListener
,
33 NS_DECL_NSIDOMEVENTLISTENER
36 /* The MobileViewportManager might be required to handle meta-viewport tags
37 * and changes, or it might not (e.g. if we are in a desktop-zooming setup).
38 * This enum indicates which mode the manager is in. It might make sense to
39 * split these two "modes" into two separate classes but for now they have a
40 * bunch of shared code and it's uncertain if that shared set will expand or
42 enum class ManagerType
{ VisualAndMetaViewport
, VisualViewportOnly
};
44 explicit MobileViewportManager(mozilla::MVMContext
* aContext
,
48 ManagerType
GetManagerType() { return mManagerType
; }
50 /* Provide a resolution to use during the first paint instead of the default
51 * resolution computed from the viewport info metadata. This is in the same
52 * "units" as the argument to nsDOMWindowUtils::SetResolutionAndScaleTo.
53 * Also takes the previous display dimensions as they were at the time the
54 * resolution was stored in order to correctly adjust the resolution if the
55 * device was rotated in the meantime. */
56 void SetRestoreResolution(float aResolution
,
57 mozilla::LayoutDeviceIntSize aDisplaySize
);
59 /* Compute the "intrinsic resolution", which is the smallest resolution at
60 * which the layout viewport fills the visual viewport. (In typical
61 * scenarios, where the aspect ratios of the two viewports match, it's the
62 * resolution at which they are the same size.)
64 * The returned resolution is suitable for passing to
65 * PresShell::SetResolutionAndScaleTo(). It's not in typed units for
66 * reasons explained at the declaration of FrameMetrics::mPresShellResolution.
68 float ComputeIntrinsicResolution() const;
70 /* The only direct calls to this should be in test code.
71 * Normally, it gets called by HandleEvent().
73 void HandleDOMMetaAdded();
76 void SetRestoreResolution(float aResolution
);
79 /* Notify the MobileViewportManager that a reflow is about to happen. This
80 * triggers the MVM to update its internal notion of display size and CSS
81 * viewport, so that code that queries those during the reflow gets an
84 void UpdateSizesBeforeReflow();
86 /* Notify the MobileViewportManager that a reflow was requested in the
88 void RequestReflow(bool aForceAdjustResolution
);
90 /* Notify the MobileViewportManager that the resolution on the presShell was
91 * updated, and the visual viewport size needs to be updated. */
92 void ResolutionUpdated(mozilla::ResolutionChangeOrigin aOrigin
);
94 /* Called to compute the initial viewport on page load or before-first-paint,
95 * whichever happens first. Also called directly if we are created after the
96 * presShell is initialized. */
97 void SetInitialViewport();
99 const mozilla::LayoutDeviceIntSize
& DisplaySize() const {
104 * Shrink the content to fit it to the display width if no initial-scale is
105 * specified and if the content is still wider than the display width.
107 void ShrinkToDisplaySizeIfNeeded();
110 * Similar to UpdateVisualViewportSize but this should be called only when we
111 * need to update visual viewport size in response to dynamic toolbar
113 * This function doesn't cause any reflows, just fires a visual viewport
116 void UpdateVisualViewportSizeByDynamicToolbar(
117 mozilla::ScreenIntCoord aToolbarHeight
);
119 nsSize
GetVisualViewportSizeUpdatedByDynamicToolbar() const {
120 return mVisualViewportSizeUpdatedByDynamicToolbar
;
124 * This refreshes the visual viewport size based on the most recently
125 * available information. It is intended to be called in particular after
126 * the root scrollframe does a reflow, which may make scrollbars appear or
127 * disappear if the content changed size.
129 void UpdateVisualViewportSizeForPotentialScrollbarChange();
132 * Returns the composition size in CSS units when zoomed to the intrinsic
135 mozilla::CSSSize
GetIntrinsicCompositionSize() const;
137 mozilla::ParentLayerSize
GetCompositionSizeWithoutDynamicToolbar() const;
139 static mozilla::LazyLogModule gLog
;
142 ~MobileViewportManager();
144 /* Main helper method to update the CSS viewport and any other properties that
146 void RefreshViewportSize(bool aForceAdjustResolution
);
148 /* Secondary main helper method to update just the visual viewport size. */
149 void RefreshVisualViewportSize();
151 /* Helper to clamp the given zoom by the min/max in the viewport info. */
152 mozilla::CSSToScreenScale
ClampZoom(
153 const mozilla::CSSToScreenScale
& aZoom
,
154 const nsViewportInfo
& aViewportInfo
) const;
156 /* Helper to update the given zoom according to changed display and viewport
158 mozilla::CSSToScreenScale
ScaleZoomWithDisplayWidth(
159 const mozilla::CSSToScreenScale
& aZoom
,
160 const float& aDisplayWidthChangeRatio
,
161 const mozilla::CSSSize
& aNewViewport
,
162 const mozilla::CSSSize
& aOldViewport
);
164 mozilla::CSSToScreenScale
ResolutionToZoom(
165 const mozilla::LayoutDeviceToLayerScale
& aResolution
) const;
166 mozilla::LayoutDeviceToLayerScale
ZoomToResolution(
167 const mozilla::CSSToScreenScale
& aZoom
) const;
169 /* Updates the presShell resolution and the visual viewport size for various
170 * types of changes. */
171 void UpdateResolutionForFirstPaint(const mozilla::CSSSize
& aViewportSize
);
172 void UpdateResolutionForViewportSizeChange(
173 const mozilla::CSSSize
& aViewportSize
,
174 const mozilla::Maybe
<float>& aDisplayWidthChangeRatio
);
175 void UpdateResolutionForContentSizeChange(
176 const mozilla::CSSSize
& aContentSize
);
178 void ApplyNewZoom(const mozilla::ScreenIntSize
& aDisplaySize
,
179 const mozilla::CSSToScreenScale
& aNewZoom
);
181 void UpdateVisualViewportSize(const mozilla::ScreenIntSize
& aDisplaySize
,
182 const mozilla::CSSToScreenScale
& aZoom
);
184 /* Updates the displayport margins for the presShell's root scrollable frame
186 void UpdateDisplayPortMargins();
188 /* Helper function for ComputeIntrinsicResolution(). */
189 mozilla::CSSToScreenScale
ComputeIntrinsicScale(
190 const nsViewportInfo
& aViewportInfo
,
191 const mozilla::ScreenIntSize
& aDisplaySize
,
192 const mozilla::CSSSize
& aViewportOrContentSize
) const;
195 * Returns the screen size subtracted the scrollbar sizes from |aDisplaySize|.
197 mozilla::ScreenIntSize
GetCompositionSize(
198 const mozilla::ScreenIntSize
& aDisplaySize
) const;
200 mozilla::CSSToScreenScale
GetZoom() const;
202 RefPtr
<mozilla::MVMContext
> mContext
;
203 ManagerType mManagerType
;
206 mozilla::LayoutDeviceIntSize mDisplaySize
;
207 mozilla::CSSSize mMobileViewportSize
;
208 mozilla::Maybe
<float> mRestoreResolution
;
209 mozilla::Maybe
<mozilla::ScreenIntSize
> mRestoreDisplaySize
;
211 * The visual viewport size updated by the dynamic toolbar transitions. This
212 * is typically used for the VisualViewport width/height APIs.
213 * NOTE: If you want to use this value, you should make sure to flush
214 * position:fixed elements layout and update
215 * FrameMetrics.mFixedLayerMargins to conform with this value.
217 nsSize mVisualViewportSizeUpdatedByDynamicToolbar
;