зеркало из https://github.com/mozilla/pjs.git
Bug 695935 - Make document.mozRequestFullScreen() asynchronous. r=bz
This commit is contained in:
Родитель
b64e5ed638
Коммит
cd58c1d983
|
@ -745,10 +745,10 @@ public:
|
|||
virtual Element* GetFullScreenElement() = 0;
|
||||
|
||||
/**
|
||||
* Requests that the document make aElement the full-screen element,
|
||||
* and move into full-screen mode.
|
||||
* Asynchronously requests that the document make aElement the full-screen
|
||||
* element, and move into full-screen mode.
|
||||
*/
|
||||
virtual void RequestFullScreen(Element* aElement) = 0;
|
||||
virtual void AsyncRequestFullScreen(Element* aElement) = 0;
|
||||
|
||||
/**
|
||||
* Requests that the document, and all documents in its hierarchy exit
|
||||
|
|
|
@ -8557,18 +8557,53 @@ GetRootDocument(nsIDocument* aDoc)
|
|||
return doc;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::RequestFullScreen(Element* aElement)
|
||||
class nsCallRequestFullScreen : public nsRunnable
|
||||
{
|
||||
if (!aElement || !nsContentUtils::IsFullScreenApiEnabled() || !GetWindow()) {
|
||||
if (aElement) {
|
||||
public:
|
||||
nsCallRequestFullScreen(Element* aElement)
|
||||
: mElement(aElement),
|
||||
mDoc(aElement->OwnerDoc()),
|
||||
mWasCallerChrome(nsContentUtils::IsCallerChrome())
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsDocument* doc = static_cast<nsDocument*>(mDoc.get());
|
||||
doc->RequestFullScreen(mElement, mWasCallerChrome);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<Element> mElement;
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
bool mWasCallerChrome;
|
||||
};
|
||||
|
||||
void
|
||||
nsDocument::AsyncRequestFullScreen(Element* aElement)
|
||||
{
|
||||
if (!aElement) {
|
||||
return;
|
||||
}
|
||||
// Request full-screen asynchronously.
|
||||
nsCOMPtr<nsIRunnable> event(new nsCallRequestFullScreen(aElement));
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
|
||||
{
|
||||
if (!aElement ||
|
||||
!aElement->IsInDoc() ||
|
||||
aElement->OwnerDoc() != this ||
|
||||
!IsFullScreenEnabled(aWasCallerChrome) ||
|
||||
!GetWindow()) {
|
||||
nsRefPtr<nsPLDOMEvent> e =
|
||||
new nsPLDOMEvent(aElement,
|
||||
new nsPLDOMEvent(this,
|
||||
NS_LITERAL_STRING("mozfullscreenerror"),
|
||||
true,
|
||||
false);
|
||||
e->PostDOMEvent();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -8663,20 +8698,25 @@ NS_IMETHODIMP
|
|||
nsDocument::GetMozFullScreenEnabled(bool *aFullScreen)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFullScreen);
|
||||
*aFullScreen = false;
|
||||
|
||||
if (nsContentUtils::IsCallerChrome() &&
|
||||
nsContentUtils::IsFullScreenApiEnabled()) {
|
||||
// Chrome code can always use the full-screen API, provided it's not
|
||||
// explicitly disabled.
|
||||
*aFullScreen = true;
|
||||
*aFullScreen = IsFullScreenEnabled(nsContentUtils::IsCallerChrome());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::IsFullScreenEnabled(bool aCallerIsChrome)
|
||||
{
|
||||
if (nsContentUtils::IsFullScreenApiEnabled() && aCallerIsChrome) {
|
||||
// Chrome code can always use the full-screen API, provided it's not
|
||||
// explicitly disabled. Note IsCallerChrome() returns true when running
|
||||
// in an nsRunnable, so don't use GetMozFullScreenEnabled() from an
|
||||
// nsRunnable!
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!nsContentUtils::IsFullScreenApiEnabled() ||
|
||||
nsContentUtils::HasPluginWithUncontrolledEventDispatch(this) ||
|
||||
!IsVisible()) {
|
||||
return NS_OK;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure that all ancestor <iframe> elements have the mozallowfullscreen
|
||||
|
@ -8689,13 +8729,12 @@ nsDocument::GetMozFullScreenEnabled(bool *aFullScreen)
|
|||
// The node requesting fullscreen, or one of its crossdoc ancestors,
|
||||
// is an iframe which doesn't have the "mozalllowfullscreen" attribute.
|
||||
// This request is not authorized by the parent document.
|
||||
return NS_OK;
|
||||
return false;
|
||||
}
|
||||
node = nsContentUtils::GetCrossDocParentNode(node);
|
||||
} while (node);
|
||||
|
||||
*aFullScreen = true;
|
||||
return NS_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
PRInt64
|
||||
|
|
|
@ -952,10 +952,16 @@ public:
|
|||
virtual Element* FindImageMap(const nsAString& aNormalizedMapName);
|
||||
|
||||
virtual Element* GetFullScreenElement();
|
||||
virtual void RequestFullScreen(Element* aElement);
|
||||
virtual void AsyncRequestFullScreen(Element* aElement);
|
||||
virtual void CancelFullScreen();
|
||||
virtual bool IsFullScreenDoc();
|
||||
|
||||
// This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
|
||||
// to move document into full-screen mode if allowed. aWasCallerChrome
|
||||
// should be true when nsIDocument::AsyncRequestFullScreen() was called
|
||||
// by chrome code.
|
||||
void RequestFullScreen(Element* aElement, bool aWasCallerChrome);
|
||||
|
||||
// Returns true if making this change results in a change in the full-screen
|
||||
// state of this document.
|
||||
bool SetFullScreenState(Element* aElement, bool aIsFullScreen);
|
||||
|
@ -969,6 +975,13 @@ public:
|
|||
protected:
|
||||
friend class nsNodeUtils;
|
||||
|
||||
// Returns true if a request for DOM full-screen is currently enabled in
|
||||
// this document. This returns true if there are no windowed plugins in this
|
||||
// doc tree, and if the document is visible, and if the api is not
|
||||
// disabled by pref. aIsCallerChrome must contain the return value of
|
||||
// nsContentUtils::IsCallerChrome() from the context we're checking.
|
||||
bool IsFullScreenEnabled(bool aIsCallerChrome);
|
||||
|
||||
/**
|
||||
* Check that aId is not empty and log a message to the console
|
||||
* service if it is.
|
||||
|
|
|
@ -3404,11 +3404,9 @@ nsresult nsGenericHTMLElement::MozRequestFullScreen()
|
|||
// This stops the full-screen from being abused similar to the popups of old,
|
||||
// and it also makes it harder for bad guys' script to go full-screen and
|
||||
// spoof the browser chrome/window and phish logins etc.
|
||||
nsIDocument* doc = OwnerDoc();
|
||||
if (!nsContentUtils::IsRequestFullScreenAllowed() ||
|
||||
!IsInDoc()) {
|
||||
if (!nsContentUtils::IsRequestFullScreenAllowed()) {
|
||||
nsRefPtr<nsPLDOMEvent> e =
|
||||
new nsPLDOMEvent(this,
|
||||
new nsPLDOMEvent(OwnerDoc(),
|
||||
NS_LITERAL_STRING("mozfullscreenerror"),
|
||||
true,
|
||||
false);
|
||||
|
@ -3416,27 +3414,8 @@ nsresult nsGenericHTMLElement::MozRequestFullScreen()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDocument(do_QueryInterface(doc));
|
||||
NS_ENSURE_STATE(domDocument);
|
||||
bool fullScreenEnabled;
|
||||
domDocument->GetMozFullScreenEnabled(&fullScreenEnabled);
|
||||
if (!fullScreenEnabled) {
|
||||
nsRefPtr<nsPLDOMEvent> e =
|
||||
new nsPLDOMEvent(this,
|
||||
NS_LITERAL_STRING("mozfullscreenerror"),
|
||||
true,
|
||||
false);
|
||||
e->PostDOMEvent();
|
||||
return NS_OK;
|
||||
}
|
||||
OwnerDoc()->AsyncRequestFullScreen(this);
|
||||
|
||||
doc->RequestFullScreen(this);
|
||||
#ifdef DEBUG
|
||||
bool fullscreen;
|
||||
domDocument->GetMozFullScreen(&fullscreen);
|
||||
NS_ASSERTION(fullscreen, "Document should report fullscreen");
|
||||
NS_ASSERTION(doc->IsFullScreenDoc(), "Should be in full screen state!");
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -283,6 +283,7 @@ _TEST_FILES = \
|
|||
test_fullscreen-api.html \
|
||||
file_fullscreen-plugins.html \
|
||||
file_fullscreen-denied.html \
|
||||
file_fullscreen-denied-inner.html \
|
||||
file_fullscreen-hidden.html \
|
||||
file_fullscreen-navigation.html \
|
||||
test_li_attributes_reflection.html \
|
||||
|
|
|
@ -94,6 +94,9 @@ function testNextKey() {
|
|||
if (!document.mozFullScreen) {
|
||||
document.body.mozRequestFullScreen();
|
||||
}
|
||||
// mozRequestFullScreen() is async...
|
||||
setTimeout(
|
||||
function() {
|
||||
ok(document.mozFullScreen, "Must be in full-screen mode");
|
||||
|
||||
gKeyName = keyList[gKeyTestIndex].code;
|
||||
|
@ -103,6 +106,7 @@ function testNextKey() {
|
|||
|
||||
testScriptInitiatedKeyEvents();
|
||||
testTrustedKeyEvents();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", keyHandler, true);
|
||||
|
|
|
@ -98,6 +98,9 @@ function fullScreenChange(event) {
|
|||
"Full-screen element should be iframe element.");
|
||||
var fse = fullScreenElement();
|
||||
fse.mozRequestFullScreen();
|
||||
|
||||
setTimeout(
|
||||
function() {
|
||||
ok(document.mozFullScreen, "Should still be full-screen mode after re-requesting.");
|
||||
is(document.mozFullScreenElement, fse, "Full-screen element should have switched to requestee.");
|
||||
var _innerFrame = iframe.contentDocument.getElementById("inner-frame");
|
||||
|
@ -110,6 +113,8 @@ function fullScreenChange(event) {
|
|||
ok(!_innerFrame.contentDocument.mozFullScreen, "Inner frame should not acquire full-screen status.");
|
||||
|
||||
document.body.appendChild(fse);
|
||||
}, 0);
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
|
@ -119,8 +124,13 @@ function fullScreenChange(event) {
|
|||
is(document.mozFullScreenElement, null, "Full-screen element should be null.");
|
||||
document.body.removeChild(iframe);
|
||||
iframe = null;
|
||||
|
||||
// Do a request out of document. It should be denied.
|
||||
// Continue test in the following mozfullscreenerror handler.
|
||||
outOfDocElement = document.createElement("div");
|
||||
outOfDocElement.mozRequestFullScreen();
|
||||
var f =
|
||||
function(e) {
|
||||
document.removeEventListener("mozfullscreenerror", f, false);
|
||||
ok(!document.mozFullScreen, "Requests for full-screen from not-in-doc elements should fail.");
|
||||
|
||||
container = document.createElement("div");
|
||||
|
@ -129,7 +139,10 @@ function fullScreenChange(event) {
|
|||
fullScreenElement().appendChild(container);
|
||||
|
||||
inDocElement.mozRequestFullScreen();
|
||||
ok(document.mozFullScreen, "Should grant request to return to full-screen mode (third time)");
|
||||
};
|
||||
document.addEventListener("mozfullscreenerror", f, false);
|
||||
outOfDocElement.mozRequestFullScreen();
|
||||
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
|
@ -157,11 +170,11 @@ function fullScreenChange(event) {
|
|||
setRequireTrustedContext(true);
|
||||
fullscreendenied = false;
|
||||
fullScreenElement().mozRequestFullScreen();
|
||||
ok(!document.mozFullScreen, "Should still be in normal mode, because calling context isn't trusted.");
|
||||
|
||||
setTimeout(
|
||||
function() {
|
||||
ok(fullscreendenied, "Request for fullscreen should have been denied because calling context isn't trusted");
|
||||
ok(!document.mozFullScreen, "Should still be in normal mode, because calling context isn't trusted.");
|
||||
button = document.createElement("button");
|
||||
button.onclick = function(){fullScreenElement().mozRequestFullScreen();}
|
||||
fullScreenElement().appendChild(button);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<html>
|
||||
<body onload='foo();'>
|
||||
<script>
|
||||
function foo() {
|
||||
document.addEventListener('mozfullscreenerror',
|
||||
function() {
|
||||
parent.ok(true, "Request from an iframe without mozallowfullscreen should be denied");
|
||||
parent.finish();
|
||||
},
|
||||
false);
|
||||
document.addEventListener('mozfullscreenchange',
|
||||
function() {
|
||||
parent.ok(false, "Request from an iframe without mozallowfullscreen should be denied, but was granted!");
|
||||
parent.finish();
|
||||
},
|
||||
false);
|
||||
parent.is(document.mozFullScreenEnabled, false, "Full-screen should not be enabled, coz mozallowfullscreen isn't present.");
|
||||
document.body.mozRequestFullScreen();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -29,14 +29,6 @@ function is(a, b, msg) {
|
|||
opener.is(a, b, msg);
|
||||
}
|
||||
|
||||
/*
|
||||
<html>
|
||||
<body onload='document.body.mozRequestFullScreen();'>
|
||||
</body>
|
||||
</html>
|
||||
*/
|
||||
var requestFullScreenContents = "data:text/html;charset=utf-8,<html>%0D%0A <body onload%3D'document.body.mozRequestFullScreen()%3B'>%0D%0A <%2Fbody>%0D%0A<%2Fhtml>";
|
||||
|
||||
var fullscreendenied = false;
|
||||
|
||||
document.addEventListener("mozfullscreenerror", function(){fullscreendenied=true;}, false);
|
||||
|
@ -54,8 +46,8 @@ function run() {
|
|||
// Request full-screen from a non trusted context (this script isn't a user
|
||||
// generated event!).
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", true);
|
||||
document.body.mozRequestFullScreen();
|
||||
fullscreendenied = false;
|
||||
document.body.mozRequestFullScreen();
|
||||
setTimeout(
|
||||
function() {
|
||||
ok(!document.mozFullScreen, "Should not grant request in non-truested context");
|
||||
|
@ -87,19 +79,18 @@ function keyHandler(event) {
|
|||
// to write.
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
|
||||
|
||||
// Create an iframe without a mozallowfullscreen sttribute, whose contents requests
|
||||
// Create an iframe without a mozallowfullscreen attribute, whose contents requests
|
||||
// full-screen. The request should be denied, and we should not receive a fullscreenchange
|
||||
// event in this document.
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = requestFullScreenContents;
|
||||
iframe.src = "file_fullscreen-denied-inner.html";
|
||||
document.body.appendChild(iframe);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
setTimeout(
|
||||
function() {
|
||||
function finish() {
|
||||
ok(!gotFullScreenChange, "Should not ever grant a fullscreen request in this doc.");
|
||||
opener.nextTest();
|
||||
}, 0);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -74,15 +74,26 @@ function startTest() {
|
|||
// Running on MacOS, all plugins are effectively windowless, request for full-screen should be granted.
|
||||
// Continue test in the (mac-specific) "mozfullscreenchange" handler.
|
||||
return;
|
||||
} else {
|
||||
// Non-MacOS, request should be denied, carry on the test after receiving error event.
|
||||
document.addEventListener("mozfullscreenerror", nonMacTest, false);
|
||||
}
|
||||
}
|
||||
|
||||
function nonMacTest() {
|
||||
document.removeEventListener("mozfullscreenerror", nonMacTest, false);
|
||||
ok(!document.mozFullScreen, "Request for full-screen from a document containing windowed plugin should be denied.");
|
||||
|
||||
// Remove plugin in this document. Should still be a windowed plugin in sub-document.
|
||||
windowedPlugin = document.getElementById("windowed-plugin");
|
||||
windowedPlugin.parentNode.removeChild(windowedPlugin);
|
||||
|
||||
document.addEventListener("mozfullscreenerror", nonMacTest2, false);
|
||||
document.body.mozRequestFullScreen();
|
||||
}
|
||||
|
||||
function nonMacTest2() {
|
||||
document.removeEventListener("mozfullscreenerror", nonMacTest2, false);
|
||||
ok(!document.mozFullScreen, "Request for full-screen from a document with subdocument containing windowed plugin should be denied.");
|
||||
// Remove subdoc which contains windowed plugin, request full-screen, request should be granted.
|
||||
// Continue test in "mozfullscreenchange" handler.
|
||||
|
|
Загрузка…
Ссылка в новой задаче