tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MobileViewportManager.h (9389B)


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