Bug 706672 - Revoke DOM full-screen when windowed plugin focused on non-MacOSX systems, and deny requests for full-screen from non-focused-tab documents. r=smaug
authorChris Pearce <chris@pearce.org.nz>
Fri, 16 Dec 2011 10:42:36 +1300
changeset 84563 9e986b4770c83366719f4b547388d8f3e5e6999a
parent 84562 8288419ba59130ff2ccfddb2e42f7b0728a443e6
child 84564 cbe10cc8c21974258a0f6ee0c1d400ed562b2408
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs706672
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 706672 - Revoke DOM full-screen when windowed plugin focused on non-MacOSX systems, and deny requests for full-screen from non-focused-tab documents. r=smaug
content/base/src/nsDocument.cpp
content/html/content/src/nsHTMLSharedObjectElement.cpp
content/html/content/test/file_fullscreen-plugins.html
dom/base/nsFocusManager.cpp
dom/locales/en-US/chrome/dom/dom.properties
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/tests/mochitest/chrome/dom_fullscreen_warning.xul
dom/tests/mochitest/chrome/test_dom_fullscreen_warning.xul
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -8622,50 +8622,16 @@ nsDocument::RestorePreviousFullScreenSta
 }
 
 bool
 nsDocument::IsFullScreenDoc()
 {
   return GetFullScreenElement() != nsnull;
 }
 
-static nsIDocument*
-GetCommonAncestor(nsIDocument* aDoc1, nsIDocument* aDoc2)
-{
-  if (!aDoc1 || !aDoc2) {
-    return nsnull;
-  }
-  nsIDocument* doc1 = aDoc1;
-  nsIDocument* doc2 = aDoc2;
-
-  nsAutoTArray<nsIDocument*, 30> parents1, parents2;
-  do {
-    parents1.AppendElement(doc1);
-    doc1 = doc1->GetParentDocument();
-  } while (doc1);
-  do {
-    parents2.AppendElement(doc2);
-    doc2 = doc2->GetParentDocument();
-  } while (doc2);
-
-  PRUint32 pos1 = parents1.Length();
-  PRUint32 pos2 = parents2.Length();
-  nsIDocument* parent = nsnull;
-  PRUint32 len;
-  for (len = NS_MIN(pos1, pos2); len > 0; --len) {
-    nsIDocument* child1 = parents1.ElementAt(--pos1);
-    nsIDocument* child2 = parents2.ElementAt(--pos2);
-    if (child1 != child2) {
-      break;
-    }
-    parent = child1;
-  }
-  return parent;
-}
-
 class nsCallRequestFullScreen : public nsRunnable
 {
 public:
   nsCallRequestFullScreen(Element* aElement)
     : mElement(aElement),
       mDoc(aElement->OwnerDoc()),
       mWasCallerChrome(nsContentUtils::IsCallerChrome())
   {
@@ -8796,16 +8762,60 @@ nsDocument::FullScreenStackTop()
   PRUint32 last = mFullScreenStack.Length() - 1;
   nsCOMPtr<Element> element(do_QueryReferent(mFullScreenStack[last]));
   NS_ASSERTION(element, "Should have full-screen element!");
   NS_ASSERTION(element->IsInDoc(), "Full-screen element should be in doc");
   NS_ASSERTION(element->OwnerDoc() == this, "Full-screen element should be in this doc");
   return element;
 }
 
+// Returns true if aDoc is in the focused tab in the active window.
+static bool
+IsInActiveTab(nsIDocument* aDoc)
+{
+  nsCOMPtr<nsISupports> container = aDoc->GetContainer();
+  nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(container);
+  if (!docshell) {
+    return false;
+  }
+
+  bool isActive = false;
+  docshell->GetIsActive(&isActive);
+  if (!isActive) {
+    return false;
+  }
+  
+  nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(container);
+  if (!dsti) {
+    return false;
+  }
+  nsCOMPtr<nsIDocShellTreeItem> rootItem;
+  dsti->GetRootTreeItem(getter_AddRefs(rootItem));
+  if (!rootItem) {
+    return false;
+  }
+  nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(rootItem);
+  if (!rootWin) {
+    return false;
+  }
+
+  nsIFocusManager* fm = nsFocusManager::GetFocusManager();
+  if (!fm) {
+    return false;
+  }
+
+  nsCOMPtr<nsIDOMWindow> activeWindow;
+  fm->GetActiveWindow(getter_AddRefs(activeWindow));
+  if (!activeWindow) {
+    return false;
+  }
+
+  return activeWindow == rootWin;
+}
+
 void
 nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
 {
   NS_ASSERTION(aElement,
     "Must pass non-null element to nsDocument::RequestFullScreen");
   if (!aElement || aElement == GetFullScreenElement()) {
     return;
   }
@@ -8827,34 +8837,43 @@ nsDocument::RequestFullScreen(Element* a
   }
   if (GetFullScreenElement() &&
       !nsContentUtils::ContentIsDescendantOf(aElement, GetFullScreenElement())) {
     // If this document is full-screen, only grant full-screen requests from 
     // a descendent of the current full-screen element.
     LogFullScreenDenied(true, "FullScreenDeniedNotDescendant", this);
     return;
   }
+  if (!nsContentUtils::IsChromeDoc(this) && !IsInActiveTab(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
   // order, but we traverse the doctree in a leaf-to-root order, so we save
   // references to the documents we must dispatch to so that we get the order
   // 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));
 
   // Set the full-screen element. This sets the full-screen style on the
   // element, and the full-screen-ancestor styles on ancestors of the element
   // in this document.
   DebugOnly<bool> x = FullScreenStackPush(aElement);
@@ -8869,18 +8888,16 @@ nsDocument::RequestFullScreen(Element* a
   nsIDocument* child = this;
   nsIDocument* parent;
   while ((parent = child->GetParentDocument())) {
     Element* element = parent->FindContentForSubDocument(child)->AsElement();
     if (static_cast<nsDocument*>(parent)->FullScreenStackPush(element)) {
       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
       // to the full-screen stacks of documents further up the tree.
       break;
     }
   }
 
@@ -8983,20 +9000,16 @@ nsDocument::IsFullScreenEnabled(bool aCa
     // nsRunnable!
     return true;
   }
 
   if (!nsContentUtils::IsFullScreenApiEnabled()) {
     LogFullScreenDenied(aLogFailure, "FullScreenDeniedDisabled", this);
     return false;
   }
-  if (nsContentUtils::HasPluginWithUncontrolledEventDispatch(this)) {
-    LogFullScreenDenied(aLogFailure, "FullScreenDeniedPlugins", this);
-    return false;
-  }
   if (!IsVisible()) {
     LogFullScreenDenied(aLogFailure, "FullScreenDeniedHidden", this);
     return false;
   }
   if (HasFullScreenSubDocument(this)) {
     LogFullScreenDenied(aLogFailure, "FullScreenDeniedSubDocFullScreen", this);
     return false;
   }
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -285,30 +285,16 @@ nsHTMLSharedObjectElement::BindToTree(ns
 
   // If we already have all the children, start the load.
   if (mIsDoneAddingChildren) {
     void (nsHTMLSharedObjectElement::*start)() =
       &nsHTMLSharedObjectElement::StartObjectLoad;
     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;
 }
 
 void
 nsHTMLSharedObjectElement::UnbindFromTree(bool aDeep,
                                           bool aNullParent)
 {
   RemovedFromDocument();
--- a/content/html/content/test/file_fullscreen-plugins.html
+++ b/content/html/content/test/file_fullscreen-plugins.html
@@ -18,21 +18,22 @@ Test plugins with DOM full-screen API:
   <style>
   body:-moz-full-screen, div:-moz-full-screen {
     background-color: red;
   }
   </style>
 </head>
 <body onload="scheduleTest();">
 
-<!-- Windowed plugin, should prevent first full-screen request. -->
+
+<!-- Windowed plugin, focusing should revoke full-screen. -->
 <embed id="windowed-plugin" type="application/x-test" style="width:200px;height:100px;" wmode="window"></embed>
 
-<!-- Windowless plugin, should not prevent full-screen requests. -->
-<embed type="application/x-test" style="width:200px;height:100px;"></embed>
+<!-- Windowless plugin, focusing should not revoke full-screen. -->
+<embed id="windowless-plugin" type="application/x-test" style="width:200px;height:100px;"></embed>
 
 
 <!-- iframe contents:
 
 <html><body><embed id='windowed-plugin' type='application/x-test' style='width:200px;height:100px;' wmode='window'></embed></body></html>
 
 -->
 
@@ -45,19 +46,21 @@ Test plugins with DOM full-screen API:
 function ok(condition, msg) {
   opener.ok(condition, "[plugins] " + msg);
 }
 
 function is(a, b, msg) {
   opener.is(a, b, "[plugins] " + msg);
 }
 
-const isMacOs = navigator.appVersion.indexOf("Macintosh") != -1;
+function e(id) {
+  return document.getElementById(id);
+}
 
-document.addEventListener("mozfullscreenchange", isMacOs ? macFullScreenChange : fullScreenChange, false);
+const isMacOs = navigator.appVersion.indexOf("Macintosh") != -1;
 
 var windowedPlugin = null;
 
 function scheduleTest() {
   // Delay test startup long enough for the windowed plugin in the subframe to
   // start up and create its window.
   opener.SimpleTest.executeSoon(function() {
     opener.SimpleTest.executeSoon(function() {
@@ -65,69 +68,78 @@ function scheduleTest() {
     })
   });
 }
 
 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.
     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.");
+  ok(!document.mozFullScreen, "Request for full-screen with focused 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);
+  // Focus a regular html element, and re-request full-screen, request should be granted.
+  e("windowless-plugin").focus();
+  document.addEventListener("mozfullscreenchange", 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.
-  var f = document.getElementById("subdoc-plugin");
-  f.parentNode.removeChild(f);
-  document.body.mozRequestFullScreen();
+  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();
 }
 
 var fullScreenChangeCount = 0;
 
 function createWindowedPlugin() {
   var p = document.createElement("embed");
   p.setAttribute("type", "application/x-test");
   p.setAttribute("wmode", "window");
   return p;
 }
 
 function macFullScreenChange(event) {
   switch (fullScreenChangeCount) {
     case 0: {
-      ok(document.mozFullScreen, "Requests for full-screen on pages with plugins should be granted on MacOS");
+      ok(document.mozFullScreen, "Requests for full-screen with focused windowed 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 windowed plugin to document should not cause full-screen to exit on MacOS.");
+          ok(document.mozFullScreen, "Adding & focusing a windowed plugin to document should not cause full-screen to exit on MacOS.");
           document.mozCancelFullScreen();
         }, 0);
           
       break;
     }
     case 1: {
       ok(!document.mozFullScreen, "Should have left full-screen mode after calling document.mozCancelFullScreen().");
       opener.nextTest();
@@ -135,58 +147,12 @@ function macFullScreenChange(event) {
     }
     default: {
       ok(false, "Should not receive any more fullscreenchange events!");
     }
   }
   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>
 </html>
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -78,16 +78,17 @@
 #include "nsXULPopupManager.h"
 #include "nsIDOMNodeFilter.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIPrincipal.h"
 #include "mozilla/dom/Element.h"
 #include "mozAutoDocUpdate.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
+#include "nsIScriptError.h"
 
 #ifdef MOZ_XUL
 #include "nsIDOMXULTextboxElement.h"
 #include "nsIDOMXULMenuListElement.h"
 #endif
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
@@ -1178,16 +1179,34 @@ nsFocusManager::SetFocusInner(nsIContent
 #ifdef DEBUG_FOCUS
   PRINTTAGF("Shift Focus: %s", contentToFocus);
   printf(" Flags: %x Current Window: %p New Window: %p Current Element: %p",
          aFlags, mFocusedWindow.get(), newWindow.get(), mFocusedContent.get());
   printf(" In Active Window: %d In Focused Window: %d\n",
          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(nsIScriptError::warningFlag,
+                                    "DOM",
+                                    contentToFocus->OwnerDoc(),
+                                    nsContentUtils::eDOM_PROPERTIES,
+                                    "FocusedWindowedPluginWhileFullScreen");
+    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.
   bool allowFrameSwitch = !(aFlags & FLAG_NOSWITCHFRAME) ||
                             IsSameOrAncestor(newWindow, mFocusedWindow);
 
   // if the element is in the active window, frame switching is allowed and
   // the content is in a visible window, fire blur and focus events.
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -113,25 +113,26 @@ TotalSizeWarning=Use of XMLHttpRequest's
 nsIJSONDecodeDeprecatedWarning=nsIJSON.decode is deprecated.  Please use JSON.parse instead.
 nsIJSONEncodeDeprecatedWarning=nsIJSON.encode is deprecated.  Please use JSON.stringify instead.
 nsIDOMWindowInternalWarning=Use of nsIDOMWindowInternal is deprecated. Use nsIDOMWindow instead.
 InputEncodingWarning=Use of inputEncoding is deprecated.
 GlobalStorageWarning=Use of globalStorage is deprecated. Please use localStorage instead.
 # 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.
-FullScreenDeniedPlugins=Request for full-screen was denied because a document on this page contains a windowed plugin.
+FullScreenDeniedFocusedPlugin=Request for full-screen was denied because a windowed plugin is focused.
 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.
 FullScreenDeniedNotInDocument=Request for full-screen was denied because requesting element is no longer in its document.
 FullScreenDeniedMovedDocument=Request for full-screen was denied because requesting element has moved document.
 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.
-AddedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was added to document.
+FocusedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was focused.
 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.
 ResponseTypeSyncXHRWarning=Use of XMLHttpRequest's responseType attribute is no longer supported in the synchronous mode in window context.
 WithCredentialsSyncXHRWarning=Use of XMLHttpRequest's withCredentials attribute is no longer supported in the synchronous mode in window context.
 JSONCharsetWarning=An attempt was made to declare a non-UTF-8 encoding for JSON retrieved using XMLHttpRequest. Only UTF-8 is supported for decoding JSON.
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -3306,21 +3306,16 @@ NS_IMETHODIMP nsPluginInstanceOwner::Cre
 
   nsresult  rv = NS_ERROR_FAILURE;
 
   if (mObjectFrame) {
     if (!mWidget) {
       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),
                                       context->DevPixelsToAppUnits(mPluginWindow->height),
                                       windowless);
       if (NS_OK == rv) {
         mWidget = mObjectFrame->GetWidget();
 
--- a/dom/tests/mochitest/chrome/dom_fullscreen_warning.xul
+++ b/dom/tests/mochitest/chrome/dom_fullscreen_warning.xul
@@ -3,16 +3,17 @@
 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
 <!--
   Test that "MozShowFullScreenWarning" is dispatched to chrome on restricted keypress.
 -->
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="start();">
 
 <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.
 var keyList = [
   // Allowed: DOM_VK_CANCEL to DOM_VK_CAPS_LOCK, inclusive
   { code: "VK_CANCEL",        warn: true},
   { code: "VK_HELP",          warn: true},
   { code: "VK_BACK_SPACE",    warn: true},
@@ -240,19 +241,23 @@ function keyHandler(event) {
 
 window.addEventListener("MozShowFullScreenWarning", function(){ gWarningEventReceived = true; }, true);
 
 window.addEventListener("keydown", keyHandler, true);
 window.addEventListener("keyup", keyHandler, true);
 window.addEventListener("keypress", keyHandler, true);
 
 function start() {
-  gBrowser = document.getElementById("browser");
-  gBrowser.contentDocument.body.mozRequestFullScreen();
-  setTimeout(startNextTest, 0);
+  SimpleTest.waitForFocus(
+    function() {
+      gBrowser = document.getElementById("browser");
+      gBrowser.contentWindow.focus();
+      gBrowser.contentDocument.body.mozRequestFullScreen();
+      setTimeout(startNextTest, 0);
+    });
 }
 
 ]]>
 </script>
 
 <browser type="content" id="browser" width="400" height="400"/>
 
 </window>
--- a/dom/tests/mochitest/chrome/test_dom_fullscreen_warning.xul
+++ b/dom/tests/mochitest/chrome/test_dom_fullscreen_warning.xul
@@ -1,18 +1,17 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
 <!--
   Test that "MozShowFullScreenWarning" is dispatched to chrome on restricted keypress.
   -->
 <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();
 
 // Ensure the full-screen api is enabled, and will be disabled on test exit.
 var gPrevEnabled = SpecialPowers.getBoolPref("full-screen-api.enabled");
 SpecialPowers.setBoolPref("full-screen-api.enabled", true);