tor-browser

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

GeckoMVMContext.cpp (7601B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "GeckoMVMContext.h"
      6 
      7 #include "mozilla/DisplayPortUtils.h"
      8 #include "mozilla/PresShell.h"
      9 #include "mozilla/ScrollContainerFrame.h"
     10 #include "mozilla/Services.h"
     11 #include "mozilla/dom/Document.h"
     12 #include "mozilla/dom/VisualViewport.h"
     13 #include "nsCOMPtr.h"
     14 #include "nsGlobalWindowInner.h"
     15 #include "nsIDOMEventListener.h"
     16 #include "nsIFrame.h"
     17 #include "nsIObserverService.h"
     18 #include "nsLayoutUtils.h"
     19 #include "nsPIDOMWindow.h"
     20 #include "nsPresContext.h"
     21 
     22 namespace mozilla {
     23 
     24 GeckoMVMContext::GeckoMVMContext(dom::Document* aDocument,
     25                                 PresShell* aPresShell)
     26    : mDocument(aDocument), mPresShell(aPresShell) {
     27  if (nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow()) {
     28    mEventTarget = window->GetChromeEventHandler();
     29  }
     30 }
     31 
     32 void GeckoMVMContext::AddEventListener(const nsAString& aType,
     33                                       nsIDOMEventListener* aListener,
     34                                       bool aUseCapture) {
     35  if (mEventTarget) {
     36    mEventTarget->AddEventListener(aType, aListener, aUseCapture);
     37  }
     38 }
     39 
     40 void GeckoMVMContext::RemoveEventListener(const nsAString& aType,
     41                                          nsIDOMEventListener* aListener,
     42                                          bool aUseCapture) {
     43  if (mEventTarget) {
     44    mEventTarget->RemoveEventListener(aType, aListener, aUseCapture);
     45  }
     46 }
     47 
     48 void GeckoMVMContext::AddObserver(nsIObserver* aObserver, const char* aTopic,
     49                                  bool aOwnsWeak) {
     50  if (nsCOMPtr<nsIObserverService> observerService =
     51          services::GetObserverService()) {
     52    observerService->AddObserver(aObserver, aTopic, aOwnsWeak);
     53  }
     54 }
     55 
     56 void GeckoMVMContext::RemoveObserver(nsIObserver* aObserver,
     57                                     const char* aTopic) {
     58  if (nsCOMPtr<nsIObserverService> observerService =
     59          services::GetObserverService()) {
     60    observerService->RemoveObserver(aObserver, aTopic);
     61  }
     62 }
     63 
     64 void GeckoMVMContext::Destroy() {
     65  mEventTarget = nullptr;
     66  mDocument = nullptr;
     67  mPresShell = nullptr;
     68 }
     69 
     70 nsViewportInfo GeckoMVMContext::GetViewportInfo(
     71    const ScreenIntSize& aDisplaySize) const {
     72  MOZ_ASSERT(mDocument);
     73  return mDocument->GetViewportInfo(aDisplaySize);
     74 }
     75 
     76 CSSToLayoutDeviceScale GeckoMVMContext::CSSToDevPixelScale() const {
     77  MOZ_ASSERT(mPresShell);
     78  return mPresShell->GetPresContext()->CSSToDevPixelScale();
     79 }
     80 
     81 float GeckoMVMContext::GetResolution() const {
     82  MOZ_ASSERT(mPresShell);
     83  return mPresShell->GetResolution();
     84 }
     85 
     86 bool GeckoMVMContext::SubjectMatchesDocument(nsISupports* aSubject) const {
     87  MOZ_ASSERT(mDocument);
     88  return SameCOMIdentity(aSubject, ToSupports(mDocument));
     89 }
     90 
     91 Maybe<CSSRect> GeckoMVMContext::CalculateScrollableRectForRSF() const {
     92  MOZ_ASSERT(mPresShell);
     93  if (ScrollContainerFrame* rootScrollContainerFrame =
     94          mPresShell->GetRootScrollContainerFrame()) {
     95    return Some(
     96        CSSRect::FromAppUnits(nsLayoutUtils::CalculateScrollableRectForFrame(
     97            rootScrollContainerFrame, nullptr)));
     98  }
     99  return Nothing();
    100 }
    101 
    102 bool GeckoMVMContext::IsResolutionUpdatedByApz() const {
    103  MOZ_ASSERT(mPresShell);
    104  return mPresShell->IsResolutionUpdatedByApz();
    105 }
    106 
    107 LayoutDeviceMargin
    108 GeckoMVMContext::ScrollbarAreaToExcludeFromCompositionBounds() const {
    109  MOZ_ASSERT(mPresShell);
    110  return LayoutDeviceMargin::FromAppUnits(
    111      nsLayoutUtils::ScrollbarAreaToExcludeFromCompositionBoundsFor(
    112          mPresShell->GetRootScrollContainerFrame()),
    113      mPresShell->GetPresContext()->AppUnitsPerDevPixel());
    114 }
    115 
    116 Maybe<LayoutDeviceIntSize> GeckoMVMContext::GetDocumentViewerSize() const {
    117  MOZ_ASSERT(mPresShell);
    118  LayoutDeviceIntSize result;
    119  if (nsLayoutUtils::GetDocumentViewerSize(mPresShell->GetPresContext(),
    120                                           result)) {
    121    return Some(result);
    122  }
    123  return Nothing();
    124 }
    125 
    126 bool GeckoMVMContext::AllowZoomingForDocument() const {
    127  MOZ_ASSERT(mDocument);
    128  return nsLayoutUtils::AllowZoomingForDocument(mDocument);
    129 }
    130 
    131 bool GeckoMVMContext::IsInReaderMode() const {
    132  MOZ_ASSERT(mDocument);
    133  nsString uri;
    134  if (NS_FAILED(mDocument->GetDocumentURI(uri))) {
    135    return false;
    136  }
    137  static auto readerModeUriPrefix = u"about:reader"_ns;
    138  return StringBeginsWith(uri, readerModeUriPrefix);
    139 }
    140 
    141 bool GeckoMVMContext::IsDocumentLoading() const {
    142  MOZ_ASSERT(mDocument);
    143  return mDocument->GetReadyStateEnum() == dom::Document::READYSTATE_LOADING;
    144 }
    145 
    146 bool GeckoMVMContext::IsDocumentFullscreen() const {
    147  MOZ_ASSERT(mDocument);
    148  return mDocument->Fullscreen();
    149 }
    150 
    151 void GeckoMVMContext::SetResolutionAndScaleTo(float aResolution,
    152                                              ResolutionChangeOrigin aOrigin) {
    153  MOZ_ASSERT(mPresShell);
    154  mPresShell->SetResolutionAndScaleTo(aResolution, aOrigin);
    155 }
    156 
    157 void GeckoMVMContext::SetVisualViewportSize(const CSSSize& aSize) {
    158  MOZ_ASSERT(mPresShell);
    159  mPresShell->SetVisualViewportSize(
    160      nsPresContext::CSSPixelsToAppUnits(aSize.width),
    161      nsPresContext::CSSPixelsToAppUnits(aSize.height));
    162 }
    163 
    164 void GeckoMVMContext::PostVisualViewportResizeEventByDynamicToolbar() {
    165  MOZ_ASSERT(mDocument);
    166 
    167  // We only fire visual viewport events and don't want to cause any explicit
    168  // reflows here since in general we don't use the up-to-date visual viewport
    169  // size for layout.
    170  if (auto* window = nsGlobalWindowInner::Cast(mDocument->GetInnerWindow())) {
    171    window->VisualViewport()->PostResizeEvent();
    172  }
    173 }
    174 
    175 void GeckoMVMContext::UpdateDisplayPortMargins() {
    176  MOZ_ASSERT(mPresShell);
    177  if (ScrollContainerFrame* root = mPresShell->GetRootScrollContainerFrame()) {
    178    nsIContent* content = root->GetContent();
    179    bool hasDisplayPort = DisplayPortUtils::HasNonMinimalDisplayPort(content);
    180    bool hasResolution = mPresShell->GetResolution() != 1.0f;
    181    if (!hasDisplayPort && !hasResolution) {
    182      // We only want to update the displayport if there is one already, or
    183      // add one if there's a resolution on the document (see bug 1225508
    184      // comment 1).
    185      return;
    186    }
    187    nsRect displayportBase = nsRect(
    188        nsPoint(0, 0), nsLayoutUtils::CalculateCompositionSizeForFrame(root));
    189    // We only create MobileViewportManager for root content documents. If that
    190    // ever changes we'd need to limit the size of this displayport base rect
    191    // because non-toplevel documents have no limit on their size.
    192    MOZ_ASSERT(
    193        mPresShell->GetPresContext()->IsRootContentDocumentCrossProcess());
    194    DisplayPortUtils::SetDisplayPortBaseIfNotSet(content, displayportBase);
    195    DisplayPortUtils::CalculateAndSetDisplayPortMargins(
    196        root, DisplayPortUtils::RepaintMode::Repaint);
    197  }
    198 }
    199 
    200 void GeckoMVMContext::Reflow(const CSSSize& aNewSize) {
    201  RefPtr doc = mDocument;
    202  RefPtr ps = mPresShell;
    203 
    204  MOZ_ASSERT(doc);
    205  MOZ_ASSERT(ps);
    206 
    207  if (ps->ResizeReflowIgnoreOverride(CSSPixel::ToAppUnits(aNewSize))) {
    208    doc->FlushPendingNotifications(FlushType::InterruptibleLayout);
    209  }
    210 }
    211 
    212 ScreenIntCoord GeckoMVMContext::GetDynamicToolbarOffset() {
    213  const nsPresContext* presContext = mPresShell->GetPresContext();
    214  return presContext->HasDynamicToolbar()
    215             ? presContext->GetDynamicToolbarMaxHeight() -
    216                   presContext->GetDynamicToolbarHeight()
    217             : ScreenIntCoord(0);
    218 }
    219 
    220 dom::InteractiveWidget GeckoMVMContext::GetInteractiveWidgetMode() const {
    221  return mDocument->InteractiveWidget();
    222 }
    223 }  // namespace mozilla