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/. */
5 #include "GeckoMVMContext.h"
7 #include "mozilla/DisplayPortUtils.h"
8 #include "mozilla/PresShell.h"
9 #include "mozilla/Services.h"
10 #include "mozilla/dom/Document.h"
11 #include "mozilla/dom/VisualViewport.h"
13 #include "nsGlobalWindowInner.h"
14 #include "nsIDOMEventListener.h"
16 #include "nsIObserverService.h"
17 #include "nsIScrollableFrame.h"
18 #include "nsLayoutUtils.h"
19 #include "nsPIDOMWindow.h"
20 #include "nsPresContext.h"
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();
32 void GeckoMVMContext::AddEventListener(const nsAString
& aType
,
33 nsIDOMEventListener
* aListener
,
36 mEventTarget
->AddEventListener(aType
, aListener
, aUseCapture
);
40 void GeckoMVMContext::RemoveEventListener(const nsAString
& aType
,
41 nsIDOMEventListener
* aListener
,
44 mEventTarget
->RemoveEventListener(aType
, aListener
, aUseCapture
);
48 void GeckoMVMContext::AddObserver(nsIObserver
* aObserver
, const char* aTopic
,
50 if (nsCOMPtr
<nsIObserverService
> observerService
=
51 services::GetObserverService()) {
52 observerService
->AddObserver(aObserver
, aTopic
, aOwnsWeak
);
56 void GeckoMVMContext::RemoveObserver(nsIObserver
* aObserver
,
58 if (nsCOMPtr
<nsIObserverService
> observerService
=
59 services::GetObserverService()) {
60 observerService
->RemoveObserver(aObserver
, aTopic
);
64 void GeckoMVMContext::Destroy() {
65 mEventTarget
= nullptr;
70 nsViewportInfo
GeckoMVMContext::GetViewportInfo(
71 const ScreenIntSize
& aDisplaySize
) const {
72 MOZ_ASSERT(mDocument
);
73 return mDocument
->GetViewportInfo(aDisplaySize
);
76 CSSToLayoutDeviceScale
GeckoMVMContext::CSSToDevPixelScale() const {
77 MOZ_ASSERT(mPresShell
);
78 return mPresShell
->GetPresContext()->CSSToDevPixelScale();
81 float GeckoMVMContext::GetResolution() const {
82 MOZ_ASSERT(mPresShell
);
83 return mPresShell
->GetResolution();
86 bool GeckoMVMContext::SubjectMatchesDocument(nsISupports
* aSubject
) const {
87 MOZ_ASSERT(mDocument
);
88 return SameCOMIdentity(aSubject
, ToSupports(mDocument
));
91 Maybe
<CSSRect
> GeckoMVMContext::CalculateScrollableRectForRSF() const {
92 MOZ_ASSERT(mPresShell
);
93 if (nsIScrollableFrame
* rootScrollableFrame
=
94 mPresShell
->GetRootScrollFrameAsScrollable()) {
96 CSSRect::FromAppUnits(nsLayoutUtils::CalculateScrollableRectForFrame(
97 rootScrollableFrame
, nullptr)));
102 bool GeckoMVMContext::IsResolutionUpdatedByApz() const {
103 MOZ_ASSERT(mPresShell
);
104 return mPresShell
->IsResolutionUpdatedByApz();
108 GeckoMVMContext::ScrollbarAreaToExcludeFromCompositionBounds() const {
109 MOZ_ASSERT(mPresShell
);
110 return LayoutDeviceMargin::FromAppUnits(
111 nsLayoutUtils::ScrollbarAreaToExcludeFromCompositionBoundsFor(
112 mPresShell
->GetRootScrollFrame()),
113 mPresShell
->GetPresContext()->AppUnitsPerDevPixel());
116 Maybe
<LayoutDeviceIntSize
> GeckoMVMContext::GetDocumentViewerSize() const {
117 MOZ_ASSERT(mPresShell
);
118 LayoutDeviceIntSize result
;
119 if (nsLayoutUtils::GetDocumentViewerSize(mPresShell
->GetPresContext(),
126 bool GeckoMVMContext::AllowZoomingForDocument() const {
127 MOZ_ASSERT(mDocument
);
128 return nsLayoutUtils::AllowZoomingForDocument(mDocument
);
131 bool GeckoMVMContext::IsInReaderMode() const {
132 MOZ_ASSERT(mDocument
);
134 if (NS_FAILED(mDocument
->GetDocumentURI(uri
))) {
137 static auto readerModeUriPrefix
= u
"about:reader"_ns
;
138 return StringBeginsWith(uri
, readerModeUriPrefix
);
141 bool GeckoMVMContext::IsDocumentLoading() const {
142 MOZ_ASSERT(mDocument
);
143 return mDocument
->GetReadyStateEnum() == dom::Document::READYSTATE_LOADING
;
146 void GeckoMVMContext::SetResolutionAndScaleTo(float aResolution
,
147 ResolutionChangeOrigin aOrigin
) {
148 MOZ_ASSERT(mPresShell
);
149 mPresShell
->SetResolutionAndScaleTo(aResolution
, aOrigin
);
152 void GeckoMVMContext::SetVisualViewportSize(const CSSSize
& aSize
) {
153 MOZ_ASSERT(mPresShell
);
154 mPresShell
->SetVisualViewportSize(
155 nsPresContext::CSSPixelsToAppUnits(aSize
.width
),
156 nsPresContext::CSSPixelsToAppUnits(aSize
.height
));
159 void GeckoMVMContext::PostVisualViewportResizeEventByDynamicToolbar() {
160 MOZ_ASSERT(mDocument
);
162 // We only fire visual viewport events and don't want to cause any explicit
163 // reflows here since in general we don't use the up-to-date visual viewport
165 if (auto* window
= nsGlobalWindowInner::Cast(mDocument
->GetInnerWindow())) {
166 window
->VisualViewport()->PostResizeEvent();
170 void GeckoMVMContext::UpdateDisplayPortMargins() {
171 MOZ_ASSERT(mPresShell
);
172 if (nsIFrame
* root
= mPresShell
->GetRootScrollFrame()) {
173 nsIContent
* content
= root
->GetContent();
174 bool hasDisplayPort
= DisplayPortUtils::HasNonMinimalDisplayPort(content
);
175 bool hasResolution
= mPresShell
->GetResolution() != 1.0f
;
176 if (!hasDisplayPort
&& !hasResolution
) {
177 // We only want to update the displayport if there is one already, or
178 // add one if there's a resolution on the document (see bug 1225508
182 nsRect displayportBase
= nsRect(
183 nsPoint(0, 0), nsLayoutUtils::CalculateCompositionSizeForFrame(root
));
184 // We only create MobileViewportManager for root content documents. If that
185 // ever changes we'd need to limit the size of this displayport base rect
186 // because non-toplevel documents have no limit on their size.
188 mPresShell
->GetPresContext()->IsRootContentDocumentCrossProcess());
189 DisplayPortUtils::SetDisplayPortBaseIfNotSet(content
, displayportBase
);
190 nsIScrollableFrame
* scrollable
= do_QueryFrame(root
);
191 DisplayPortUtils::CalculateAndSetDisplayPortMargins(
192 scrollable
, DisplayPortUtils::RepaintMode::Repaint
);
196 void GeckoMVMContext::Reflow(const CSSSize
& aNewSize
) {
197 RefPtr doc
= mDocument
;
198 RefPtr ps
= mPresShell
;
203 if (ps
->ResizeReflowIgnoreOverride(CSSPixel::ToAppUnits(aNewSize
.width
),
204 CSSPixel::ToAppUnits(aNewSize
.height
))) {
205 doc
->FlushPendingNotifications(FlushType::InterruptibleLayout
);
209 ScreenIntCoord
GeckoMVMContext::GetDynamicToolbarOffset() {
210 const nsPresContext
* presContext
= mPresShell
->GetPresContext();
211 return presContext
->HasDynamicToolbar()
212 ? presContext
->GetDynamicToolbarMaxHeight() -
213 presContext
->GetDynamicToolbarHeight()
217 } // namespace mozilla