mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
Bug 1285069 part 2 - Remove nsPointerLockPermissionRequest, only keep the Allow method under a different name. r=smaug
We still want to keep ApplyPointerLock asynchronous so that the timing when pointer lock takes effect is not changed by this patch. MozReview-Commit-ID: EA8c6uzOd8F --HG-- extra : rebase_source : 1d6355b618e67ff42c65d8088d3ccb1dca339401 extra : source : 98e099aad4b57295ffdce68a0140179d50bfd044
This commit is contained in:
parent
efc0e7f9af
commit
4bbb9f1825
@ -223,7 +223,6 @@
|
||||
#include "nsDOMCaretPosition.h"
|
||||
#include "nsIDOMHTMLTextAreaElement.h"
|
||||
#include "nsViewportInfo.h"
|
||||
#include "nsIContentPermissionPrompt.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsITextControlElement.h"
|
||||
#include "nsIDOMNSEditableElement.h"
|
||||
@ -241,7 +240,6 @@
|
||||
#include "nsIDocumentActivity.h"
|
||||
#include "nsIStructuredCloneContainer.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsContentPermissionHelper.h"
|
||||
#include "mozilla/dom/DOMStringList.h"
|
||||
#include "nsWindowMemoryReporter.h"
|
||||
#include "nsLocation.h"
|
||||
@ -12299,152 +12297,34 @@ DispatchPointerLockError(nsIDocument* aTarget)
|
||||
asyncDispatcher->PostDOMEvent();
|
||||
}
|
||||
|
||||
static const uint8_t kPointerLockRequestLimit = 2;
|
||||
|
||||
class nsPointerLockPermissionRequest;
|
||||
mozilla::StaticRefPtr<nsPointerLockPermissionRequest> gPendingPointerLockRequest;
|
||||
|
||||
class nsPointerLockPermissionRequest : public Runnable,
|
||||
public nsIContentPermissionRequest
|
||||
class PointerLockRequest final : public Runnable
|
||||
{
|
||||
public:
|
||||
nsPointerLockPermissionRequest(Element* aElement, bool aUserInputOrChromeCaller)
|
||||
: mElement(do_GetWeakReference(aElement)),
|
||||
mDocument(do_GetWeakReference(aElement->OwnerDoc())),
|
||||
mUserInputOrChromeCaller(aUserInputOrChromeCaller)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
|
||||
if (doc && doc->GetInnerWindow()) {
|
||||
mRequester = new nsContentPermissionRequester(doc->GetInnerWindow());
|
||||
}
|
||||
}
|
||||
PointerLockRequest(Element* aElement, bool aUserInputOrChromeCaller)
|
||||
: mElement(do_GetWeakReference(aElement))
|
||||
, mDocument(do_GetWeakReference(aElement->OwnerDoc()))
|
||||
, mUserInputOrChromeCaller(aUserInputOrChromeCaller)
|
||||
{}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSICONTENTPERMISSIONREQUEST
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
nsCOMPtr<Element> e = do_QueryReferent(mElement);
|
||||
nsCOMPtr<nsIDocument> d = do_QueryReferent(mDocument);
|
||||
if (!e || !d || gPendingPointerLockRequest != this ||
|
||||
e->GetUncomposedDoc() != d) {
|
||||
Handled();
|
||||
DispatchPointerLockError(d);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsDocument* doc = static_cast<nsDocument*>(d.get());
|
||||
if (doc->GetFullscreenElement() || doc->mAllowRelocking) {
|
||||
Allow(JS::UndefinedHandleValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// In non-fullscreen mode user input (or chrome caller) is required!
|
||||
// Also, don't let the page to try to get the permission too many times.
|
||||
if (!mUserInputOrChromeCaller ||
|
||||
doc->mCancelledPointerLockRequests > kPointerLockRequestLimit) {
|
||||
Handled();
|
||||
DispatchPointerLockError(d);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Allow(JS::UndefinedHandleValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void Handled()
|
||||
{
|
||||
mElement = nullptr;
|
||||
mDocument = nullptr;
|
||||
if (gPendingPointerLockRequest == this) {
|
||||
gPendingPointerLockRequest = nullptr;
|
||||
}
|
||||
}
|
||||
NS_IMETHOD Run() final;
|
||||
|
||||
private:
|
||||
nsWeakPtr mElement;
|
||||
nsWeakPtr mDocument;
|
||||
bool mUserInputOrChromeCaller;
|
||||
|
||||
protected:
|
||||
virtual ~nsPointerLockPermissionRequest() {}
|
||||
nsCOMPtr<nsIContentPermissionRequester> mRequester;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsPointerLockPermissionRequest,
|
||||
Runnable,
|
||||
nsIContentPermissionRequest)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPointerLockPermissionRequest::GetTypes(nsIArray** aTypes)
|
||||
PointerLockRequest::Run()
|
||||
{
|
||||
nsTArray<nsString> emptyOptions;
|
||||
return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("pointerLock"),
|
||||
NS_LITERAL_CSTRING("unused"),
|
||||
emptyOptions,
|
||||
aTypes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPointerLockPermissionRequest::GetPrincipal(nsIPrincipal** aPrincipal)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> d = do_QueryReferent(mDocument);
|
||||
if (d) {
|
||||
NS_ADDREF(*aPrincipal = d->NodePrincipal());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPointerLockPermissionRequest::GetWindow(mozIDOMWindow** aWindow)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> d = do_QueryReferent(mDocument);
|
||||
if (d) {
|
||||
NS_IF_ADDREF(*aWindow = d->GetInnerWindow());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPointerLockPermissionRequest::GetElement(nsIDOMElement** aElement)
|
||||
{
|
||||
// It is enough to implement GetWindow.
|
||||
*aElement = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPointerLockPermissionRequest::Cancel()
|
||||
{
|
||||
nsCOMPtr<nsIDocument> d = do_QueryReferent(mDocument);
|
||||
Handled();
|
||||
if (d) {
|
||||
auto doc = static_cast<nsDocument*>(d.get());
|
||||
if (doc->mCancelledPointerLockRequests <= kPointerLockRequestLimit) {
|
||||
doc->mCancelledPointerLockRequests++;
|
||||
}
|
||||
DispatchPointerLockError(d);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPointerLockPermissionRequest::Allow(JS::HandleValue aChoices)
|
||||
{
|
||||
MOZ_ASSERT(aChoices.isUndefined());
|
||||
|
||||
nsCOMPtr<Element> e = do_QueryReferent(mElement);
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
|
||||
nsDocument* d = static_cast<nsDocument*>(doc.get());
|
||||
if (!e || !d || gPendingPointerLockRequest != this ||
|
||||
e->GetUncomposedDoc() != d) {
|
||||
Handled();
|
||||
if (!e || !d || e->GetUncomposedDoc() != d) {
|
||||
DispatchPointerLockError(d);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Mark handled here so that we don't need to call it everywhere below.
|
||||
Handled();
|
||||
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(EventStateManager::sPointerLockedElement);
|
||||
if (e == pointerLockedElement) {
|
||||
@ -12458,12 +12338,18 @@ nsPointerLockPermissionRequest::Allow(JS::HandleValue aChoices)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If it is neither user input initiated, nor requested in fullscreen,
|
||||
// it should be rejected.
|
||||
if (!mUserInputOrChromeCaller && !doc->GetFullscreenElement()) {
|
||||
DispatchPointerLockError(d);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!d->SetPointerLock(e, NS_STYLE_CURSOR_NONE)) {
|
||||
DispatchPointerLockError(d);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
d->mCancelledPointerLockRequests = 0;
|
||||
e->SetPointerLock();
|
||||
EventStateManager::sPointerLockedElement = do_GetWeakReference(e);
|
||||
EventStateManager::sPointerLockedDoc = do_GetWeakReference(doc);
|
||||
@ -12479,16 +12365,6 @@ nsPointerLockPermissionRequest::Allow(JS::HandleValue aChoices)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPointerLockPermissionRequest::GetRequester(nsIContentPermissionRequester** aRequester)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRequester);
|
||||
|
||||
nsCOMPtr<nsIContentPermissionRequester> requester = mRequester;
|
||||
requester.forget(aRequester);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
@ -12582,11 +12458,8 @@ nsDocument::RequestPointerLock(Element* aElement)
|
||||
|
||||
bool userInputOrChromeCaller = EventStateManager::IsHandlingUserInput() ||
|
||||
nsContentUtils::IsCallerChrome();
|
||||
|
||||
gPendingPointerLockRequest =
|
||||
new nsPointerLockPermissionRequest(aElement, userInputOrChromeCaller);
|
||||
nsCOMPtr<nsIRunnable> r = gPendingPointerLockRequest.get();
|
||||
NS_DispatchToMainThread(r);
|
||||
NS_DispatchToMainThread(new PointerLockRequest(aElement,
|
||||
userInputOrChromeCaller));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -12718,8 +12591,6 @@ nsDocument::UnlockPointer(nsIDocument* aDoc)
|
||||
|
||||
EventStateManager::sPointerLockedElement = nullptr;
|
||||
EventStateManager::sPointerLockedDoc = nullptr;
|
||||
static_cast<nsDocument*>(pointerLockedDoc.get())->mAllowRelocking = !!aDoc;
|
||||
gPendingPointerLockRequest = nullptr;
|
||||
|
||||
nsContentUtils::DispatchEventOnlyToChrome(
|
||||
doc, ToSupports(pointerLockedElement),
|
||||
@ -12773,7 +12644,6 @@ nsIDocument::GetMozPointerLockElement()
|
||||
void
|
||||
nsDocument::XPCOMShutdown()
|
||||
{
|
||||
gPendingPointerLockRequest = nullptr;
|
||||
sProcessingStack.reset();
|
||||
}
|
||||
|
||||
|
@ -1651,11 +1651,7 @@ public:
|
||||
// terminated instead of letting it finish at its own pace.
|
||||
bool mParserAborted:1;
|
||||
|
||||
friend class nsPointerLockPermissionRequest;
|
||||
friend class nsCallRequestFullScreen;
|
||||
// When set, trying to lock the pointer doesn't require permission from the
|
||||
// user.
|
||||
bool mAllowRelocking:1;
|
||||
|
||||
// ScreenOrientation "pending promise" as described by
|
||||
// http://www.w3.org/TR/screen-orientation/
|
||||
@ -1674,10 +1670,6 @@ public:
|
||||
// 'style-sheet-applicable-state-changed' notification.
|
||||
bool mSSApplicableStateNotificationPending:1;
|
||||
|
||||
// The number of pointer lock requests which are cancelled by the user.
|
||||
// The value is saturated to kPointerLockRequestLimit+1 = 3.
|
||||
uint8_t mCancelledPointerLockRequests:2;
|
||||
|
||||
// Whether we have reported use counters for this document with Telemetry yet.
|
||||
// Normally this is only done at document destruction time, but for image
|
||||
// documents (SVG documents) that are not guaranteed to be destroyed, we
|
||||
|
Loading…
Reference in New Issue
Block a user