Backout 80831e4a10de (bug 706672) for build failures on a CLOSED TREE

This commit is contained in:
Ed Morley 2011-12-15 22:09:55 +00:00
parent ac62f6712f
commit c1da559e35
8 changed files with 108 additions and 119 deletions

View File

@ -8801,43 +8801,6 @@ nsDocument::FullScreenStackTop()
return element;
}
static bool
IsInFocusedTab(nsIDocument* aDoc)
{
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (!fm) {
return false;
}
// Is there a focused DOMWindow?
nsCOMPtr<nsIDOMWindow> focusedWindow;
fm->GetFocusedWindow(getter_AddRefs(focusedWindow));
if (!focusedWindow) {
return false;
}
// Retreive the focused document.
nsCOMPtr<nsIDOMDocument> domDocument;
focusedWindow->GetDocument(getter_AddRefs(domDocument));
nsCOMPtr<nsIDocument> focusedDoc = do_QueryInterface(domDocument);
// When the chrome document is focused, only grant requests from the
// chrome document.
if (nsContentUtils::IsChromeDoc(focusedDoc)) {
return aDoc == focusedDoc;
}
// Find the common ancestor of aDoc and the focused document.
nsIDocument* commonAncestor = GetCommonAncestor(focusedDoc, aDoc);
if (commonAncestor == focusedDoc || commonAncestor == aDoc) {
// The focused document is either above or below aDoc in the
// doctree. It must be in the same tab (doctree branch).
return true;
}
return false;
}
void
nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
{
@ -8869,25 +8832,6 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
LogFullScreenDenied(true, "FullScreenDeniedNotDescendant", this);
return;
}
if (!IsInFocusedTab(this)) {
LogFullScreenDenied(true, "FullScreenDeniedNotFocusedTab", this);
return;
}
// Deny requests when a windowed plugin is focused.
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (!fm) {
NS_WARNING("Failed to retrieve focus manager in full-screen request.");
return;
}
nsCOMPtr<nsIDOMElement> focusedElement;
fm->GetFocusedElement(getter_AddRefs(focusedElement));
if (focusedElement) {
nsCOMPtr<nsIContent> content = do_QueryInterface(focusedElement);
if (nsContentUtils::HasPluginWithUncontrolledEventDispatch(content)) {
LogFullScreenDenied(true, "FullScreenDeniedFocusedPlugin", this);
return;
}
}
// 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
@ -8896,6 +8840,16 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
// as specified.
nsAutoTArray<nsIDocument*, 8> changed;
// If another top-level window is full-screen. Exit it from full-screen.
nsCOMPtr<nsIDocument> fullScreenDoc(do_QueryReferent(sFullScreenDoc));
nsIDocument* commonAncestor = GetCommonAncestor(fullScreenDoc, this);
if (fullScreenDoc && !commonAncestor) {
// A document which doesn't have a common ancestor is full-screen, this
// must be in a separate browser window. Fully exit full-screen, to move
// the other browser window/doctree out of full-screen.
nsIDocument::ExitFullScreen(false);
}
// Remember the root document, so that if a full-screen document is hidden
// we can reset full-screen state in the remaining visible full-screen documents.
sFullScreenRootDoc = do_GetWeakReference(nsContentUtils::GetRootDocument(this));
@ -8920,6 +8874,8 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
changed.AppendElement(parent);
child = parent;
} else {
NS_ASSERTION(!commonAncestor || child == commonAncestor,
"Should finish loop at common ancestor (or null)");
// We've reached either the root, or a point in the doctree where the
// new full-screen element container is the same as the previous
// full-screen element's container. No more changes need to be made
@ -9032,6 +8988,10 @@ nsDocument::IsFullScreenEnabled(bool aCallerIsChrome, bool aLogFailure)
LogFullScreenDenied(aLogFailure, "FullScreenDeniedDisabled", this);
return false;
}
if (nsContentUtils::HasPluginWithUncontrolledEventDispatch(this)) {
LogFullScreenDenied(aLogFailure, "FullScreenDeniedPlugins", this);
return false;
}
if (!IsVisible()) {
LogFullScreenDenied(aLogFailure, "FullScreenDeniedHidden", this);
return false;

View File

@ -290,6 +290,20 @@ nsHTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, start));
}
#ifndef XP_MACOSX
if (aDocument &&
aDocument->IsFullScreenDoc() &&
nsContentUtils::HasPluginWithUncontrolledEventDispatch(this)) {
// This content contains a windowed plugin for which we don't control
// event dispatch, and we're in full-screen mode. Exit full-screen mode
// to prevent phishing attacks.
nsIDocument::ExitFullScreen(true);
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
"DOM", aDocument,
nsContentUtils::eDOM_PROPERTIES,
"AddedWindowedPluginWhileFullScreen");
}
#endif
return NS_OK;
}

View File

@ -23,12 +23,11 @@ Test plugins with DOM full-screen API:
</head>
<body onload="scheduleTest();">
<!-- Windowed plugin, focusing should revoke full-screen. -->
<!-- Windowed plugin, should prevent first full-screen request. -->
<embed id="windowed-plugin" type="application/x-test" style="width:200px;height:100px;" wmode="window"></embed>
<!-- Windowless plugin, focusing should not revoke full-screen. -->
<embed id="windowless-plugin" type="application/x-test" style="width:200px;height:100px;"></embed>
<!-- Windowless plugin, should not prevent full-screen requests. -->
<embed type="application/x-test" style="width:200px;height:100px;"></embed>
<!-- iframe contents:
@ -51,12 +50,10 @@ function is(a, b, msg) {
opener.is(a, b, "[plugins] " + msg);
}
function e(id) {
return document.getElementById(id);
}
const isMacOs = navigator.appVersion.indexOf("Macintosh") != -1;
document.addEventListener("mozfullscreenchange", isMacOs ? macFullScreenChange : fullScreenChange, false);
var windowedPlugin = null;
function scheduleTest() {
@ -73,14 +70,9 @@ function startTest() {
ok(!document.mozFullScreen, "Should not be in full-screen mode initially");
document.body.mozRequestFullScreen();
// Focus the windowed plugin. On MacOS we should still enter full-screen mode,
// on windows the pending request for full-screen should be denied.
e("windowed-plugin").focus();
if (isMacOs) {
// Running on MacOS, all plugins are effectively windowless, request for full-screen should be granted.
// Continue test in the (mac-specific) "mozfullscreenchange" handler.
document.addEventListener("mozfullscreenchange", macFullScreenChange, false);
return;
} else {
// Non-MacOS, request should be denied, carry on the test after receiving error event.
@ -90,25 +82,24 @@ function startTest() {
function nonMacTest() {
document.removeEventListener("mozfullscreenerror", nonMacTest, false);
ok(!document.mozFullScreen, "Request for full-screen with focused windowed plugin should be denied.");
ok(!document.mozFullScreen, "Request for full-screen from a document containing windowed plugin should be denied.");
// Focus a regular html element, and re-request full-screen, request should be granted.
e("windowless-plugin").focus();
document.addEventListener("mozfullscreenchange", nonMacTest2, false);
// 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("mozfullscreenchange", nonMacTest2, false);
ok(document.mozFullScreen, "Request for full-screen with non-plugin focused should be granted.");
// Focus a windowed plugin, full-screen should be revoked.
document.addEventListener("mozfullscreenchange", nonMacTest3, false);
e("windowed-plugin").focus();
}
function nonMacTest3() {
ok(!document.mozFullScreen, "Full-screen should have been revoked when windowed-plugin was focused.");
opener.nextTest();
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.
var f = document.getElementById("subdoc-plugin");
f.parentNode.removeChild(f);
document.body.mozRequestFullScreen();
}
var fullScreenChangeCount = 0;
@ -123,18 +114,15 @@ function createWindowedPlugin() {
function macFullScreenChange(event) {
switch (fullScreenChangeCount) {
case 0: {
ok(document.mozFullScreen, "Requests for full-screen with focused windowed plugins should be granted on MacOS");
ok(document.mozFullScreen, "Requests for full-screen on pages with plugins should be granted on MacOS");
// Create a new windowed plugin, and add that to the document. Should *not* exit full-screen mode on MacOS.
windowedPlugin = createWindowedPlugin();
document.body.appendChild(windowedPlugin);
// Focus windowed plugin. Should not exit full-screen mode on MacOS.
windowedPlugin.focus();
setTimeout(
function() {
ok(document.mozFullScreen, "Adding & focusing a windowed plugin to document should not cause full-screen to exit on MacOS.");
ok(document.mozFullScreen, "Adding windowed plugin to document should not cause full-screen to exit on MacOS.");
document.mozCancelFullScreen();
}, 0);
@ -152,6 +140,52 @@ function macFullScreenChange(event) {
fullScreenChangeCount++;
}
function fullScreenChange(event) {
switch (fullScreenChangeCount) {
case 0: {
ok(document.mozFullScreen, "Request for full-screen with document containing windowless plugin should be granted");
is(document.mozFullScreenElement, document.body, "FSE should be body.");
// Add windowed plugin to document, should cause full-screen mode to exit.
document.body.appendChild(windowedPlugin);
break;
}
case 1: {
ok(!document.mozFullScreen, "Should have left full-screen mode after re-adding windowed plugin to document");
windowedPlugin.parentNode.removeChild(windowedPlugin);
document.body.mozRequestFullScreen();
break;
}
case 2: {
ok(document.mozFullScreen, "Should have reentered full-screen mode");
// Create a new windowed plugin, and add that to the document. Should exit full-screen mode.
windowedPlugin = createWindowedPlugin();
document.body.appendChild(windowedPlugin);
break;
}
case 3: {
ok(!document.mozFullScreen, "Should have left full-screen mode after adding windowed plugin created after going full-screen to document");
windowedPlugin.parentNode.removeChild(windowedPlugin);
windowedPlugin = createWindowedPlugin();
document.body.mozRequestFullScreen();
break;
}
case 4: {
ok(document.mozFullScreen, "Should have (again) reentered full-screen mode");
document.body.appendChild(windowedPlugin);
break;
}
case 5: {
ok(!document.mozFullScreen, "Should have left full-screen mode after adding windowed plugin created before going full-screen to document");
opener.nextTest();
break;
}
default: {
ok(false, "Should not receive any more fullscreenchange events!");
}
}
fullScreenChangeCount++;
}
</script>
</pre>
</body>

View File

@ -83,7 +83,6 @@
#include "mozAutoDocUpdate.h"
#include "mozilla/Preferences.h"
#include "mozilla/LookAndFeel.h"
#include "nsIScriptError.h"
#ifdef MOZ_XUL
#include "nsIDOMXULTextboxElement.h"
@ -1184,25 +1183,6 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, PRInt32 aFlags,
isElementInActiveWindow, isElementInFocusedWindow);
#endif
// Exit full-screen if we're focusing a windowed plugin on a non-MacOSX
// system. We don't control event dispatch to windowed plugins on non-MacOSX,
// so we can't display the "Press ESC to leave full-screen mode" warning on
// key input if a windowed plugin is focused, so just exit full-screen
// to guard against phishing.
#ifndef XP_MACOSX
if (contentToFocus &&
nsContentUtils::GetRootDocument(contentToFocus->OwnerDoc())->IsFullScreenDoc() &&
nsContentUtils::HasPluginWithUncontrolledEventDispatch(contentToFocus)) {
nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
"FocusedWindowedPluginWhileFullScreen",
nsnull, 0, nsnull,
EmptyString(), 0, 0,
nsIScriptError::warningFlag,
"DOM", contentToFocus->OwnerDoc());
nsIDocument::ExitFullScreen(true);
}
#endif
// if the FLAG_NOSWITCHFRAME flag is used, only allow the focus to be
// shifted away from the current element if the new shell to focus is
// the same or an ancestor shell of the currently focused shell.

View File

@ -118,7 +118,7 @@ GlobalStorageWarning=Use of globalStorage is deprecated. Please use localStorage
# LOCALIZATION NOTE: Do not translate "MozBeforePaint" and "mozRequestAnimationFrame"
MozBeforePaintWarning=MozBeforePaint events are no longer supported. mozRequestAnimationFrame must be passed a non-null callback argument.
FullScreenDeniedDisabled=Request for full-screen was denied because full-screen API is disabled by user preference.
FullScreenDeniedFocusedPlugin=Request for full-screen was denied because a windowed plugin is focused.
FullScreenDeniedPlugins=Request for full-screen was denied because a document on this page contains a windowed plugin.
FullScreenDeniedHidden=Request for full-screen was denied because the document is no longer visible.
FullScreenDeniedIframeDisallowed=Request for full-screen was denied because at least one of the document's containing iframes does not have a "mozallowfullscreen" attribute.
FullScreenDeniedNotInputDriven=Request for full-screen was denied because Element.mozRequestFullScreen() was not called from inside a short running user-generated event handler.
@ -127,9 +127,8 @@ FullScreenDeniedMovedDocument=Request for full-screen was denied because request
FullScreenDeniedLostWindow=Request for full-screen was denied because we no longer have a window.
FullScreenDeniedSubDocFullScreen=Request for full-screen was denied because a subdocument of the document requesting full-screen is already full-screen.
FullScreenDeniedNotDescendant=Request for full-screen was denied because requesting element is not a descendant of the current full-screen element.
FullScreenDeniedNotFocusedTab=Request for full-screen was denied because requesting element is not in the currently focused tab.
RemovedFullScreenElement=Exited full-screen because full-screen element was removed from document.
FocusedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was focused.
AddedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was added to document.
HTMLMultipartXHRWarning=HTML parsing in XMLHttpRequest is not supported for multipart responses.
HTMLSyncXHRWarning=HTML parsing in XMLHttpRequest is not supported in the synchronous mode.
InvalidRedirectChannelWarning=Unable to redirect to %S because the channel doesn't implement nsIWritablePropertyBag2.

View File

@ -3311,6 +3311,11 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
bool windowless = false;
mInstance->IsWindowless(&windowless);
nsIDocument *doc = mContent ? mContent->OwnerDoc() : nsnull;
#ifndef XP_MACOSX
if (!windowless && doc && doc->IsFullScreenDoc()) {
nsIDocument::ExitFullScreen(true);
}
#endif
// always create widgets in Twips, not pixels
nsPresContext* context = mObjectFrame->PresContext();
rv = mObjectFrame->CreateWidget(context->DevPixelsToAppUnits(mPluginWindow->width),

View File

@ -8,7 +8,6 @@
<script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"><![CDATA[
// List of key codes, and whether they should cause a warning in full-screen mode.
@ -246,12 +245,9 @@ window.addEventListener("keyup", keyHandler, true);
window.addEventListener("keypress", keyHandler, true);
function start() {
SimpleTest.waitForFocus(
function() {
gBrowser = document.getElementById("browser");
gBrowser.contentDocument.body.mozRequestFullScreen();
setTimeout(startNextTest, 0);
});
gBrowser = document.getElementById("browser");
gBrowser.contentDocument.body.mozRequestFullScreen();
setTimeout(startNextTest, 0);
}
]]>

View File

@ -6,7 +6,8 @@
-->
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" width="400" height="400">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script>
SimpleTest.waitForExplicitFinish();