Bug 1284785 part 1 - Make ShouldLockPointer have internal linkage rather than being a method of nsDocument. r?smaug
MozReview-Commit-ID: 9dYVmUnTEgR
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -12310,16 +12310,75 @@ public:
NS_IMETHOD Run() final;
private:
nsWeakPtr mElement;
nsWeakPtr mDocument;
bool mUserInputOrChromeCaller;
};
+static bool
+ShouldLockPointer(Element* aElement, Element* aCurrentLock,
+ bool aNoFocusCheck = false)
+{
+ // Check if pointer lock pref is enabled
+ if (!Preferences::GetBool("full-screen-api.pointer-lock.enabled")) {
+ NS_WARNING("ShouldLockPointer(): Pointer Lock pref not enabled");
+ return false;
+ }
+
+ nsCOMPtr<nsIDocument> ownerDoc = aElement->OwnerDoc();
+ if (aCurrentLock && aCurrentLock->OwnerDoc() != ownerDoc) {
+ NS_WARNING("ShouldLockPointer(): Existing pointer lock element in a different document");
+ return false;
+ }
+
+ if (!aElement->IsInUncomposedDoc()) {
+ NS_WARNING("ShouldLockPointer(): Element without Document");
+ return false;
+ }
+
+ if (ownerDoc->GetSandboxFlags() & SANDBOXED_POINTER_LOCK) {
+ NS_WARNING("ShouldLockPointer(): Document is sandboxed and doesn't allow pointer-lock");
+ return false;
+ }
+
+ // Check if the element is in a document with a docshell.
+ if (!ownerDoc->GetContainer()) {
+ return false;
+ }
+ nsCOMPtr<nsPIDOMWindowOuter> ownerWindow = ownerDoc->GetWindow();
+ if (!ownerWindow) {
+ return false;
+ }
+ nsCOMPtr<nsPIDOMWindowInner> ownerInnerWindow = ownerDoc->GetInnerWindow();
+ if (!ownerInnerWindow) {
+ return false;
+ }
+ if (ownerWindow->GetCurrentInnerWindow() != ownerInnerWindow) {
+ return false;
+ }
+
+ nsCOMPtr<nsPIDOMWindowOuter> top = ownerWindow->GetScriptableTop();
+ if (!top || !top->GetExtantDoc() || top->GetExtantDoc()->Hidden()) {
+ NS_WARNING("ShouldLockPointer(): Top document isn't visible.");
+ return false;
+ }
+
+ if (!aNoFocusCheck) {
+ mozilla::ErrorResult rv;
+ if (!top->GetExtantDoc()->HasFocus(rv)) {
+ NS_WARNING("ShouldLockPointer(): Top document isn't focused.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
NS_IMETHODIMP
PointerLockRequest::Run()
{
nsCOMPtr<Element> e = do_QueryReferent(mElement);
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
nsDocument* d = static_cast<nsDocument*>(doc.get());
if (!e || !d || e->GetUncomposedDoc() != d) {
DispatchPointerLockError(d);
@@ -12329,17 +12388,17 @@ PointerLockRequest::Run()
nsCOMPtr<Element> pointerLockedElement =
do_QueryReferent(EventStateManager::sPointerLockedElement);
if (e == pointerLockedElement) {
DispatchPointerLockChange(d);
return NS_OK;
}
// Note, we must bypass focus change, so pass true as the last parameter!
- if (!d->ShouldLockPointer(e, pointerLockedElement, true)) {
+ if (!ShouldLockPointer(e, pointerLockedElement, true)) {
DispatchPointerLockError(d);
return NS_OK;
}
// If it is neither user input initiated, nor requested in fullscreen,
// it should be rejected.
if (!mUserInputOrChromeCaller && !doc->GetFullscreenElement()) {
DispatchPointerLockError(d);
@@ -12386,75 +12445,16 @@ nsDocument::RequestPointerLock(Element*
bool userInputOrChromeCaller = EventStateManager::IsHandlingUserInput() ||
nsContentUtils::IsCallerChrome();
NS_DispatchToMainThread(new PointerLockRequest(aElement,
userInputOrChromeCaller));
}
bool
-nsDocument::ShouldLockPointer(Element* aElement, Element* aCurrentLock,
- bool aNoFocusCheck)
-{
- // Check if pointer lock pref is enabled
- if (!Preferences::GetBool("full-screen-api.pointer-lock.enabled")) {
- NS_WARNING("ShouldLockPointer(): Pointer Lock pref not enabled");
- return false;
- }
-
- if (aCurrentLock && aCurrentLock->OwnerDoc() != aElement->OwnerDoc()) {
- NS_WARNING("ShouldLockPointer(): Existing pointer lock element in a different document");
- return false;
- }
-
- if (!aElement->IsInUncomposedDoc()) {
- NS_WARNING("ShouldLockPointer(): Element without Document");
- return false;
- }
-
- if (mSandboxFlags & SANDBOXED_POINTER_LOCK) {
- NS_WARNING("ShouldLockPointer(): Document is sandboxed and doesn't allow pointer-lock");
- return false;
- }
-
- // Check if the element is in a document with a docshell.
- nsCOMPtr<nsIDocument> ownerDoc = aElement->OwnerDoc();
- if (!ownerDoc->GetContainer()) {
- return false;
- }
- nsCOMPtr<nsPIDOMWindowOuter> ownerWindow = ownerDoc->GetWindow();
- if (!ownerWindow) {
- return false;
- }
- nsCOMPtr<nsPIDOMWindowInner> ownerInnerWindow = ownerDoc->GetInnerWindow();
- if (!ownerInnerWindow) {
- return false;
- }
- if (ownerWindow->GetCurrentInnerWindow() != ownerInnerWindow) {
- return false;
- }
-
- nsCOMPtr<nsPIDOMWindowOuter> top = ownerWindow->GetScriptableTop();
- if (!top || !top->GetExtantDoc() || top->GetExtantDoc()->Hidden()) {
- NS_WARNING("ShouldLockPointer(): Top document isn't visible.");
- return false;
- }
-
- if (!aNoFocusCheck) {
- mozilla::ErrorResult rv;
- if (!top->GetExtantDoc()->HasFocus(rv)) {
- NS_WARNING("ShouldLockPointer(): Top document isn't focused.");
- return false;
- }
- }
-
- return true;
-}
-
-bool
nsDocument::SetPointerLock(Element* aElement, int aCursorStyle)
{
MOZ_ASSERT(!aElement || aElement->OwnerDoc() == this,
"We should be either unlocking pointer (aElement is nullptr), "
"or locking pointer to an element in this document");
#ifdef DEBUG
if (!aElement) {
nsCOMPtr<nsIDocument> pointerLockedDoc =
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1263,18 +1263,16 @@ public:
// Returns the top element from the full-screen stack.
Element* FullScreenStackTop();
// DOM-exposed fullscreen API
bool FullscreenEnabled() override;
Element* GetFullscreenElement() override;
void RequestPointerLock(Element* aElement) override;
- bool ShouldLockPointer(Element* aElement, Element* aCurrentLock,
- bool aNoFocusCheck = false);
bool SetPointerLock(Element* aElement, int aCursorStyle);
static void UnlockPointer(nsIDocument* aDoc = nullptr);
void SetCurrentOrientation(mozilla::dom::OrientationType aType,
uint16_t aAngle) override;
uint16_t CurrentOrientationAngle() const override;
mozilla::dom::OrientationType CurrentOrientationType() const override;
void SetOrientationPendingPromise(mozilla::dom::Promise* aPromise) override;