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 "mozilla/Maybe.h"
11 #include "nsCOMPtr.h"
12 #include "nsIDOMEventListener.h"
13 #include "nsIObserver.h"
14 #include "Units.h"
15 
16 class nsIDOMEventTarget;
17 class nsIDocument;
18 class nsIPresShell;
19 class nsViewportInfo;
20 
21 class MobileViewportManager final : public nsIDOMEventListener,
22                                     public nsIObserver {
23  public:
24   NS_DECL_ISUPPORTS
25   NS_DECL_NSIDOMEVENTLISTENER
26   NS_DECL_NSIOBSERVER
27 
28   MobileViewportManager(nsIPresShell* aPresShell, nsIDocument* aDocument);
29   void Destroy();
30 
31   /* Provide a resolution to use during the first paint instead of the default
32    * resolution computed from the viewport info metadata. This is in the same
33    * "units" as the argument to nsDOMWindowUtils::SetResolutionAndScaleTo.
34    * Also takes the previous display dimensions as they were at the time the
35    * resolution was stored in order to correctly adjust the resolution if the
36    * device was rotated in the meantime. */
37   void SetRestoreResolution(float aResolution,
38                             mozilla::LayoutDeviceIntSize aDisplaySize);
39 
40  private:
41   void SetRestoreResolution(float aResolution);
42 
43  public:
44   /* Notify the MobileViewportManager that a reflow was requested in the
45    * presShell.*/
46   void RequestReflow();
47 
48   /* Notify the MobileViewportManager that the resolution on the presShell was
49    * updated, and the SPCSPS needs to be updated. */
50   void ResolutionUpdated();
51 
52  private:
53   ~MobileViewportManager();
54 
55   /* Called to compute the initial viewport on page load or before-first-paint,
56    * whichever happens first. */
57   void SetInitialViewport();
58 
59   /* Main helper method to update the CSS viewport and any other properties that
60    * need updating. */
61   void RefreshViewportSize(bool aForceAdjustResolution);
62 
63   /* Secondary main helper method to update just the SPCSPS. */
64   void RefreshSPCSPS();
65 
66   /* Helper to clamp the given zoom by the min/max in the viewport info. */
67   mozilla::CSSToScreenScale ClampZoom(const mozilla::CSSToScreenScale& aZoom,
68                                       const nsViewportInfo& aViewportInfo);
69 
70   /* Helper to update the given resolution according to changed display and
71    * viewport widths. */
72   mozilla::LayoutDeviceToLayerScale ScaleResolutionWithDisplayWidth(
73       const mozilla::LayoutDeviceToLayerScale& aRes,
74       const float& aDisplayWidthChangeRatio,
75       const mozilla::CSSSize& aNewViewport,
76       const mozilla::CSSSize& aOldViewport);
77 
78   /* Updates the presShell resolution and returns the new zoom. */
79   mozilla::CSSToScreenScale UpdateResolution(
80       const nsViewportInfo& aViewportInfo,
81       const mozilla::ScreenIntSize& aDisplaySize,
82       const mozilla::CSSSize& aViewport,
83       const mozilla::Maybe<float>& aDisplayWidthChangeRatio);
84 
85   /* Updates the scroll-position-clamping scrollport size */
86   void UpdateSPCSPS(const mozilla::ScreenIntSize& aDisplaySize,
87                     const mozilla::CSSToScreenScale& aZoom);
88 
89   /* Updates the displayport margins for the presShell's root scrollable frame
90    */
91   void UpdateDisplayPortMargins();
92 
93   nsCOMPtr<nsIDocument> mDocument;
94   nsIPresShell* MOZ_NON_OWNING_REF
95       mPresShell;  // raw ref since the presShell owns this
96   nsCOMPtr<nsIDOMEventTarget> mEventTarget;
97   bool mIsFirstPaint;
98   bool mPainted;
99   mozilla::LayoutDeviceIntSize mDisplaySize;
100   mozilla::CSSSize mMobileViewportSize;
101   mozilla::Maybe<float> mRestoreResolution;
102   mozilla::Maybe<mozilla::ScreenIntSize> mRestoreDisplaySize;
103 };
104 
105 #endif
106