diff --git a/dom/base/VisualViewport.cpp b/dom/base/VisualViewport.cpp new file mode 100644 index 0000000000..c33b1dbf5f --- /dev/null +++ b/dom/base/VisualViewport.cpp @@ -0,0 +1,144 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "VisualViewport.h" +#include "nsIScrollableFrame.h" +#include "nsIDocShell.h" + +using namespace mozilla; +using namespace mozilla::dom; + +VisualViewport::VisualViewport(nsPIDOMWindowInner* aWindow) + : DOMEventTargetHelper(aWindow) +{ +} + +VisualViewport::VisualViewport(nsIGlobalObject* aGlobal) + : DOMEventTargetHelper(aGlobal) +{ +} + +VisualViewport::~VisualViewport() +{ +} + +/* virtual */ +JSObject* +VisualViewport::WrapObject(JSContext* aCx, JS::Handle aGivenProto) +{ + return VisualViewportBinding::Wrap(aCx, this, aGivenProto); +} + +/* XXXMC: We are effectively getting the size from the root scrollframe of the content + * and the scale from our DPP resolution. + * Since we are only on desktop, by definition have full view size (no "notch" or + * other mobile "don't touch" areas), we are hard-coding: + * - VisualViewportOffset = (0,0) + * - PageLeft/PageTop = 0.0 + * - OffsetLeft/OffsetTop = 0.0 + */ + +CSSSize +VisualViewport::VisualViewportSize() const +{ + CSSSize size = CSSSize(0,0); + + nsIPresShell* presShell = GetPresShell(); + if (presShell) { + nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); + if (sf) { + size = CSSRect::FromAppUnits(sf->GetScrollPortRect().Size()); + } + } + return size; +} + +double +VisualViewport::Width() const +{ + CSSSize size = VisualViewportSize(); + return size.width; +} + +double +VisualViewport::Height() const +{ + CSSSize size = VisualViewportSize(); + return size.height; +} + +double +VisualViewport::Scale() const +{ + double scale = 1; + nsIPresShell* presShell = GetPresShell(); + if (presShell) { + scale = presShell->GetResolution(); + } + return scale; +} + +CSSPoint +VisualViewport::VisualViewportOffset() const +{ + CSSPoint offset = CSSPoint(0,0); + return offset; +} + +CSSPoint +VisualViewport::LayoutViewportOffset() const +{ + CSSPoint offset = CSSPoint(0,0); + + nsIPresShell* presShell = GetPresShell(); + if (presShell) { + nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); + if (sf) { + offset = CSSPoint::FromAppUnits(sf->GetScrollPosition()); + } + } + return offset; +} + +double +VisualViewport::PageLeft() const +{ + return 0.0; +} + +double +VisualViewport::PageTop() const +{ + return 0.0; +} + +double +VisualViewport::OffsetLeft() const +{ + return 0.0; +} + +double +VisualViewport::OffsetTop() const +{ + return 0.0; +} + +nsIPresShell* +VisualViewport::GetPresShell() const +{ + nsCOMPtr window = GetOwner(); + if (!window) { + return nullptr; + } + + nsIDocShell* docShell = window->GetDocShell(); + if (!docShell) { + return nullptr; + } + + return docShell->GetPresShell(); +} diff --git a/dom/base/VisualViewport.h b/dom/base/VisualViewport.h new file mode 100644 index 0000000000..720b368726 --- /dev/null +++ b/dom/base/VisualViewport.h @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 mozilla_dom_VisualViewport_h +#define mozilla_dom_VisualViewport_h + +#include "mozilla/DOMEventTargetHelper.h" +#include "mozilla/dom/VisualViewportBinding.h" +#include "Units.h" +#include "nsIPresShell.h" + +namespace mozilla { +namespace dom { + +/* Visual Viewport API spec: https://wicg.github.io/visual-viewport/#the-visualviewport-interface */ +class VisualViewport final: public mozilla::DOMEventTargetHelper +{ + +public: + explicit VisualViewport(nsPIDOMWindowInner* aWindow); + explicit VisualViewport(nsIGlobalObject* aGlobal); + + double OffsetLeft() const; + double OffsetTop() const; + double PageLeft() const; + double PageTop() const; + double Width() const; + double Height() const; + double Scale() const; + + virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; + +private: + virtual ~VisualViewport(); + + CSSSize VisualViewportSize() const; + CSSPoint VisualViewportOffset() const; + CSSPoint LayoutViewportOffset() const; + nsIPresShell* GetPresShell() const; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_VisualViewport_h diff --git a/dom/base/moz.build b/dom/base/moz.build index 04f66ba0f8..f3676239b2 100755 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -217,6 +217,7 @@ EXPORTS.mozilla.dom += [ 'Timeout.h', 'TimeoutHandler.h', 'TreeWalker.h', + 'VisualViewport.h', 'WebKitCSSMatrix.h', 'WebSocket.h', 'WindowOrientationObserver.h', @@ -365,6 +366,7 @@ UNIFIED_SOURCES += [ 'TimeoutHandler.cpp', 'TimerClamping.cpp', 'TreeWalker.cpp', + 'VisualViewport.cpp', 'WebKitCSSMatrix.cpp', 'WebSocket.cpp', 'WindowNamedPropertiesHandler.cpp', diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 30554486e5..c528fee14a 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -23,6 +23,7 @@ #include "mozilla/dom/StorageEventBinding.h" #include "mozilla/dom/Timeout.h" #include "mozilla/dom/TimeoutHandler.h" +#include "mozilla/dom/VisualViewport.h" #include "mozilla/IntegerPrintfMacros.h" #include "nsDOMOfflineResourceList.h" #include "nsError.h" @@ -4156,6 +4157,16 @@ nsGlobalWindow::GetNavigator() return navigator; } +VisualViewport* +nsGlobalWindow::VisualViewport() +{ + if (!mVisualViewport) { + mVisualViewport = new mozilla::dom::VisualViewport(this); + } + + return mVisualViewport; +} + nsScreen* nsGlobalWindow::GetScreen(ErrorResult& aError) { diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 564dcee500..ba4b521c50 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -134,6 +134,7 @@ class SpeechSynthesis; class TabGroup; class Timeout; class U2F; +class VisualViewport; class WakeLock; struct WindowPostMessageOptions; class Worklet; @@ -974,6 +975,7 @@ public: already_AddRefed GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt, mozilla::ErrorResult& aError) override; + mozilla::dom::VisualViewport* VisualViewport(); already_AddRefed MatchMediaOuter(const nsAString& aQuery); already_AddRefed MatchMedia(const nsAString& aQuery, mozilla::ErrorResult& aError); @@ -1854,6 +1856,8 @@ protected: RefPtr mHistory; RefPtr mCustomElements; + RefPtr mVisualViewport; + // These member variables are used on both inner and the outer windows. nsCOMPtr mDocumentPrincipal; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index f3bfc1db9e..5312cc0261 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1162,6 +1162,10 @@ DOMInterfaces = { 'wrapperCache': False, }, +'VisualViewport': { + 'nativeType': 'mozilla::dom::VisualViewport', +}, + 'VTTCue': { 'nativeType': 'mozilla::dom::TextTrackCue' }, diff --git a/dom/webidl/VisualViewport.webidl b/dom/webidl/VisualViewport.webidl new file mode 100644 index 0000000000..25c25cd189 --- /dev/null +++ b/dom/webidl/VisualViewport.webidl @@ -0,0 +1,21 @@ +/* -*- Mode: IDL; 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/. + * + * The origin of this IDL file is: + * https://wicg.github.io/visual-viewport/#the-visualviewport-interface + */ + +interface VisualViewport : EventTarget { + readonly attribute double offsetLeft; + readonly attribute double offsetTop; + + readonly attribute double pageLeft; + readonly attribute double pageTop; + + readonly attribute double width; + readonly attribute double height; + + readonly attribute double scale; +}; diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl index 2ba9f4f124..1d8f4b92eb 100644 --- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -15,6 +15,7 @@ * http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html * https://w3c.github.io/webappsec-secure-contexts/#monkey-patching-global-object * https://w3c.github.io/requestidlecallback/ + * https://wicg.github.io/visual-viewport/#the-visualviewport-interface */ interface ApplicationCache; @@ -492,3 +493,8 @@ partial interface Window { dictionary WindowPostMessageOptions : StructuredSerializeOptions { USVString targetOrigin = "/"; }; + +partial interface Window { + [SameObject, Pref="dom.visualviewport.enabled", Replaceable] + readonly attribute VisualViewport visualViewport; +}; diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 560e1600aa..ee8b779ae8 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -557,6 +557,7 @@ WEBIDL_FILES = [ 'VideoStreamTrack.webidl', 'VideoTrack.webidl', 'VideoTrackList.webidl', + 'VisualViewport.webidl', 'VTTCue.webidl', 'VTTRegion.webidl', 'WaveShaperNode.webidl', diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index e24e7eb037..d403854661 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -317,6 +317,7 @@ private: DECL_GFX_PREF(Live, "dom.ipc.plugins.asyncdrawing.enabled", PluginAsyncDrawingEnabled, bool, false); DECL_GFX_PREF(Live, "dom.meta-viewport.enabled", MetaViewportEnabled, bool, false); + DECL_GFX_PREF(Live, "dom.visualviewport.enabled", VisualViewportEnabled, bool, false); DECL_GFX_PREF(Once, "dom.vr.enabled", VREnabled, bool, false); DECL_GFX_PREF(Once, "dom.vr.oculus.enabled", VROculusEnabled, bool, true); DECL_GFX_PREF(Once, "dom.vr.openvr.enabled", VROpenVREnabled, bool, false); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index cbffe84c23..5f270a7a8e 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5045,6 +5045,9 @@ pref("intl.allow-insecure-text-input", false); // Enable meta-viewport support in remote APZ-enabled frames. pref("dom.meta-viewport.enabled", false); +// Disable the Visual Viewport API +pref("dom.visualviewport.enabled", false); + // Disable support. See m-c bug 1457503 / UXP #1102. pref("dom.meta-set-cookie.enabled", false);