gecko-dev/layout/base/MobileViewportManager.h

99 строки
3.8 KiB
C
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/Maybe.h"
#include "nsIDOMEventListener.h"
#include "nsIObserver.h"
#include "Units.h"
class nsIDOMEventTarget;
class nsIDocument;
class nsIPresShell;
class nsViewportInfo;
class MobileViewportManager final : public nsIDOMEventListener
, public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
NS_DECL_NSIOBSERVER
MobileViewportManager(nsIPresShell* aPresShell,
nsIDocument* aDocument);
void Destroy();
/* 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
Bug 1282902 - Part 3 - Let the MobileViewportManager recalculate the saved resolution if the display width changed before restoring. r=kats The mobile session store saves the current document resolution in order to restore the previous zoom level when restoring a page. If the display width has changed since the session data was captured (e.g. because the device was rotated), the resolution might have to be scaled appropriately. Currently, the session store does this scaling by itself by comparing the stored and current window widths, however this implementation is slightly simplified and doesn't cover all use cases, which means some pages can be restored at a wrong zoom level after rotation. To correctly cover all cases, the session store would have to compare viewport widths, too. Because the MobileViewportManager doesn't wait for the session store to set the restore resolution, the latter has to call setRestoreResolution() as early as possible in order to guarantee that the restore resolution is set before the first paint of the document. Therefore the session store currently calls this after receiving a LocationChange notification. However at that time, the correct viewport for the current document is not yet available, which means the resolution cannot be recalculated by the session store at that point. Therefore, this patch changes the approach taken and lets the MVM handle all resolution calculations instead. The session store now simply passes the stored previous display dimensions along with the previous document resolution to the MVM, which can then compare them to the current display and viewport widths and scale the resolution appropriately before using it during first paint. MozReview-Commit-ID: IGxWw87yftK --HG-- extra : transplant_source : e%8D%BD%26%D2%C3%8E5%E3%2B%C0t%BA%DB%C1%BBs%3F%13%1F
2016-07-01 22:23:25 +03:00
* "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);
/* Notify the MobileViewportManager that a reflow was requested in the
* presShell.*/
void RequestReflow();
/* Notify the MobileViewportManager that the resolution on the presShell was
* updated, and the SPCSPS needs to be updated. */
void ResolutionUpdated();
private:
~MobileViewportManager();
/* Called to compute the initial viewport on page load or before-first-paint,
* whichever happens first. */
void SetInitialViewport();
/* Main helper method to update the CSS viewport and any other properties that
* need updating. */
void RefreshViewportSize(bool aForceAdjustResolution);
/* Secondary main helper method to update just the SPCSPS. */
void RefreshSPCSPS();
/* Helper to clamp the given zoom by the min/max in the viewport info. */
mozilla::CSSToScreenScale ClampZoom(const mozilla::CSSToScreenScale& aZoom,
const nsViewportInfo& aViewportInfo);
/* Helper to update the given resolution according to changed display and viewport widths. */
mozilla::LayoutDeviceToLayerScale
ScaleResolutionWithDisplayWidth(const mozilla::LayoutDeviceToLayerScale& aRes,
const float& aDisplayWidthChangeRatio,
const mozilla::CSSSize& aNewViewport,
const mozilla::CSSSize& aOldViewport);
/* Updates the presShell resolution and returns the new zoom. */
mozilla::CSSToScreenScale UpdateResolution(const nsViewportInfo& aViewportInfo,
const mozilla::ScreenIntSize& aDisplaySize,
const mozilla::CSSSize& aViewport,
const mozilla::Maybe<float>& aDisplayWidthChangeRatio);
/* Updates the scroll-position-clamping scrollport size */
void UpdateSPCSPS(const mozilla::ScreenIntSize& aDisplaySize,
const mozilla::CSSToScreenScale& aZoom);
/* Updates the displayport margins for the presShell's root scrollable frame */
void UpdateDisplayPortMargins();
nsCOMPtr<nsIDocument> mDocument;
nsIPresShell* MOZ_NON_OWNING_REF mPresShell; // raw ref since the presShell owns this
nsCOMPtr<nsIDOMEventTarget> mEventTarget;
bool mIsFirstPaint;
bool mPainted;
mozilla::LayoutDeviceIntSize mDisplaySize;
mozilla::CSSSize mMobileViewportSize;
mozilla::Maybe<float> mRestoreResolution;
Bug 1282902 - Part 3 - Let the MobileViewportManager recalculate the saved resolution if the display width changed before restoring. r=kats The mobile session store saves the current document resolution in order to restore the previous zoom level when restoring a page. If the display width has changed since the session data was captured (e.g. because the device was rotated), the resolution might have to be scaled appropriately. Currently, the session store does this scaling by itself by comparing the stored and current window widths, however this implementation is slightly simplified and doesn't cover all use cases, which means some pages can be restored at a wrong zoom level after rotation. To correctly cover all cases, the session store would have to compare viewport widths, too. Because the MobileViewportManager doesn't wait for the session store to set the restore resolution, the latter has to call setRestoreResolution() as early as possible in order to guarantee that the restore resolution is set before the first paint of the document. Therefore the session store currently calls this after receiving a LocationChange notification. However at that time, the correct viewport for the current document is not yet available, which means the resolution cannot be recalculated by the session store at that point. Therefore, this patch changes the approach taken and lets the MVM handle all resolution calculations instead. The session store now simply passes the stored previous display dimensions along with the previous document resolution to the MVM, which can then compare them to the current display and viewport widths and scale the resolution appropriately before using it during first paint. MozReview-Commit-ID: IGxWw87yftK --HG-- extra : transplant_source : e%8D%BD%26%D2%C3%8E5%E3%2B%C0t%BA%DB%C1%BBs%3F%13%1F
2016-07-01 22:23:25 +03:00
mozilla::Maybe<mozilla::ScreenIntSize> mRestoreDisplaySize;
};
#endif