mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 753546 part 3 - Record fullscreen approval in nsDocument flag. r=smaug
This commit is contained in:
parent
b8d01f2593
commit
a462b79857
@ -92,9 +92,8 @@ class Element;
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x8e51e6d9, 0x914d, 0x46ba, \
|
||||
{ 0xb3, 0x11, 0x2f, 0x27, 0x3d, 0xe6, 0x0d, 0x19 } }
|
||||
|
||||
{ 0x88d887da, 0xd228, 0x41c2, \
|
||||
{ 0xb8, 0x0a, 0x42, 0xec, 0xf0, 0xcb, 0xce, 0x37 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
@ -744,6 +743,14 @@ public:
|
||||
*/
|
||||
virtual bool IsFullScreenDoc() = 0;
|
||||
|
||||
/**
|
||||
* Sets whether this document is approved for fullscreen mode.
|
||||
* Documents aren't approved for fullscreen until chrome has sent a
|
||||
* "fullscreen-approved" notification with a subject which is a pointer
|
||||
* to the approved document.
|
||||
*/
|
||||
virtual void SetApprovedForFullscreen(bool aIsApproved) = 0;
|
||||
|
||||
/**
|
||||
* Exits all documents from DOM full-screen mode, and moves the top-level
|
||||
* browser window out of full-screen mode. If aRunAsync is true, this runs
|
||||
|
@ -7391,7 +7391,7 @@ nsDocument::OnPageHide(bool aPersisted,
|
||||
// document to reset its state, so reset full-screen state in *this*
|
||||
// document. OnPageHide() is called in every hidden document, so doing
|
||||
// this ensures all hidden documents have their full-screen state reset.
|
||||
ClearFullScreenStack();
|
||||
CleanupFullscreenState();
|
||||
|
||||
// Next reset full-screen state in all visible documents in the doctree.
|
||||
nsIDocument::ExitFullScreen(false);
|
||||
@ -8581,7 +8581,7 @@ nsIDocument::ExitFullScreen(bool aRunAsync)
|
||||
static bool
|
||||
ResetFullScreen(nsIDocument* aDocument, void* aData) {
|
||||
if (aDocument->IsFullScreenDoc()) {
|
||||
static_cast<nsDocument*>(aDocument)->ClearFullScreenStack();
|
||||
static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
|
||||
NS_ASSERTION(!aDocument->IsFullScreenDoc(), "Should reset full-screen");
|
||||
nsTArray<nsIDocument*>* changed = reinterpret_cast<nsTArray<nsIDocument*>*>(aData);
|
||||
changed->AppendElement(aDocument);
|
||||
@ -8659,7 +8659,7 @@ nsDocument::RestorePreviousFullScreenState()
|
||||
nsIDocument* doc = fullScreenDoc;
|
||||
while (doc != this) {
|
||||
NS_ASSERTION(doc->IsFullScreenDoc(), "Should be full-screen doc");
|
||||
static_cast<nsDocument*>(doc)->ClearFullScreenStack();
|
||||
static_cast<nsDocument*>(doc)->CleanupFullscreenState();
|
||||
UnlockPointer();
|
||||
DispatchFullScreenChange(doc);
|
||||
doc = doc->GetParentDocument();
|
||||
@ -8675,6 +8675,7 @@ nsDocument::RestorePreviousFullScreenState()
|
||||
// Full-screen stack in document is empty. Go back up to the parent
|
||||
// document. We'll pop the containing element off its stack, and use
|
||||
// its next full-screen element as the full-screen element.
|
||||
static_cast<nsDocument*>(doc)->CleanupFullscreenState();
|
||||
doc = doc->GetParentDocument();
|
||||
} else {
|
||||
// Else we popped the top of the stack, and there's still another
|
||||
@ -8768,21 +8769,46 @@ LogFullScreenDenied(bool aLogFailure, const char* aMessage, nsIDocument* aDoc)
|
||||
aMessage);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::ClearFullScreenStack()
|
||||
nsresult
|
||||
nsDocument::AddFullscreenApprovedObserver()
|
||||
{
|
||||
if (mFullScreenStack.IsEmpty()) {
|
||||
return;
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
NS_ENSURE_TRUE(os, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult res = os->AddObserver(this, "fullscreen-approved", true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::RemoveFullscreenApprovedObserver()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
NS_ENSURE_TRUE(os, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult res = os->RemoveObserver(this, "fullscreen-approved");
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::CleanupFullscreenState()
|
||||
{
|
||||
if (!mFullScreenStack.IsEmpty()) {
|
||||
// The top element in the full-screen stack will have full-screen
|
||||
// style bits set on it and its ancestors. Remove the style bits.
|
||||
// Note the non-top elements won't have the style bits set.
|
||||
Element* top = FullScreenStackTop();
|
||||
NS_ASSERTION(top, "Should have a top when full-screen stack isn't empty");
|
||||
if (top) {
|
||||
nsEventStateManager::SetFullScreenState(top, false);
|
||||
}
|
||||
mFullScreenStack.Clear();
|
||||
}
|
||||
// The top element in the full-screen stack will have full-screen
|
||||
// style bits set on it and its ancestors. Remove the style bits.
|
||||
// Note the non-top elements won't have the style bits set.
|
||||
Element* top = FullScreenStackTop();
|
||||
NS_ASSERTION(top, "Should have a top when full-screen stack isn't empty");
|
||||
if (top) {
|
||||
nsEventStateManager::SetFullScreenState(top, false);
|
||||
}
|
||||
mFullScreenStack.Clear();
|
||||
SetApprovedForFullscreen(false);
|
||||
RemoveFullscreenApprovedObserver();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -8950,6 +8976,8 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
|
||||
}
|
||||
}
|
||||
|
||||
AddFullscreenApprovedObserver();
|
||||
|
||||
// Stores a list of documents which we must dispatch "mozfullscreenchange"
|
||||
// too. We're required by the spec to dispatch the events in root-to-leaf
|
||||
// order, but we traverse the doctree in a leaf-to-root order, so we save
|
||||
@ -9018,6 +9046,14 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
|
||||
true);
|
||||
e->PostDOMEvent();
|
||||
|
||||
// If this document hasn't already been approved in this session,
|
||||
// check to see if the user has granted the fullscreen access
|
||||
// to the document's principal's host, if it has one.
|
||||
if (!mIsApprovedForFullscreen) {
|
||||
mIsApprovedForFullscreen =
|
||||
nsContentUtils::IsSitePermAllow(NodePrincipal(), "fullscreen");
|
||||
}
|
||||
|
||||
// Remember this is the requesting full-screen document.
|
||||
sFullScreenDoc = do_GetWeakReference(static_cast<nsIDocument*>(this));
|
||||
|
||||
@ -9246,19 +9282,6 @@ nsDocument::ClearPendingPointerLockRequest(bool aDispatchErrorEvents)
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryReferent(sPendingPointerLockDoc));
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (!os) {
|
||||
NS_WARNING("Lost observer service in ClearPendingPointerLockRequest()!");
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserver> obs(do_QueryInterface(doc));
|
||||
if (!os) {
|
||||
NS_WARNING("Document must implement nsIObserver");
|
||||
return;
|
||||
}
|
||||
os->RemoveObserver(obs, "fullscreen-approved");
|
||||
|
||||
if (aDispatchErrorEvents) {
|
||||
DispatchPointerLockError(doc);
|
||||
}
|
||||
@ -9283,16 +9306,7 @@ nsDocument::SetPendingPointerLockRequest(Element* aElement)
|
||||
// If there's an existing pending pointer lock request, deny it.
|
||||
ClearPendingPointerLockRequest(true);
|
||||
|
||||
NS_ENSURE_TRUE(aElement != nsnull, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
NS_ENSURE_TRUE(os != nsnull, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIObserver> obs(do_QueryInterface(aElement->OwnerDoc()));
|
||||
NS_ENSURE_TRUE(obs != nsnull, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult res = os->AddObserver(obs, "fullscreen-approved", true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(aElement != nsnull, NS_ERROR_FAILURE);
|
||||
|
||||
sPendingPointerLockDoc = do_GetWeakReference(aElement->OwnerDoc());
|
||||
sPendingPointerLockElement = do_GetWeakReference(aElement);
|
||||
@ -9303,6 +9317,12 @@ nsDocument::SetPendingPointerLockRequest(Element* aElement)
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::SetApprovedForFullscreen(bool aIsApproved)
|
||||
{
|
||||
mIsApprovedForFullscreen = aIsApproved;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::Observe(nsISupports *aSubject,
|
||||
@ -9311,11 +9331,17 @@ nsDocument::Observe(nsISupports *aSubject,
|
||||
{
|
||||
if (strcmp("fullscreen-approved", aTopic) == 0) {
|
||||
nsCOMPtr<nsIDocument> subject(do_QueryInterface(aSubject));
|
||||
if (subject != this) {
|
||||
return NS_OK;
|
||||
}
|
||||
SetApprovedForFullscreen(true);
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryReferent(sPendingPointerLockDoc));
|
||||
if (subject == doc) {
|
||||
if (this == doc) {
|
||||
// This doc has a pointer lock request, waiting for fullscreen to be
|
||||
// approved before it can be granted. Process the pointer lock request.
|
||||
nsCOMPtr<Element> element(do_QueryReferent(sPendingPointerLockElement));
|
||||
nsDocument::ClearPendingPointerLockRequest(false);
|
||||
nsAsyncPointerLockRequest::Request(element, doc);
|
||||
nsAsyncPointerLockRequest::Request(element, this);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
@ -9339,8 +9365,8 @@ nsDocument::RequestPointerLock(Element* aElement)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nsContentUtils::IsSitePermAllow(NodePrincipal(), "fullscreen")) {
|
||||
// Domain isn't yet approved for fullscreen, so we must wait until
|
||||
if (!mIsApprovedForFullscreen) {
|
||||
// Document isn't yet approved for fullscreen, so we must wait until
|
||||
// it's been approved.
|
||||
if (NS_FAILED(SetPendingPointerLockRequest(aElement))) {
|
||||
NS_WARNING("Failed to make pointer lock request pending!");
|
||||
|
@ -929,6 +929,8 @@ public:
|
||||
virtual void AsyncRequestFullScreen(Element* aElement);
|
||||
virtual void RestorePreviousFullScreenState();
|
||||
virtual bool IsFullScreenDoc();
|
||||
virtual void SetApprovedForFullscreen(bool aIsApproved);
|
||||
|
||||
static void ExitFullScreen();
|
||||
|
||||
// This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
|
||||
@ -939,7 +941,14 @@ public:
|
||||
|
||||
// Removes all elements from the full-screen stack, removing full-scren
|
||||
// styles from the top element in the stack.
|
||||
void ClearFullScreenStack();
|
||||
void CleanupFullscreenState();
|
||||
|
||||
// Add/remove "fullscreen-approved" observer service notification listener.
|
||||
// Chrome sends us a notification when fullscreen is approved for a
|
||||
// document, with the notification subject as the document that was approved.
|
||||
// We maintain this listener while in fullscreen mode.
|
||||
nsresult AddFullscreenApprovedObserver();
|
||||
nsresult RemoveFullscreenApprovedObserver();
|
||||
|
||||
// Pushes aElement onto the full-screen stack, and removes full-screen styles
|
||||
// from the former full-screen stack top, and its ancestors, and applies the
|
||||
@ -1180,6 +1189,21 @@ protected:
|
||||
// terminated instead of letting it finish at its own pace.
|
||||
bool mParserAborted:1;
|
||||
|
||||
// Whether this document has been approved for fullscreen, either by explicit
|
||||
// approval via the fullscreen-approval UI, or because it received
|
||||
// approval because its document's host already had the "fullscreen"
|
||||
// permission granted when the document requested fullscreen.
|
||||
//
|
||||
// Note if a document's principal doesn't have a host, the permission manager
|
||||
// can't store permissions for it, so we can only manage approval using this
|
||||
// flag.
|
||||
//
|
||||
// Note we must track this separately from the "fullscreen" permission,
|
||||
// so that pending pointer lock requests can determine whether documents
|
||||
// whose principal doesn't have a host (i.e. those which can't store
|
||||
// permissions in the permission manager) have been approved for fullscreen.
|
||||
bool mIsApprovedForFullscreen:1;
|
||||
|
||||
PRUint8 mXMLDeclarationBits;
|
||||
|
||||
nsInterfaceHashtable<nsPtrHashKey<nsIContent>, nsPIBoxObject> *mBoxObjectTable;
|
||||
|
Loading…
Reference in New Issue
Block a user