Bug 694204 - Prevent default action on ESC key press to exit full-screen mode, prevents <video> loads being cancelled on full-screen exit. r=smaug
authorChris Pearce <chris@pearce.org.nz>
Tue, 01 Nov 2011 18:11:29 +1300
changeset 79499 ddad75e027ab1e450db0af4aa83fa3a9bfabb122
parent 79498 b72b2c0f996f88d37996e6f53fc24c895fafca25
child 79500 e269b5ec522ab66f582525017579e2ad1ae78a9a
push id21408
push userkhuey@mozilla.com
push dateTue, 01 Nov 2011 14:32:20 +0000
treeherdermozilla-central@cd9add22f090 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs694204
milestone10.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 694204 - Prevent default action on ESC key press to exit full-screen mode, prevents <video> loads being cancelled on full-screen exit. r=smaug
content/html/content/test/file_fullscreen-api-keys.html
layout/base/nsPresShell.cpp
--- a/content/html/content/test/file_fullscreen-api-keys.html
+++ b/content/html/content/test/file_fullscreen-api-keys.html
@@ -38,17 +38,17 @@ var keyList = [
   { code: "VK_CAPS_LOCK",     allowed: true},
 
   { code: "VK_KANA",          allowed: false},
   { code: "VK_HANGUL",        allowed: false},
   { code: "VK_JUNJA",         allowed: false},
   { code: "VK_FINAL",         allowed: false},
   { code: "VK_HANJA",         allowed: false},
   { code: "VK_KANJI",         allowed: false},
-  { code: "VK_ESCAPE",        allowed: false},
+  { code: "VK_ESCAPE",        allowed: false, suppressed: true},
   { code: "VK_CONVERT",       allowed: false},
   { code: "VK_NONCONVERT",    allowed: false},
   { code: "VK_ACCEPT",        allowed: false},
   { code: "VK_MODECHANGE",    allowed: false},
 
   // Allowed: DOM_VK_SPACE to DOM_VK_DELETE, inclusive
   { code: "VK_SPACE",         allowed: true},
   { code: "VK_PAGE_UP",       allowed: true},
@@ -171,24 +171,26 @@ function ok(condition, msg) {
 function is(a, b, msg) {
   opener.is(a, b, msg);
 }
 
 var gKeyTestIndex = 0;
 var gKeyName;
 var gKeyCode;
 var gKeyAllowed;
+var gKeySuppressed;
 var gKeyReceived = false;
 
 function keyHandler(event) {
-  event.preventDefault()
+  event.preventDefault();
   gKeyReceived = true;
 }
 
 function checkKeyEffect() {
+  is(gKeySuppressed, !gKeyReceived, "Should not receive suppressed key events");
   is(document.mozFullScreen, gKeyAllowed,
      (gKeyAllowed ? ("Should remain in full-screen mode for allowed key press " + gKeyName)
                   : ("Should drop out of full-screen mode for restricted key press " + gKeyName)));
 
   if (gKeyTestIndex < keyList.length) {
     setTimeout(testNextKey, 0);
   } else {
     document.mozCancelFullScreen();
@@ -234,16 +236,18 @@ function testNextKey() {
   if (!document.mozFullScreen) {
     document.body.mozRequestFullScreen();
   }
   ok(document.mozFullScreen, "Must be in full-screen mode");
 
   gKeyName = keyList[gKeyTestIndex].code;
   gKeyCode = KeyEvent["DOM_" + gKeyName];
   gKeyAllowed = keyList[gKeyTestIndex].allowed;
+  gKeySuppressed = (keyList[gKeyTestIndex].suppressed != undefined) ?
+                    keyList[gKeyTestIndex].suppressed : false;
   gKeyTestIndex++;
 
   testScriptInitiatedKeyEvents();
   testTrustedKeyEvents();
 }
 
 window.addEventListener("keydown", keyHandler, true);
 window.addEventListener("keyup", keyHandler, true);
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -6339,27 +6339,40 @@ PresShell::HandleEventInternal(nsEvent* 
   if (!NS_EVENT_NEEDS_FRAME(aEvent) || GetCurrentEventFrame()) {
     bool isHandlingUserInput = false;
 
     // XXX How about IME events and input events for plugins?
     if (NS_IS_TRUSTED_EVENT(aEvent)) {
       switch (aEvent->message) {
       case NS_KEY_PRESS:
       case NS_KEY_DOWN:
-      case NS_KEY_UP:
+      case NS_KEY_UP: {
         if (IsFullScreenAndRestrictedKeyEvent(mCurrentEventContent, aEvent) &&
-            aEvent->message == NS_KEY_DOWN) {
+            aEvent->message == NS_KEY_UP) {
           // We're in DOM full-screen mode, and a key with a restricted key
           // code has been pressed. Exit full-screen mode.
           NS_DispatchToCurrentThread(
             NS_NewRunnableMethod(mCurrentEventContent->OwnerDoc(),
                                  &nsIDocument::CancelFullScreen));
         }
+        nsIDocument *doc = mCurrentEventContent ?
+                           mCurrentEventContent->OwnerDoc() : nsnull;
+        if (doc &&
+            doc->IsFullScreenDoc() &&
+            static_cast<const nsKeyEvent*>(aEvent)->keyCode == NS_VK_ESCAPE) {
+          // Prevent default action on ESC key press when exiting
+          // DOM full-screen mode. This prevents the browser ESC key
+          // handler from stopping all loads in the document, which
+          // would cause <video> loads to stop.
+          aEvent->flags |= (NS_EVENT_FLAG_NO_DEFAULT |
+                            NS_EVENT_FLAG_ONLY_CHROME_DISPATCH);
+        }
         // Else not full-screen mode or key code is unrestricted, fall
         // through to normal handling.
+      }
       case NS_MOUSE_BUTTON_DOWN:
       case NS_MOUSE_BUTTON_UP:
         isHandlingUserInput = true;
         break;
       case NS_DRAGDROP_DROP:
         nsCOMPtr<nsIDragSession> session = nsContentUtils::GetDragSession();
         if (session) {
           bool onlyChromeDrop = false;