layout/base/GeckoMVMContext.cpp
author Daniel Holbert <dholbert@cs.stanford.edu>
Wed, 23 Oct 2019 22:10:11 +0000
changeset 498897 db3fe5184abb0201fe0b7a6384cde1e6e52bbaca
parent 496464 7214f827b7fb017fd9ee1a81b9e54f2d97e5f8c1
child 503204 086f87f26b1fd6049e616399eb7e519b7b775671
permissions -rw-r--r--
Bug 1590639 part 2: Fix non-unified build issues in layout/base. r=TYLin Changes here: - Adding a "dom::" prefix in GeckoMVMContext.cpp (could've also added a "using" decl, but I'm just adding a one-off prefix to match "dom::Document" usage elsewhere in this file). - Giving nsLayoutUtils an include for ViewportFrame.h since it uses that type. - Giving nsPresArena.cpp an include for nsDisplayList.h to provide the DisplayListArenaObjectId enum type. Depends on D50163 Differential Revision: https://phabricator.services.mozilla.com/D50164

/* 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/. */

#include "GeckoMVMContext.h"

#include "mozilla/PresShell.h"
#include "mozilla/Services.h"
#include "mozilla/dom/Document.h"
#include "nsCOMPtr.h"
#include "nsIDOMEventListener.h"
#include "nsIFrame.h"
#include "nsIObserverService.h"
#include "nsLayoutUtils.h"
#include "nsPIDOMWindow.h"
#include "nsPresContext.h"

namespace mozilla {

GeckoMVMContext::GeckoMVMContext(dom::Document* aDocument,
                                 PresShell* aPresShell)
    : mDocument(aDocument), mPresShell(aPresShell) {
  if (nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow()) {
    mEventTarget = window->GetChromeEventHandler();
  }
}

void GeckoMVMContext::AddEventListener(const nsAString& aType,
                                       nsIDOMEventListener* aListener,
                                       bool aUseCapture) {
  if (mEventTarget) {
    mEventTarget->AddEventListener(aType, aListener, aUseCapture);
  }
}

void GeckoMVMContext::RemoveEventListener(const nsAString& aType,
                                          nsIDOMEventListener* aListener,
                                          bool aUseCapture) {
  if (mEventTarget) {
    mEventTarget->RemoveEventListener(aType, aListener, aUseCapture);
  }
}

void GeckoMVMContext::AddObserver(nsIObserver* aObserver, const char* aTopic,
                                  bool aOwnsWeak) {
  if (nsCOMPtr<nsIObserverService> observerService =
          services::GetObserverService()) {
    observerService->AddObserver(aObserver, aTopic, aOwnsWeak);
  }
}

void GeckoMVMContext::RemoveObserver(nsIObserver* aObserver,
                                     const char* aTopic) {
  if (nsCOMPtr<nsIObserverService> observerService =
          services::GetObserverService()) {
    observerService->RemoveObserver(aObserver, aTopic);
  }
}

void GeckoMVMContext::Destroy() {
  mEventTarget = nullptr;
  mDocument = nullptr;
  mPresShell = nullptr;
}

nsViewportInfo GeckoMVMContext::GetViewportInfo(
    const ScreenIntSize& aDisplaySize) const {
  MOZ_ASSERT(mDocument);
  return mDocument->GetViewportInfo(aDisplaySize);
}

CSSToLayoutDeviceScale GeckoMVMContext::CSSToDevPixelScale() const {
  MOZ_ASSERT(mPresShell);
  return mPresShell->GetPresContext()->CSSToDevPixelScale();
}

float GeckoMVMContext::GetResolution() const {
  MOZ_ASSERT(mPresShell);
  return mPresShell->GetResolution();
}

bool GeckoMVMContext::SubjectMatchesDocument(nsISupports* aSubject) const {
  MOZ_ASSERT(mDocument);
  return SameCOMIdentity(aSubject, ToSupports(mDocument));
}

Maybe<CSSRect> GeckoMVMContext::CalculateScrollableRectForRSF() const {
  MOZ_ASSERT(mPresShell);
  if (nsIScrollableFrame* rootScrollableFrame =
          mPresShell->GetRootScrollFrameAsScrollable()) {
    return Some(
        CSSRect::FromAppUnits(nsLayoutUtils::CalculateScrollableRectForFrame(
            rootScrollableFrame, nullptr)));
  }
  return Nothing();
}

bool GeckoMVMContext::IsResolutionUpdatedByApz() const {
  MOZ_ASSERT(mPresShell);
  return mPresShell->IsResolutionUpdatedByApz();
}

LayoutDeviceMargin
GeckoMVMContext::ScrollbarAreaToExcludeFromCompositionBounds() const {
  MOZ_ASSERT(mPresShell);
  return LayoutDeviceMargin::FromAppUnits(
      nsLayoutUtils::ScrollbarAreaToExcludeFromCompositionBoundsFor(
          mPresShell->GetRootScrollFrame()),
      mPresShell->GetPresContext()->AppUnitsPerDevPixel());
}

Maybe<LayoutDeviceIntSize> GeckoMVMContext::GetContentViewerSize() const {
  MOZ_ASSERT(mPresShell);
  LayoutDeviceIntSize result;
  if (nsLayoutUtils::GetContentViewerSize(mPresShell->GetPresContext(),
                                          result)) {
    return Some(result);
  }
  return Nothing();
}

bool GeckoMVMContext::AllowZoomingForDocument() const {
  MOZ_ASSERT(mDocument);
  return nsLayoutUtils::AllowZoomingForDocument(mDocument);
}

bool GeckoMVMContext::IsInReaderMode() const {
  MOZ_ASSERT(mDocument);
  nsString uri;
  if (NS_FAILED(mDocument->GetDocumentURI(uri))) {
    return false;
  }
  static auto readerModeUriPrefix = NS_LITERAL_STRING("about:reader");
  return StringBeginsWith(uri, readerModeUriPrefix);
}

bool GeckoMVMContext::IsDocumentLoading() const {
  MOZ_ASSERT(mDocument);
  return mDocument->GetReadyStateEnum() == dom::Document::READYSTATE_LOADING;
}

void GeckoMVMContext::SetResolutionAndScaleTo(float aResolution,
                                              ResolutionChangeOrigin aOrigin) {
  MOZ_ASSERT(mPresShell);
  mPresShell->SetResolutionAndScaleTo(aResolution, aOrigin);
}

void GeckoMVMContext::SetVisualViewportSize(const CSSSize& aSize) {
  MOZ_ASSERT(mPresShell);
  nsLayoutUtils::SetVisualViewportSize(mPresShell, aSize);
}

void GeckoMVMContext::UpdateDisplayPortMargins() {
  MOZ_ASSERT(mPresShell);
  if (nsIFrame* root = mPresShell->GetRootScrollFrame()) {
    bool hasDisplayPort = nsLayoutUtils::HasDisplayPort(root->GetContent());
    bool hasResolution = mPresShell->GetResolution() != 1.0f;
    if (!hasDisplayPort && !hasResolution) {
      // We only want to update the displayport if there is one already, or
      // add one if there's a resolution on the document (see bug 1225508
      // comment 1).
      return;
    }
    nsRect displayportBase = nsRect(
        nsPoint(0, 0), nsLayoutUtils::CalculateCompositionSizeForFrame(root));
    // We only create MobileViewportManager for root content documents. If that
    // ever changes we'd need to limit the size of this displayport base rect
    // because non-toplevel documents have no limit on their size.
    MOZ_ASSERT(
        mPresShell->GetPresContext()->IsRootContentDocumentCrossProcess());
    nsLayoutUtils::SetDisplayPortBaseIfNotSet(root->GetContent(),
                                              displayportBase);
    nsIScrollableFrame* scrollable = do_QueryFrame(root);
    nsLayoutUtils::CalculateAndSetDisplayPortMargins(
        scrollable, nsLayoutUtils::RepaintMode::Repaint);
  }
}

void GeckoMVMContext::Reflow(const CSSSize& aNewSize) {
  MOZ_ASSERT(mPresShell);

  RefPtr<PresShell> presShell = mPresShell;
  presShell->ResizeReflowIgnoreOverride(CSSPixel::ToAppUnits(aNewSize.width),
                                        CSSPixel::ToAppUnits(aNewSize.height),
                                        ResizeReflowOptions::NoOption);
}

}  // namespace mozilla