1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MobileViewportManager_h_
#define MobileViewportManager_h_
#include "mozilla/Logging.h"
#include "mozilla/Maybe.h"
#include "mozilla/MVMContext.h"
#include "mozilla/PresShellForwards.h"
#include "nsCOMPtr.h"
#include "nsIDOMEventListener.h"
#include "nsIObserver.h"
#include "Units.h"
#include "UnitTransforms.h"
class nsViewportInfo;
namespace mozilla {
class MVMContext;
namespace dom {
class Document;
class EventTarget;
} // namespace dom
} // namespace mozilla
class MobileViewportManager final : public nsIDOMEventListener,
public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
NS_DECL_NSIOBSERVER
/* The MobileViewportManager might be required to handle meta-viewport tags
* and changes, or it might not (e.g. if we are in a desktop-zooming setup).
* This enum indicates which mode the manager is in. It might make sense to
* split these two "modes" into two separate classes but for now they have a
* bunch of shared code and it's uncertain if that shared set will expand or
* contract. */
enum class ManagerType { VisualAndMetaViewport, VisualViewportOnly };
explicit MobileViewportManager(mozilla::MVMContext* aContext,
ManagerType aType);
void Destroy();
ManagerType GetManagerType() { return mManagerType; }
/* Provide a resolution to use during the first paint instead of the default
* resolution computed from the viewport info metadata. This is in the same
* "units" as the argument to nsDOMWindowUtils::SetResolutionAndScaleTo.
* Also takes the previous display dimensions as they were at the time the
* resolution was stored in order to correctly adjust the resolution if the
* device was rotated in the meantime. */
void SetRestoreResolution(float aResolution,
mozilla::LayoutDeviceIntSize aDisplaySize);
/* Compute the "intrinsic resolution", which is the smallest resolution at
* which the layout viewport fills the visual viewport. (In typical
* scenarios, where the aspect ratios of the two viewports match, it's the
* resolution at which they are the same size.)
*
* The returned resolution is suitable for passing to
* PresShell::SetResolutionAndScaleTo(). It's not in typed units for
* reasons explained at the declaration of FrameMetrics::mPresShellResolution.
*/
float ComputeIntrinsicResolution() const;
/* The only direct calls to this should be in test code.
* Normally, it gets called by HandleEvent().
*/
void HandleDOMMetaAdded();
private:
void SetRestoreResolution(float aResolution);
public:
/* Notify the MobileViewportManager that a reflow is about to happen. This
* triggers the MVM to update its internal notion of display size and CSS
* viewport, so that code that queries those during the reflow gets an
* up-to-date value.
*/
void UpdateSizesBeforeReflow();
/* Notify the MobileViewportManager that a reflow was requested in the
* presShell.*/
void RequestReflow(bool aForceAdjustResolution);
/* Notify the MobileViewportManager that the resolution on the presShell was
* updated, and the visual viewport size needs to be updated. */
void ResolutionUpdated(mozilla::ResolutionChangeOrigin aOrigin);
/* 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
* presShell is initialized. */
void SetInitialViewport();
mozilla::LayoutDeviceIntSize DisplaySize() const {
return mozilla::ViewAs<mozilla::LayoutDevicePixel>(
GetLayoutDisplaySize(),
mozilla::PixelCastJustification::LayoutDeviceIsScreenForBounds);
};
/*
* Shrink the content to fit it to the display width if no initial-scale is
* specified and if the content is still wider than the display width.
*/
void ShrinkToDisplaySizeIfNeeded();
/*
* 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;
}
/*
* This refreshes the visual viewport size based on the most recently
* available information. It is intended to be called in particular after
* the root scrollframe does a reflow, which may make scrollbars appear or
* disappear if the content changed size.
*/
void UpdateVisualViewportSizeForPotentialScrollbarChange();
/*
* Returns the composition size in CSS units when zoomed to the intrinsic
* scale.
*/
mozilla::CSSSize GetIntrinsicCompositionSize() const;
mozilla::ParentLayerSize GetCompositionSizeWithoutDynamicToolbar() const;
void UpdateKeyboardHeight(mozilla::ScreenIntCoord aKeyboardHeight);
static mozilla::LazyLogModule gLog;
mozilla::CSSToScreenScale GetZoom() const;
/* Main helper method to update the CSS viewport and any other properties that
* need updating. */
void RefreshViewportSize(bool aForceAdjustResolution);
/*
* Returns the visible area for setting nsPresContext's visible area.
*/
nsRect InitialVisibleArea();
mozilla::ScreenIntCoord GetKeyboardHeight() const { return mKeyboardHeight; }
private:
~MobileViewportManager();
/* Secondary main helper method to update just the visual viewport size. */
void RefreshVisualViewportSize();
/* Helper to clamp the given zoom by the min/max in the viewport info. */
mozilla::CSSToScreenScale ClampZoom(
const mozilla::CSSToScreenScale& aZoom,
const nsViewportInfo& aViewportInfo) const;
/* Helper to update the given zoom according to changed display and viewport
* widths. */
mozilla::CSSToScreenScale ScaleZoomWithDisplayWidth(
const mozilla::CSSToScreenScale& aZoom,
const float& aDisplayWidthChangeRatio,
const mozilla::CSSSize& aNewViewport,
const mozilla::CSSSize& aOldViewport);
mozilla::CSSToScreenScale ResolutionToZoom(
const mozilla::LayoutDeviceToLayerScale& aResolution) const;
mozilla::LayoutDeviceToLayerScale ZoomToResolution(
const mozilla::CSSToScreenScale& aZoom) const;
/* Updates the presShell resolution and the visual viewport size for various
* types of changes. */
void UpdateResolutionForFirstPaint(const mozilla::CSSSize& aViewportSize);
void UpdateResolutionForViewportSizeChange(
const mozilla::CSSSize& aViewportSize,
const mozilla::Maybe<float>& aDisplayWidthChangeRatio);
void UpdateResolutionForContentSizeChange(
const mozilla::CSSSize& aContentSize);
void ApplyNewZoom(const mozilla::CSSToScreenScale& aNewZoom);
void UpdateVisualViewportSize(const mozilla::CSSToScreenScale& aZoom);
/* Updates the displayport margins for the presShell's root scrollable frame
*/
void UpdateDisplayPortMargins();
/* Helper function for ComputeIntrinsicResolution(). */
mozilla::CSSToScreenScale ComputeIntrinsicScale(
const nsViewportInfo& aViewportInfo,
const mozilla::ScreenIntSize& aDisplaySize,
const mozilla::CSSSize& aViewportOrContentSize) const;
/*
* Returns the screen size subtracted the scrollbar sizes from |aDisplaySize|.
*/
mozilla::ScreenIntSize GetCompositionSize(
const mozilla::ScreenIntSize& aDisplaySize) const;
/*
* Returns the display size for layout. It varies depending on the
* interactive-widget value.
*/
mozilla::ScreenIntSize GetLayoutDisplaySize() const;
/*
* Returns the display size for visual viewport events. It varies depending on
* the interactive-widget value. The size doesn't match above
* GetLayoutDisplaySize() in the case of resizes-visual.
*/
mozilla::ScreenIntSize GetDisplaySizeForVisualViewport() const;
RefPtr<mozilla::MVMContext> mContext;
ManagerType mManagerType;
bool mIsFirstPaint;
bool mPainted;
// True if this MobileViewportManager needs to update the visual viewport size
// even if the layout viewport size is unchanged.
bool mInvalidViewport;
mozilla::LayoutDeviceIntSize mDisplaySize;
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;
/*
* The software keyboard height.
*/
mozilla::ScreenIntCoord mKeyboardHeight;
mozilla::Maybe<mozilla::ScreenIntCoord> mPendingKeyboardHeight;
};
#endif
|