Bug 730434 - remove 'home' event and other non-standard event types r=fabrice
authorVivien Nicolas <21@vingtetun.org>
Thu, 01 Mar 2012 17:04:00 +0100
changeset 88097 bef026927a580b819879b8c9e534df97061d150e
parent 88096 41205fe435777a75a89b120a05fb12051c6dbd7f
child 88098 1f3c7742021ceb560f19fdb2c9aef3da8ebed5da
push id22171
push usermak77@bonardo.net
push dateFri, 02 Mar 2012 13:56:30 +0000
treeherdermozilla-central@343ec916dfd5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice
bugs730434
milestone13.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 730434 - remove 'home' event and other non-standard event types r=fabrice
b2g/chrome/content/commandUtil.js
b2g/chrome/content/shell.js
b2g/chrome/content/shell.xul
b2g/chrome/jar.mn
deleted file mode 100644
--- a/b2g/chrome/content/commandUtil.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- * Command Updater
- */
-let CommandUpdater = {
-  /**
-   * Gets a controller that can handle a particular command.
-   * @param {string} command
-   *        A command to locate a controller for, preferring controllers that
-   *        show the command as enabled.
-   * @return {object} In this order of precedence:
-   *            - the first controller supporting the specified command
-   *              associated with the focused element that advertises the
-   *              command as ENABLED.
-   *            - the first controller supporting the specified command
-   *              associated with the global window that advertises the
-   *              command as ENABLED.
-   *            - the first controller supporting the specified command
-   *              associated with the focused element.
-   *            - the first controller supporting the specified command
-   *              associated with the global window.
-   */
-  _getControllerForCommand: function(command) {
-    try {
-      let commandDispatcher = top.document.commandDispatcher;
-      let controller = commandDispatcher.getControllerForCommand(command);
-      if (controller && controller.isCommandEnabled(command))
-        return controller;
-    }
-    catch (e) { }
-
-    let controllerCount = window.controllers.getControllerCount();
-    for (let i = 0; i < controllerCount; ++i) {
-      let current = window.controllers.getControllerAt(i);
-      try {
-        if (current.supportsCommand(command) &&
-            current.isCommandEnabled(command))
-          return current;
-      }
-      catch (e) { }
-    }
-    return controller || window.controllers.getControllerForCommand(command);
-  },
-
-  /**
-   * Updates the state of a XUL <command> element for the specified command
-   * depending on its state.
-   * @param {string} command
-   *        The name of the command to update the XUL <command> element for.
-   */
-  updateCommand: function(command) {
-    let enabled = false;
-    try {
-      let controller = this._getControllerForCommand(command);
-      if (controller) {
-        enabled = controller.isCommandEnabled(command);
-      }
-    }
-    catch (ex) { }
-
-    this.enableCommand(command, enabled);
-  },
-
-  /**
-   * Updates the state of a XUL <command> element for the specified command
-   * depending on its state.
-   * @param {string} command
-   *        The name of the command to update the XUL <command> element for.
-   */
-  updateCommands: function(_commands) {
-    let commands = _commands.split(',');
-    for (let command in commands) {
-      this.updateCommand(commands[command]);
-    }
-  },
-
-  /**
-   * Enables or disables a XUL <command> element.
-   * @param {string} command
-   *          The name of the command to enable or disable.
-   * @param {bool} enabled
-   *          true if the command should be enabled, false otherwise.
-   */
-  enableCommand: function(command, enabled) {
-    let element = document.getElementById(command);
-    if (!element)
-      return;
-
-    if (enabled)
-      element.removeAttribute('disabled');
-    else
-      element.setAttribute('disabled', 'true');
-  },
-
-  /**
-   * Performs the action associated with a specified command using the most
-   * relevant controller.
-   * @param {string} command
-   *          The command to perform.
-   */
-  doCommand: function(command) {
-    let controller = this._getControllerForCommand(command);
-    if (!controller)
-      return;
-    controller.doCommand(command);
-  },
-
-  /**
-   * Changes the label attribute for the specified command.
-   * @param {string} command
-   *          The command to update.
-   * @param {string} labelAttribute
-   *          The label value to use.
-   */
-  setMenuValue: function(command, labelAttribute) {
-    let commandNode = top.document.getElementById(command);
-    if (commandNode) {
-      let label = commandNode.getAttribute(labelAttribute);
-      if (label)
-        commandNode.setAttribute('label', label);
-    }
-  },
-
-  /**
-   * Changes the accesskey attribute for the specified command.
-   * @param {string} command
-   *          The command to update.
-   * @param {string} valueAttribute
-   *          The value attribute to use.
-   */
-  setAccessKey: function(command, valueAttribute) {
-    let commandNode = top.document.getElementById(command);
-    if (commandNode) {
-      let value = commandNode.getAttribute(valueAttribute);
-      if (value)
-        commandNode.setAttribute('accesskey', value);
-    }
-  },
-
-  /**
-   * Inform all the controllers attached to a node that an event has occurred
-   * (e.g. the tree controllers need to be informed of blur events so that they
-   * can change some of the menu items back to their default values)
-   * @param  {node} node
-   *          The node receiving the event.
-   * @param  {event} event
-   *          The event.
-   */
-  onEvent: function(node, event) {
-    let numControllers = node.controllers.getControllerCount();
-    let controller;
-
-    for (let i = 0; i < numControllers; i++) {
-      controller = node.controllers.getControllerAt(i);
-      if (controller)
-        controller.onEvent(event);
-    }
-  }
-};
-
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -28,22 +28,26 @@ XPCOMUtils.defineLazyGetter(Services, 's
            .getService(Ci.nsIStyleSheetService);
 });
 
 XPCOMUtils.defineLazyGetter(Services, 'idle', function() {
   return Cc['@mozilla.org/widget/idleservice;1']
            .getService(Ci.nsIIdleService);
 });
 
-XPCOMUtils.defineLazyServiceGetter(Services, 'fm', function(){
-  return Cc['@mozilla.org/focus-managr;1']
+XPCOMUtils.defineLazyGetter(Services, 'audioManager', function() {
+  return Cc['@mozilla.org/telephony/audiomanager;1']
+           .getService(Ci.nsIAudioManager);
+});
+
+XPCOMUtils.defineLazyServiceGetter(Services, 'fm', function() {
+  return Cc['@mozilla.org/focus-manager;1']
            .getService(Ci.nsFocusManager);
 });
 
-
 #ifndef MOZ_WIDGET_GONK
 // In order to use http:// scheme instead of file:// scheme
 // (that is much more restricted) the following code kick-off
 // a local http server listening on http://127.0.0.1:7777 and
 // http://localhost:7777.
 function startupHttpd(baseDir, port) {
   const httpdURL = 'chrome://browser/content/httpd.js';
   let httpd = {};
@@ -69,19 +73,16 @@ function addPermissions(urls) {
 
     permissions.forEach(function(permission) {
       Services.perms.add(uri, permission, allow);
     });
   });
 }
 
 var shell = {
-  // FIXME/bug 678695: this should be a system setting
-  preferredScreenBrightness: 1.0,
-  
   isDebug: false,
 
   get contentBrowser() {
     delete this.contentBrowser;
     return this.contentBrowser = document.getElementById('homescreen');
   },
 
   get homeURL() {
@@ -106,23 +107,33 @@ var shell = {
 
   start: function shell_init() {
     let homeURL = this.homeURL;
     if (!homeURL) {
       let msg = 'Fatal error during startup: [No homescreen found]';
       return alert(msg);
     }
 
-    window.controllers.appendController(this);
-    window.addEventListener('keypress', this);
+    ['keydown', 'keypress', 'keyup'].forEach((function listenKey(type) {
+      window.addEventListener(type, this, false, true);
+      window.addEventListener(type, this, true, true);
+    }).bind(this));
+
     window.addEventListener('MozApplicationManifest', this);
-    window.addEventListener("AppCommand", this);
     window.addEventListener('mozfullscreenchange', this);
     this.contentBrowser.addEventListener('load', this, true);
 
+    // Until the volume can be set from the content side, set it to a
+    // a specific value when the device starts. This way the front-end
+    // can display a notification when the volume change and show a volume
+    // level modified from this point.
+    try {
+      Services.audioManager.masterVolume = 0.5;
+    } catch(e) {}
+
     try {
       Services.io.offline = false;
 
       let fileScheme = 'file://';
       if (homeURL.substring(0, fileScheme.length) == fileScheme) {
 #ifndef MOZ_WIDGET_GONK
         homeURL = homeURL.replace(fileScheme, '');
 
@@ -154,128 +165,116 @@ var shell = {
     }
 
     let browser = this.contentBrowser;
     browser.homePage = homeURL;
     browser.goHome();
   },
 
   stop: function shell_stop() {
-    window.controllers.removeController(this);
-    window.removeEventListener('keypress', this);
     window.removeEventListener('MozApplicationManifest', this);
-    window.removeEventListener('AppCommand', this);
-  },
-
-  supportsCommand: function shell_supportsCommand(cmd) {
-    let isSupported = false;
-    switch (cmd) {
-      case 'cmd_close':
-        isSupported = true;
-        break;
-      default:
-        isSupported = false;
-        break;
-    }
-    return isSupported;
-  },
-
-  isCommandEnabled: function shell_isCommandEnabled(cmd) {
-    return true;
-  },
-
-  doCommand: function shell_doCommand(cmd) {
-    switch (cmd) {
-      case 'cmd_close':
-        content.postMessage('appclose', '*');
-        break;
-    }
+    window.removeEventListener('mozfullscreenchange', this);
   },
 
   toggleDebug: function shell_toggleDebug() {
     this.isDebug = !this.isDebug;
 
     if (this.isDebug) {
       Services.prefs.setBoolPref("layers.acceleration.draw-fps", true);
       Services.prefs.setBoolPref("nglayout.debug.paint_flashing", true);
     } else {
       Services.prefs.setBoolPref("layers.acceleration.draw-fps", false);
       Services.prefs.setBoolPref("nglayout.debug.paint_flashing", false);
     }
   },
  
-  changeVolume: function shell_changeVolume(aDelta) {
-    let audioManager = Cc["@mozilla.org/telephony/audiomanager;1"].getService(Ci.nsIAudioManager);
-
+  changeVolume: function shell_changeVolume(delta) {
     let steps = 10;
     try {
       steps = Services.prefs.getIntPref("media.volume.steps");
       if (steps <= 0)
         steps = 1;
     } catch(e) {}
 
-    let volume = audioManager.masterVolume + aDelta / steps;
+    let audioManager = Services.audioManager;
+    if (!audioManager)
+      return;
+
+    let volume = audioManager.masterVolume + delta / steps;
     if (volume > 1)
       volume = 1;
     if (volume < 0)
       volume = 0;
     audioManager.masterVolume = volume;
   },
 
+  forwardKeyToHomescreen: function shell_forwardKeyToHomescreen(evt) {
+    let generatedEvent = content.document.createEvent('KeyboardEvent');
+    generatedEvent.initKeyEvent(evt.type, true, true, evt.view, evt.ctrlKey,
+                                evt.altKey, evt.shiftKey, evt.metaKey,
+                                evt.keyCode, evt.charCode);
+
+    content.dispatchEvent(generatedEvent);
+  },
+
   handleEvent: function shell_handleEvent(evt) {
     switch (evt.type) {
+      case 'keydown':
+      case 'keyup':
       case 'keypress':
-        switch (evt.keyCode) {
-          case evt.DOM_VK_HOME:
-            this.sendEvent(content, 'home');
-            break;
-          case evt.DOM_VK_SLEEP:
-            this.toggleScreen();
+        // If the home key is pressed, always forward it to the homescreen
+        if (evt.eventPhase == evt.CAPTURING_PHASE) {
+          if (evt.keyCode == evt.VK_DOM_HOME) {
+            window.setTimeout(this.forwardKeyToHomescreen, 0, evt);
+            evt.preventDefault();
+            evt.stopPropagation();
+          } 
+          return;
+        }
+
+        // If one of the other keys is used in an application and is
+        // cancelled via preventDefault, do nothing.
+        let homescreen = (evt.target.ownerDocument.defaultView == content);
+        if (!homescreen && evt.defaultPrevented)
+          return;
 
-            let details = {
-              'enabled': screen.mozEnabled
-            };
-            this.sendEvent(content, 'sleep', details);
-            break;
-          case evt.DOM_VK_ESCAPE:
-            if (evt.defaultPrevented)
-              return;
-            this.doCommand('cmd_close');
-            break;
-        }
-        break;
-      case 'AppCommand':
-        switch (evt.command) {
-          case 'Menu':
-            if (Services.prefs.getBoolPref('b2g.keys.menu.enabled'))
-              this.sendEvent(content, 'menu');
-            break;
-          case 'Search':
-            if (Services.prefs.getBoolPref('b2g.keys.search.enabled'))
-              this.toggleDebug();
-            break;
-          case 'VolumeUp':
-            this.changeVolume(1);
-            break;
-          case 'VolumeDown':
-            this.changeVolume(-1);
-            break;
+        // If one of the other keys is used in an application and is
+        // not used forward it to the homescreen
+        if (!homescreen)
+          window.setTimeout(this.forwardKeyToHomescreen, 0, evt);
+
+        // For debug purposes and because some of the APIs are not yet exposed
+        // to the content, let's react on some of the keyup events.
+        if (evt.type == 'keyup') {
+          switch (evt.keyCode) {
+            case evt.DOM_VK_F5:
+              if (Services.prefs.getBoolPref('b2g.keys.search.enabled'))
+                this.toggleDebug();
+              break;
+  
+            case evt.DOM_VK_PAGE_DOWN:
+              this.changeVolume(-1);
+              break;
+  
+            case evt.DOM_VK_PAGE_UP:
+              this.changeVolume(1);
+              break;
+          }
         }
         break;
 
       case 'mozfullscreenchange':
         // When the screen goes fullscreen make sure to set the focus to the
         // main window so noboby can prevent the ESC key to get out fullscreen
         // mode
         if (document.mozFullScreen)
           Services.fm.focusedWindow = window;
         break;
       case 'load':
         this.contentBrowser.removeEventListener('load', this, true);
-        this.turnScreenOn();
 
         let chromeWindow = window.QueryInterface(Ci.nsIDOMChromeWindow);
         chromeWindow.browserDOMWindow = new nsBrowserAccess();
 
         this.sendEvent(window, 'ContentStart');
         break;
       case 'MozApplicationManifest':
         try {
@@ -312,39 +311,25 @@ var shell = {
         }
         break;
     }
   },
   sendEvent: function shell_sendEvent(content, type, details) {
     let event = content.document.createEvent('CustomEvent');
     event.initCustomEvent(type, true, true, details ? details : {});
     content.dispatchEvent(event);
-  },
-  toggleScreen: function shell_toggleScreen() {
-    if (screen.mozEnabled)
-      this.turnScreenOff();
-    else
-      this.turnScreenOn();
-  },
-  turnScreenOff: function shell_turnScreenOff() {
-    screen.mozEnabled = false;
-    screen.mozBrightness = 0.0;
-  },
-  turnScreenOn: function shell_turnScreenOn() {
-    screen.mozEnabled = true;
-    screen.mozBrightness = this.preferredScreenBrightness;
   }
 };
 
 (function PowerManager() {
   let idleHandler = {
     observe: function(subject, topic, time) {
       if (topic === "idle") {
         // TODO: Check wakelock status. See bug 697132.
-        shell.turnScreenOff();
+        screen.mozEnabled = false;
       }
     },
   }
   let idleTimeout = Services.prefs.getIntPref("power.screen.timeout");
   if (idleTimeout) {
     Services.idle.addIdleObserver(idleHandler, idleTimeout);
   }
 })();
--- a/b2g/chrome/content/shell.xul
+++ b/b2g/chrome/content/shell.xul
@@ -10,28 +10,23 @@
         windowtype="navigator:browser"
 #ifdef ANDROID
         sizemode="fullscreen"
 #endif
         style="background: black; overflow: hidden;"
         onload="shell.start();"
         onunload="shell.stop();">
 
-  <script type="application/javascript" src="chrome://browser/content/commandUtil.js"/>
   <script type="application/javascript" src="chrome://browser/content/shell.js"/>
 #ifndef MOZ_TOUCH
   <script type="application/javascript" src="chrome://browser/content/touch.js"/>
 #endif
 #ifndef MOZ_WIDGET_GONK
   <script type="application/javascript" src="chrome://browser/content/httpd.js"/>
 #endif
 
-  <commandset id="mainCommandSet">
-    <command id="cmd_close" oncommand="CommandUpdater.doCommand(this.id);"/>
-  </commandset>
-
   <browser id="homescreen"
            type="content-primary"
            flex="1"
            style="overflow: hidden;"
            src="data:text/html,%3C!DOCTYPE html>%3Cbody style='background:black;'>"/>
 </window>
 
--- a/b2g/chrome/jar.mn
+++ b/b2g/chrome/jar.mn
@@ -4,22 +4,21 @@ chrome.jar:
 % content branding %content/branding/
 % content browser %content/
 
 * content/shell.xul                     (content/shell.xul)
 * content/shell.js                      (content/shell.js)
 #ifndef MOZ_TOUCH
   content/touch.js                      (content/touch.js)
 #endif
-  content/commandUtil.js                (content/commandUtil.js)
 #ifndef MOZ_WIDGET_GONK
   content/httpd.js                      (content/httpd.js)
 #endif
   content/webapi.js                     (content/webapi.js)
   content/content.css                   (content/content.css)
 
 % override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml
 % override chrome://global/skin/netError.css chrome://browser/content/netError.css
   content/netError.xhtml                (content/netError.xhtml)
   content/netError.css                  (content/netError.css)
   content/images/errorpage-larry-black.png (content/images/errorpage-larry-black.png)
   content/images/errorpage-larry-white.png (content/images/errorpage-larry-white.png)
-  content/images/errorpage-warning.png (content/images/errorpage-warning.png)
\ No newline at end of file
+  content/images/errorpage-warning.png (content/images/errorpage-warning.png)