Merge last PGO-green changeset of mozilla-inbound to mozilla-central
authorEd Morley <emorley@mozilla.com>
Wed, 27 Jun 2012 11:29:26 +0100
changeset 97753 1a56f1f011c964815844ef8bdd9f313db20feebf
parent 97688 5cdbeae144058bfc99438bf33c515eb76ddbd408 (current diff)
parent 97752 8e830624d9ee91045b25b8c30e85b3a423bca819 (diff)
child 97754 a12ce6b09f13a6296503eb0f5d1c7d097f412fef
push id22993
push useremorley@mozilla.com
push dateWed, 27 Jun 2012 10:31:27 +0000
treeherdermozilla-central@1a56f1f011c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone16.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
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
dom/tests/mochitest/devicestorage/Makefile.in
dom/tests/mochitest/devicestorage/devicestorage_common.js
dom/tests/mochitest/devicestorage/test_enumerate.html
testing/xpcshell/xpcshell.ini
--- a/b2g/chrome/content/forms.js
+++ b/b2g/chrome/content/forms.js
@@ -8,120 +8,110 @@ dump("##################################
 
 "use strict";
 
 let Ci = Components.interfaces;
 let Cc = Components.classes;
 let Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 XPCOMUtils.defineLazyServiceGetter(Services, "fm",
                                    "@mozilla.org/focus-manager;1",
                                    "nsIFocusManager");
 
 let HTMLInputElement = Ci.nsIDOMHTMLInputElement;
 let HTMLTextAreaElement = Ci.nsIDOMHTMLTextAreaElement;
 let HTMLSelectElement = Ci.nsIDOMHTMLSelectElement;
 let HTMLOptGroupElement = Ci.nsIDOMHTMLOptGroupElement;
 let HTMLOptionElement = Ci.nsIDOMHTMLOptionElement;
 
 let FormAssistant = {
   init: function fa_init() {
     addEventListener("focus", this, true, false);
+    addEventListener("blur", this, true, false);
     addEventListener("keypress", this, true, false);
-    addEventListener("mousedown", this, true, false);
     addEventListener("resize", this, true, false);
-    addEventListener("click", this, true, false);
-    addEventListener("blur", this, true, false);
     addMessageListener("Forms:Select:Choice", this);
     addMessageListener("Forms:Input:Value", this);
     Services.obs.addObserver(this, "ime-enabled-state-changed", false);
     Services.obs.addObserver(this, "xpcom-shutdown", false);
   },
 
   isKeyboardOpened: false,
   previousTarget : null,
   handleEvent: function fa_handleEvent(evt) {
     let previousTarget = this.previousTarget;
     let target = evt.target;
 
     switch (evt.type) {
       case "focus":
-        this.previousTarget = Services.fm.focusedElement;
-        break;
-
-      case "blur":
-        if (!target)
-          return;
-        this.previousTarget = null;
-
-        if (target instanceof HTMLSelectElement ||
-            (target instanceof HTMLOptionElement && target.parentNode instanceof HTMLSelectElement)) {
-
-          sendAsyncMessage("Forms:Input", { "type": "blur" });
-        }
-        break;
-
-      case 'resize':
-        if (!this.isKeyboardOpened)
-          return;
-
-        Services.fm.focusedElement.scrollIntoView(false);
-        break;
-
-      case "mousedown":
-        if (evt.target != target || this.isKeyboardOpened)
+        if (this.isKeyboardOpened)
           return;
 
         let ignore = {
           button: true,
+          file: true,
           checkbox: true,
-          file: true,
           radio: true,
           reset: true,
           submit: true
         };
     
-        if ((target instanceof HTMLInputElement && ignore[target.type]) ||
-            !(target instanceof HTMLInputElement ||
-              target instanceof HTMLTextAreaElement)) {
+        if (evt.target instanceof HTMLSelectElement) { 
+          content.setTimeout(function showIMEForSelect() {
+            sendAsyncMessage("Forms:Input", getJSON(evt.target));
+          });
+        } else if (evt.target instanceof HTMLOptionElement &&
+                   evt.target.parentNode instanceof HTMLSelectElement) {
+          content.setTimeout(function showIMEForSelect() {
+            sendAsyncMessage("Forms:Input", getJSON(evt.target.parentNode));
+          });
+        } else if ((target instanceof HTMLInputElement && !ignore[target.type]) ||
+                    target instanceof HTMLTextAreaElement) {
+          this.isKeyboardOpened = this.tryShowIme(evt.target);
+          this.previousTarget = evt.target;
+        }
+        break;
+
+      case "blur":
+        if (this.previousTarget) {
+          sendAsyncMessage("Forms:Input", { "type": "blur" });
+          this.previousTarget = null;
+        }
+        break;
+
+      case "resize":
+        if (!this.isKeyboardOpened)
           return;
+
+        let focusedElement = this.previousTarget;
+        if (focusedElement) {
+          focusedElement.scrollIntoView(false);
         }
-
-        this.isKeyboardOpened = this.tryShowIme(evt.target);
         break;
 
       case "keypress":
         if (evt.keyCode != evt.DOM_VK_ESCAPE || !this.isKeyboardOpened)
           return;
 
         sendAsyncMessage("Forms:Input", { "type": "blur" });
         this.isKeyboardOpened = false;
 
         evt.preventDefault();
         evt.stopPropagation();
         break;
-
-      case "click":
-        content.setTimeout(function showIMEForSelect() {
-          if (evt.target instanceof HTMLSelectElement) { 
-            sendAsyncMessage("Forms:Input", getJSON(evt.target));
-          } else if (evt.target instanceof HTMLOptionElement &&
-                     evt.target.parentNode instanceof HTMLSelectElement) {
-            sendAsyncMessage("Forms:Input", getJSON(evt.target.parentNode));
-          }
-        });
-        break;
     }
   },
 
   receiveMessage: function fa_receiveMessage(msg) {
-    let target = Services.fm.focusedElement;
-    if (!target)
+    let target = this.previousTarget;
+    if (!target) {
       return;
+    }
 
     let json = msg.json;
     switch (msg.name) {
       case "Forms:Input:Value":
         target.value = json.value;
         break;
 
       case "Forms:Select:Choice":
@@ -164,29 +154,31 @@ let FormAssistant = {
         break;
     }
   },
 
   tryShowIme: function(element) {
     // FIXME/bug 729623: work around apparent bug in the IME manager
     // in gecko.
     let readonly = element.getAttribute("readonly");
-    if (readonly)
+    if (readonly) {
       return false;
+    }
 
     sendAsyncMessage("Forms:Input", getJSON(element));
     return true;
   }
 };
 
 FormAssistant.init();
 
 
 function getJSON(element) {
-  let type = element.type;
+  let type = element.type || "";
+
   // FIXME/bug 344616 is input type="number"
   // Until then, let's return 'number' even if the platform returns 'text'
   let attributeType = element.getAttribute("type") || "";
   if (attributeType && attributeType.toLowerCase() === "number")
     type = "number";
 
   return {
     "type": type.toLowerCase(),
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -106,16 +106,22 @@ var shell = {
     browserFrame.setAttribute('id', 'homescreen');
     browserFrame.setAttribute('mozbrowser', 'true');
     browserFrame.setAttribute('mozapp', manifestURL);
     browserFrame.setAttribute('mozallowfullscreen', 'true');
     browserFrame.setAttribute('style', "overflow: hidden; -moz-box-flex: 1; border: none;");
     browserFrame.setAttribute('src', "data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;");
     document.getElementById('shell').appendChild(browserFrame);
 
+    browserFrame.contentWindow
+                .QueryInterface(Ci.nsIInterfaceRequestor)
+                .getInterface(Ci.nsIWebNavigation)
+                .sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
+                                    .createInstance(Ci.nsISHistory);
+
     ['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('mozfullscreenchange', this);
     window.addEventListener('sizemodechange', this);
--- a/b2g/chrome/content/webapi.js
+++ b/b2g/chrome/content/webapi.js
@@ -8,20 +8,16 @@
 
 dump('======================= webapi.js ======================= \n');
 
 let { classes: Cc, interfaces: Ci, utils: Cu }  = Components;
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import('resource://gre/modules/Services.jsm');
 Cu.import('resource://gre/modules/Geometry.jsm');
 
-XPCOMUtils.defineLazyServiceGetter(Services, 'fm',
-                                   '@mozilla.org/focus-manager;1',
-                                   'nsIFocusManager');
-
 const ContentPanning = {
   init: function cp_init() {
     ['mousedown', 'mouseup', 'mousemove'].forEach(function(type) {
       addEventListener(type, ContentPanning, true);
     });
   },
 
   handleEvent: function cp_handleEvent(evt) {
--- a/b2g/components/MozKeyboard.js
+++ b/b2g/components/MozKeyboard.js
@@ -2,16 +2,17 @@
  * 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/. */
 
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
+const kFormsFrameScript = "chrome://browser/content/forms.js";
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 const messageManager = Cc["@mozilla.org/globalmessagemanager;1"]
                          .getService(Ci.nsIChromeFrameMessageManager);
 
 
@@ -32,20 +33,22 @@ MozKeyboard.prototype = {
     "classID": Components.ID("{397a7fdf-2254-47be-b74e-76625a1a66d5}"),
     "contractID": "@mozilla.org/b2g-keyboard;1",
     "interfaces": [Ci.nsIB2GKeyboard],
     "flags": Ci.nsIClassInfo.DOM_OBJECT,
     "classDescription": "B2G Virtual Keyboard"
   }),
 
   init: function mozKeyboardInit(win) {
-    messageManager.loadFrameScript("chrome://browser/content/forms.js", true);
+    messageManager.loadFrameScript(kFormsFrameScript, true);
     messageManager.addMessageListener("Forms:Input", this);
 
     Services.obs.addObserver(this, "inner-window-destroyed", false);
+    Services.obs.addObserver(this, 'in-process-browser-frame-shown', false);
+    Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
 
     this._window = win;
     this._utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
                      .getInterface(Ci.nsIDOMWindowUtils);
     this.innerWindowID = this._utils.currentInnerWindowID;
 
     this._focusHandler = null;
   },
@@ -100,19 +103,34 @@ MozKeyboard.prototype = {
       "detail": msg.json
     };
 
     let evt = new this._window.CustomEvent("focuschanged", detail);
     handler.handleEvent(evt);
   },
 
   observe: function mozKeyboardObserve(subject, topic, data) {
-    if (topic == "inner-window-destroyed") {
+    switch (topic) {
+    case "inner-window-destroyed": {
       let wId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
       if (wId == this.innerWindowID) {
         this.uninit();
       }
+      break;
+    }
+    case 'remote-browser-frame-shown':
+    case 'in-process-browser-frame-shown': {
+      let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
+      let mm = frameLoader.messageManager;
+      mm.addMessageListener("Forms:Input", this);
+      try {
+        mm.loadFrameScript(kFormsFrameScript, true);
+      } catch (e) {
+        dump('Error loading ' + kFormsFrameScript + ' as frame script: ' + e + '\n');
+      }
+      break;
+    }
     }
   }
 };
 
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([MozKeyboard]);
 
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -657,23 +657,16 @@
             if (isRTL) {
               var width = innerRect.right - outerRect.left;
             } else {
               var width = outerRect.right - innerRect.left;
             }
             popup.setAttribute("width", width > 100 ? width : 100);
 
             var yOffset = outerRect.bottom - innerRect.bottom;
-
-            // setConsumeRollupEvent() before we call openPopup(), 
-            // see bug #404438 for more details
-            popup.popupBoxObject.setConsumeRollupEvent(
-              this.consumeRollupEvent ? 
-                Ci.nsIPopupBoxObject.ROLLUP_CONSUME : 
-                Ci.nsIPopupBoxObject.ROLLUP_NO_CONSUME);
             popup.openPopup(this.inputField, "after_start", 0, yOffset, false, false);
           }
         ]]></body>
       </method>
 
       <method name="observe">
         <parameter name="aSubject"/>
         <parameter name="aTopic"/>
--- a/build/unix/mozconfig.asan
+++ b/build/unix/mozconfig.asan
@@ -1,11 +1,11 @@
-# Use Clang r155417
-export CC="/tools/clang-3.0/bin/clang -fgnu89-inline"
-export CXX="/tools/clang-3.0/bin/clang++"
+# Use Clang as specified in manifest
+export CC="$topsrcdir/clang/bin/clang -fgnu89-inline"
+export CXX="$topsrcdir/clang/bin/clang++"
 
 # Mandatory flags for ASan
 export ASANFLAGS="-faddress-sanitizer -Dxmalloc=myxmalloc -fPIC"
 export CFLAGS="$ASANFLAGS"
 export CXXFLAGS="$ASANFLAGS"
 export LDFLAGS="-faddress-sanitizer"
 
 # Enable ASan specific code and build workarounds
--- a/content/base/src/CSPUtils.jsm
+++ b/content/base/src/CSPUtils.jsm
@@ -47,37 +47,37 @@ var gPrefObserver = {
     if(aTopic != "nsPref:changed") return;
     if(aData === "debug")
       this._debugEnabled = this._branch.getBoolPref("debug");
   },
 
 };
 
 
-function CSPWarning(aMsg, aSource, aScriptSample, aLineNum) {
+function CSPWarning(aMsg, aWindowID, aSource, aScriptSample, aLineNum) {
   var textMessage = 'CSP WARN:  ' + aMsg + "\n";
 
   var consoleMsg = Components.classes["@mozilla.org/scripterror;1"]
                     .createInstance(Components.interfaces.nsIScriptError);
-  consoleMsg.init(textMessage, aSource, aScriptSample, aLineNum, 0,
+  consoleMsg.initWithWindowID(textMessage, aSource, aScriptSample, aLineNum, 0,
                   Components.interfaces.nsIScriptError.warningFlag,
-                  "Content Security Policy");
+                  "Content Security Policy", aWindowID);
   Components.classes["@mozilla.org/consoleservice;1"]
                     .getService(Components.interfaces.nsIConsoleService)
                     .logMessage(consoleMsg);
 }
 
-function CSPError(aMsg) {
+function CSPError(aMsg, aWindowID) {
   var textMessage = 'CSP ERROR:  ' + aMsg + "\n";
 
   var consoleMsg = Components.classes["@mozilla.org/scripterror;1"]
                     .createInstance(Components.interfaces.nsIScriptError);
-  consoleMsg.init(textMessage, null, null, 0, 0,
+  consoleMsg.initWithWindowID(textMessage, null, null, 0, 0,
                   Components.interfaces.nsIScriptError.errorFlag,
-                  "Content Security Policy");
+                  "Content Security Policy", aWindowID);
   Components.classes["@mozilla.org/consoleservice;1"]
                     .getService(Components.interfaces.nsIConsoleService)
                     .logMessage(consoleMsg);
 }
 
 function CSPdebug(aMsg) {
   if (!gPrefObserver.debugEnabled) return;
 
--- a/content/base/src/contentSecurityPolicy.js
+++ b/content/base/src/contentSecurityPolicy.js
@@ -98,16 +98,44 @@ ContentSecurityPolicy.prototype = {
   get allowsInlineScript() {
     return this._reportOnlyMode || this._policy.allowsInlineScripts;
   },
 
   get allowsEval() {
     return this._reportOnlyMode || this._policy.allowsEvalInScripts;
   },
 
+  get innerWindowID() {
+    let win = null;
+    let loadContext = null;
+
+    try {
+      loadContext = this._docRequest
+                        .notificationCallbacks.getInterface(Ci.nsILoadContext);
+    } catch (ex) {
+      try {
+        loadContext = this._docRequest.loadGroup
+                          .notificationCallbacks.getInterface(Ci.nsILoadContext);
+      } catch (ex) {
+      }
+    }
+
+    if (loadContext) {
+      win = loadContext.associatedWindow;
+    }
+    if (win) {
+      try {
+         let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+         return winUtils.currentInnerWindowID;
+      } catch (ex) {
+      }
+    }
+    return null;
+  },
+
   /**
    * Log policy violation on the Error Console and send a report if a report-uri
    * is present in the policy
    *
    * @param aViolationType
    *     one of the VIOLATION_TYPE_* constants, e.g. inline-script or eval
    * @param aSourceFile
    *     name of the source file containing the violation (if available)
@@ -253,16 +281,17 @@ ContentSecurityPolicy.prototype = {
       if (aLineNum)
         report["csp-report"]["line-number"] = aLineNum;
 
       var reportString = JSON.stringify(report);
       CSPdebug("Constructed violation report:\n" + reportString);
 
       CSPWarning("Directive \"" + violatedDirective + "\" violated"
                + (blockedUri['asciiSpec'] ? " by " + blockedUri.asciiSpec : ""),
+                 this.innerWindowID,
                  (aSourceFile) ? aSourceFile : null,
                  (aScriptSample) ? decodeURIComponent(aScriptSample) : null,
                  (aLineNum) ? aLineNum : null);
 
       // For each URI in the report list, send out a report.
       // We make the assumption that all of the URIs are absolute URIs; this
       // should be taken care of in CSPRep.fromString (where it converts any
       // relative URIs into absolute ones based on "self").
@@ -313,18 +342,18 @@ ContentSecurityPolicy.prototype = {
           }
 
           //send data (and set up error notifications)
           chan.asyncOpen(new CSPViolationReportListener(uris[i]), null);
           CSPdebug("Sent violation report to " + uris[i]);
         } catch(e) {
           // it's possible that the URI was invalid, just log a
           // warning and skip over that.
-          CSPWarning("Tried to send report to invalid URI: \"" + uris[i] + "\"");
-          CSPWarning("error was: \"" + e + "\"");
+          CSPWarning("Tried to send report to invalid URI: \"" + uris[i] + "\"", this.innerWindowID);
+          CSPWarning("error was: \"" + e + "\"", this.innerWindowID);
         }
       }
     }
   },
 
   /**
    * Exposed Method to analyze docShell for approved frame ancestry.
    * Also sends violation reports if necessary.
@@ -517,17 +546,17 @@ CSPReportRedirectSink.prototype = {
 
     throw Components.results.NS_ERROR_NO_INTERFACE;
   },
 
   // nsIChannelEventSink
   asyncOnChannelRedirect: function channel_redirect(oldChannel, newChannel,
                                                     flags, callback) {
     CSPWarning("Post of violation report to " + oldChannel.URI.asciiSpec +
-               " failed, as a redirect occurred");
+               " failed, as a redirect occurred", this.innerWindowID);
 
     // cancel the old channel so XHR failure callback happens
     oldChannel.cancel(Cr.NS_ERROR_ABORT);
 
     // notify an observer that we have blocked the report POST due to a redirect,
     // used in testing, do this async since we're in an async call now to begin with
     Services.tm.mainThread.dispatch(
       function() {
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -96,18 +96,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParser)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNodeInfoManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptLoader)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsContentSink)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParser)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNodeInfoManager,
-                                                  nsNodeInfoManager)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfoManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptLoader)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
 nsContentSink::nsContentSink()
 {
   // We have a zeroing operator new
   NS_ASSERTION(!mLayoutStarted, "What?");
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1679,16 +1679,17 @@ GK_ATOM(blockFrame, "BlockFrame")
 GK_ATOM(boxFrame, "BoxFrame")
 GK_ATOM(brFrame, "BRFrame")
 GK_ATOM(bulletFrame, "BulletFrame")
 GK_ATOM(columnSetFrame, "ColumnSetFrame")
 GK_ATOM(comboboxControlFrame, "ComboboxControlFrame")
 GK_ATOM(comboboxDisplayFrame, "ComboboxDisplayFrame")
 GK_ATOM(deckFrame, "DeckFrame")
 GK_ATOM(fieldSetFrame, "FieldSetFrame")
+GK_ATOM(flexContainerFrame, "FlexContainerFrame")
 GK_ATOM(formControlFrame, "FormControlFrame") // radio or checkbox
 GK_ATOM(frameSetFrame, "FrameSetFrame")
 GK_ATOM(gfxButtonControlFrame, "gfxButtonControlFrame")
 GK_ATOM(HTMLButtonControlFrame, "HTMLButtonControlFrame")
 GK_ATOM(HTMLCanvasFrame, "HTMLCanvasFrame")
 GK_ATOM(subDocumentFrame, "subDocumentFrame")
 GK_ATOM(imageBoxFrame, "ImageBoxFrame")
 GK_ATOM(imageFrame, "ImageFrame")
--- a/content/base/src/nsNodeInfo.cpp
+++ b/content/base/src/nsNodeInfo.cpp
@@ -172,18 +172,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
     }
 
     cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(nsNodeInfo), name);
   }
   else {
     NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsNodeInfo, tmp->mRefCnt.get())
   }
 
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mOwnerManager,
-                                                  nsNodeInfoManager)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mOwnerManager)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeInfo)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsNodeInfo, LastRelease())
 NS_INTERFACE_TABLE_HEAD(nsNodeInfo)
   NS_INTERFACE_TABLE1(nsNodeInfo, nsINodeInfo)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsNodeInfo)
 NS_INTERFACE_MAP_END
--- a/content/base/src/nsNodeInfoManager.cpp
+++ b/content/base/src/nsNodeInfoManager.cpp
@@ -125,32 +125,37 @@ nsNodeInfoManager::~nsNodeInfoManager()
     PR_LOG(gNodeInfoManagerLeakPRLog, PR_LOG_DEBUG,
            ("NODEINFOMANAGER %p destroyed", this));
 #endif
 
   nsLayoutStatics::Release();
 }
 
 
-NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsNodeInfoManager)
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsNodeInfoManager, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsNodeInfoManager, Release)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsNodeInfoManager)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsNodeInfoManager)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfoManager)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsNodeInfoManager)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsNodeInfoManager)
   if (tmp->mDocument &&
       nsCCUncollectableMarker::InGeneration(cb,
                                             tmp->mDocument->GetMarkedCCGeneration())) {
     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
   }
   if (tmp->mNonDocumentNodeInfos) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mDocument)
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mBindingManager)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeInfoManager)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsNodeInfoManager)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsNodeInfoManager)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
 nsresult
 nsNodeInfoManager::Init(nsIDocument *aDocument)
 {
   NS_ENSURE_TRUE(mNodeInfoHash, NS_ERROR_OUT_OF_MEMORY);
 
   NS_PRECONDITION(!mPrincipal,
                   "Being inited when we already have a principal?");
   nsresult rv = CallCreateInstance("@mozilla.org/nullprincipal;1",
--- a/content/base/src/nsNodeInfoManager.h
+++ b/content/base/src/nsNodeInfoManager.h
@@ -23,25 +23,24 @@ class nsIURI;
 class nsDocument;
 class nsIDOMDocumentType;
 class nsIDOMDocument;
 class nsAString;
 class nsIDOMNamedNodeMap;
 class nsXULPrototypeDocument;
 class nsBindingManager;
 
-class nsNodeInfoManager
+class nsNodeInfoManager : public nsISupports
 {
 public:
   nsNodeInfoManager();
   ~nsNodeInfoManager();
 
-  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsNodeInfoManager)
-
-  NS_INLINE_DECL_REFCOUNTING(nsNodeInfoManager)
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeInfoManager)
 
   /**
    * Initialize the nodeinfo manager with a document.
    */
   nsresult Init(nsIDocument *aDocument);
 
   /**
    * Release the reference to the document, this will be called when
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -775,17 +775,19 @@ PRInt64 nsOggReader::RangeEndTime(PRInt6
 
   // We need to find the last page which ends before aEndOffset that
   // has a granulepos that we can convert to a timestamp. We do this by
   // backing off from aEndOffset until we encounter a page on which we can
   // interpret the granulepos. If while backing off we encounter a page which
   // we've previously encountered before, we'll either backoff again if we
   // haven't found an end time yet, or return the last end time found.
   const int step = 5000;
+  const int maxOggPageSize = 65306;
   PRInt64 readStartOffset = aEndOffset;
+  PRInt64 readLimitOffset = aEndOffset;
   PRInt64 readHead = aEndOffset;
   PRInt64 endTime = -1;
   PRUint32 checksumAfterSeek = 0;
   PRUint32 prevChecksumAfterSeek = 0;
   bool mustBackOff = false;
   while (true) {
     ogg_page page;    
     int ret = ogg_sync_pageseek(&sync.mState, &page);
@@ -797,16 +799,22 @@ PRInt64 nsOggReader::RangeEndTime(PRInt6
           // We have encountered a page before, or we're at the end of file.
           break;
         }
         mustBackOff = false;
         prevChecksumAfterSeek = checksumAfterSeek;
         checksumAfterSeek = 0;
         ogg_sync_reset(&sync.mState);
         readStartOffset = NS_MAX(static_cast<PRInt64>(0), readStartOffset - step);
+        // There's no point reading more than the maximum size of
+        // an Ogg page into data we've previously scanned. Any data
+        // between readLimitOffset and aEndOffset must be garbage
+        // and we can ignore it thereafter.
+        readLimitOffset = NS_MIN(readLimitOffset,
+                                 readStartOffset + maxOggPageSize);
         readHead = NS_MAX(aStartOffset, readStartOffset);
       }
 
       PRInt64 limit = NS_MIN(static_cast<PRInt64>(PR_UINT32_MAX),
                              aEndOffset - readHead);
       limit = NS_MAX(static_cast<PRInt64>(0), limit);
       limit = NS_MIN(limit, static_cast<PRInt64>(step));
       PRUint32 bytesToRead = static_cast<PRUint32>(limit);
@@ -822,16 +830,19 @@ PRInt64 nsOggReader::RangeEndTime(PRInt6
         NS_ASSERTION(readHead < aEndOffset,
                      "resource pos must be before range end");
         res = resource->Seek(nsISeekableStream::NS_SEEK_SET, readHead);
         NS_ENSURE_SUCCESS(res, -1);
         res = resource->Read(buffer, bytesToRead, &bytesRead);
         NS_ENSURE_SUCCESS(res, -1);
       }
       readHead += bytesRead;
+      if (readHead > readLimitOffset) {
+        mustBackOff = true;
+      }
 
       // Update the synchronisation layer with the number
       // of bytes written to the buffer
       ret = ogg_sync_wrote(&sync.mState, bytesRead);
       if (ret != 0) {
         endTime = -1;
         break;
       }
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -165,18 +165,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULPrototypeDocument)
     if (nsCCUncollectableMarker::InGeneration(cb, tmp->mCCGeneration)) {
         return NS_SUCCESS_INTERRUPTED_TRAVERSE;
     }
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRoot)
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mGlobalObject");
     cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObject*>(tmp->mGlobalObject));
-    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNodeInfoManager,
-                                                    nsNodeInfoManager)
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfoManager)
     for (PRUint32 i = 0; i < tmp->mPrototypeWaiters.Length(); ++i) {
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mPrototypeWaiters[i]");
         cb.NoteXPCOMChild(static_cast<nsINode*>(tmp->mPrototypeWaiters[i].get()));
     }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULPrototypeDocument)
     NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObjectOwner)
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -9854,27 +9854,16 @@ nsDocShell::AddState(nsIVariant *aData, 
             mCurrentURI->Equals(newURI, &equalURIs);
         }
         else {
             equalURIs = false;
         }
 
     } // end of same-origin check
 
-    nsCOMPtr<nsISHistory> sessionHistory = mSessionHistory;
-    if (!sessionHistory) {
-        // Get the handle to SH from the root docshell
-        GetRootSessionHistory(getter_AddRefs(sessionHistory));
-    }
-    NS_ENSURE_TRUE(sessionHistory, NS_ERROR_FAILURE);
-
-    nsCOMPtr<nsISHistoryInternal> shInternal =
-        do_QueryInterface(sessionHistory, &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     // Step 3: Create a new entry in the session history. This will erase
     // all SHEntries after the new entry and make this entry the current
     // one.  This operation may modify mOSHE, which we need later, so we
     // keep a reference here.
     NS_ENSURE_TRUE(mOSHE, NS_ERROR_FAILURE);
     nsCOMPtr<nsISHEntry> oldOSHE = mOSHE;
 
     mLoadType = LOAD_PUSHSTATE;
--- a/docshell/test/test_bug511449.html
+++ b/docshell/test/test_bug511449.html
@@ -2,16 +2,17 @@
 <html>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=511449
 -->
 <head>
   <title>Test for Bug 511449</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/NativeKeyCodes.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=511449">Mozilla Bug 511449</a>
 <p id="display"></p>
 <div id="status"></div>
 <div id="content">
 </div>
@@ -35,17 +36,17 @@ function runTest() {
 function runNextTest() {
   var didClose = false;
   win.onunload = function() {
     didClose = true;
   }
   netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
   var utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
                   getInterface(Components.interfaces.nsIDOMWindowUtils);
-  utils.sendNativeKeyEvent(0, 13 /* w */, 0x4000 /* cmd */, "w", "w");
+  utils.sendNativeKeyEvent(0, MAC_VK_ANSI_W, 0x4000 /* cmd */, "w", "w");
 
   setTimeout(function () {
     ok(didClose, "Cmd+W should have closed the tab");
     if (!didClose) {
       win.close();
     }
     SimpleTest.finish();
   }, 1000);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -5921,21 +5921,28 @@ static const IDBConstant sIDBConstants[]
   { IDBConstant::IDBTransaction, "READ_ONLY",         "readonly" },
   { IDBConstant::IDBTransaction, "READ_WRITE",        "readwrite" },
   { IDBConstant::IDBTransaction, "VERSION_CHANGE",    "versionchange" },
 };
 
 static JSBool
 IDBConstantGetter(JSContext *cx, JSHandleObject obj, JSHandleId id, jsval* vp)
 {
-  MOZ_ASSERT(JSID_IS_INT(id));
-  
-  int8_t index = JSID_TO_INT(id);
-  
-  MOZ_ASSERT((uint8_t)index < mozilla::ArrayLength(sIDBConstants));
+  JSString *idstr = JSID_TO_STRING(id);
+  unsigned index;
+  for (index = 0; index < mozilla::ArrayLength(sIDBConstants); index++) {
+    JSBool match;
+    if (!JS_StringEqualsAscii(cx, idstr, sIDBConstants[index].name, &match)) {
+      return JS_FALSE;
+    }
+    if (match) {
+      break;
+    }
+  }
+  MOZ_ASSERT(index < mozilla::ArrayLength(sIDBConstants));
 
   const IDBConstant& c = sIDBConstants[index];
 
   // Put a warning on the console
   nsString warnText =
     NS_LITERAL_STRING("The constant ") +
     NS_ConvertASCIItoUTF16(c.interface) +
     NS_LITERAL_STRING(".") +
@@ -6010,19 +6017,19 @@ DefineIDBInterfaceConstants(JSContext *c
   }
 
   for (int8_t i = 0; i < (int8_t)mozilla::ArrayLength(sIDBConstants); ++i) {
     const IDBConstant& c = sIDBConstants[i];
     if (c.interface != interface) {
       continue;
     }
 
-    if (!::JS_DefinePropertyWithTinyId(cx, obj, c.name, i, JSVAL_VOID,
-                                       IDBConstantGetter, nsnull,
-                                       JSPROP_ENUMERATE)) {
+    if (!JS_DefineProperty(cx, obj, c.name, JSVAL_VOID,
+                           IDBConstantGetter, nsnull,
+                           JSPROP_ENUMERATE)) {
       return NS_ERROR_UNEXPECTED;
     }
   }
 
   return NS_OK;
 }
 
 class nsDOMConstructor MOZ_FINAL : public nsIDOMDOMConstructor
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -342,16 +342,18 @@ interface nsIDOMWindowUtils : nsISupport
                        [optional] in unsigned long aAdditionalFlags);
 
   /**
    * See nsIWidget::SynthesizeNativeKeyEvent
    *
    * Cannot be accessed from unprivileged context (not content-accessible)
    * Will throw a DOM security error if called without UniversalXPConnect
    * privileges.
+   *
+   * When you use this for tests, use the constants defined in NativeKeyCodes.js
    */
   void sendNativeKeyEvent(in long aNativeKeyboardLayout,
                           in long aNativeKeyCode,
                           in long aModifierFlags,
                           in AString aCharacters,
                           in AString aUnmodifiedCharacters);
 
   /**
--- a/dom/sms/src/ril/SmsDatabaseService.js
+++ b/dom/sms/src/ril/SmsDatabaseService.js
@@ -342,28 +342,32 @@ SmsDatabaseService.prototype = {
   },
 
 
   /**
    * nsISmsDatabaseService API
    */
 
   saveReceivedMessage: function saveReceivedMessage(sender, body, date) {
+    let receiver = this.mRIL.rilContext.icc ? this.mRIL.rilContext.icc.msisdn : null;
+
     let message = {delivery:  DELIVERY_RECEIVED,
                    sender:    sender,
-                   receiver:  this.mRIL.rilContext.icc.msisdn, 
+                   receiver:  receiver,
                    body:      body,
                    timestamp: date,
                    read:      FILTER_READ_UNREAD};
     return this.saveMessage(message);
   },
 
   saveSentMessage: function saveSentMessage(receiver, body, date) {
+    let sender = this.mRIL.rilContext.icc ? this.mRIL.rilContext.icc.msisdn : null;
+
     let message = {delivery:  DELIVERY_SENT,
-                   sender:    this.mRIL.rilContext.icc.msisdn,
+                   sender:    sender,
                    receiver:  receiver,
                    body:      body,
                    timestamp: date,
                    read:      FILTER_READ_READ};
     return this.saveMessage(message);
   },
 
   getMessage: function getMessage(messageId, requestId) {
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -462,18 +462,20 @@ ContainerLayer::DefaultComputeEffectiveT
 #else
         contTransform.HasNonIntegerTranslation()) {
 #endif
         for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) {
           const nsIntRect *clipRect = child->GetEffectiveClipRect();
           /* We can't (easily) forward our transform to children with a non-empty clip
            * rect since it would need to be adjusted for the transform. See
            * the calculations performed by CalculateScissorRect above.
+           * Nor for a child with a mask layer.
            */
-          if (clipRect && !clipRect->IsEmpty() && !child->GetVisibleRegion().IsEmpty()) {
+          if ((clipRect && !clipRect->IsEmpty() && !child->GetVisibleRegion().IsEmpty()) ||
+              child->GetMaskLayer()) {
             useIntermediateSurface = true;
             break;
           }
         }
       }
     }
   }
 
new file mode 100644
--- /dev/null
+++ b/gfx/tests/crashtests/768079-1.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<html style="-moz-perspective: 7000px; overflow: hidden;">
+<body style="overflow: hidden; -moz-transform: rotateX(30deg); border-radius: 1px; -moz-columns: 2 10px; visibility: collapse;">X</body>
+</html>
--- a/gfx/tests/crashtests/crashtests.list
+++ b/gfx/tests/crashtests/crashtests.list
@@ -81,9 +81,9 @@ load 580212-1.html
 load 580233-1.html
 load 580719-1.html
 load 594654-1.xhtml
 load 595727-1.html
 load 633453-1.html
 load 633322-1.html
 load 686190-1.html
 load 693143-1.html
-
+load 768079-1.html
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -5798,32 +5798,32 @@ EmitDefaults(JSContext *cx, BytecodeEmit
     uint16_t ndefaults = bce->sc->funbox()->ndefaults;
     JSFunction *fun = bce->sc->fun();
     unsigned nformal = fun->nargs - fun->hasRest();
     EMIT_UINT16_IMM_OP(JSOP_ACTUALSFILLED, nformal - ndefaults);
     ptrdiff_t top = bce->offset();
     size_t tableSize = (size_t)(JUMP_OFFSET_LEN * (3 + ndefaults));
     if (EmitN(cx, bce, JSOP_TABLESWITCH, tableSize) < 0)
         return false;
-    jsbytecode *pc = bce->code(top + JUMP_OFFSET_LEN);
+    ptrdiff_t jumpoff = top + JUMP_OFFSET_LEN;
     JS_ASSERT(nformal >= ndefaults);
     uint16_t defstart = nformal - ndefaults;
-    SET_JUMP_OFFSET(pc, defstart);
-    pc += JUMP_OFFSET_LEN;
-    SET_JUMP_OFFSET(pc, nformal - 1);
-    pc += JUMP_OFFSET_LEN;
+    SET_JUMP_OFFSET(bce->code(jumpoff), defstart);
+    jumpoff += JUMP_OFFSET_LEN;
+    SET_JUMP_OFFSET(bce->code(jumpoff), nformal - 1);
+    jumpoff += JUMP_OFFSET_LEN;
 
     // Fill body of switch, which sets defaults where needed.
     unsigned i;
     ParseNode *arg, *pnlast = pn->last();
     for (arg = pn->pn_head, i = 0; arg != pnlast; arg = arg->pn_next, i++) {
         if (!(arg->pn_dflags & PND_DEFAULT))
             continue;
-        SET_JUMP_OFFSET(pc, bce->offset() - top);
-        pc += JUMP_OFFSET_LEN;
+        SET_JUMP_OFFSET(bce->code(jumpoff), bce->offset() - top);
+        jumpoff += JUMP_OFFSET_LEN;
         ParseNode *expr;
         if (arg->isKind(PNK_NAME)) {
             expr = arg->expr();
         } else {
             // The argument name is bound to a function. We still have to
             // evaluate the default in case it has side effects.
             JS_ASSERT(!arg->isDefn());
             JS_ASSERT(arg->isKind(PNK_ASSIGN));
@@ -5852,17 +5852,17 @@ EmitDefaults(JSContext *cx, BytecodeEmit
             // not. Only the decompiler is going to see it.
             if (!EmitUnaliasedVarOp(cx, JSOP_SETLOCAL, slot, bce))
                 return false;
             SET_JUMP_OFFSET(bce->code(hop), bce->offset() - hop);
         }
         if (Emit1(cx, bce, JSOP_POP) < 0)
             return false;
     }
-    JS_ASSERT(pc == bce->code(top + tableSize));
+    JS_ASSERT(jumpoff == top + ptrdiff_t(tableSize));
     SET_JUMP_OFFSET(bce->code(top), bce->offset() - top);
     return true;
 }
 
 JSBool
 frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
 {
     JS_CHECK_RECURSION(cx, return JS_FALSE);
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -588,17 +588,18 @@ SizeOfJSContext();
     D(NSJSCONTEXT_DESTROY)                      \
     D(SET_NEW_DOCUMENT)                         \
     D(SET_DOC_SHELL)                            \
     D(DOM_UTILS)                                \
     D(DOM_IPC)                                  \
     D(DOM_WORKER)                               \
     D(INTER_SLICE_GC)                           \
     D(REFRESH_FRAME)                            \
-    D(FULL_GC_TIMER)
+    D(FULL_GC_TIMER)                            \
+    D(SHUTDOWN_CC)
 
 namespace gcreason {
 
 /* GCReasons will end up looking like JSGC_MAYBEGC */
 enum Reason {
 #define MAKE_REASON(name) name,
     GCREASONS(MAKE_REASON)
 #undef MAKE_REASON
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -874,16 +874,18 @@ MarkExactStackRoots(JSTracer *trc)
                 void **addr = (void **)rooter->address();
                 if (*addr) {
                     if (i == THING_ROOT_OBJECT) {
                         MarkObjectRoot(trc, (JSObject **)addr, "exact stackroot object");
                     } else if (i == THING_ROOT_STRING) {
                         MarkStringRoot(trc, (JSString **)addr, "exact stackroot string");
                     } else if (i == THING_ROOT_ID) {
                         MarkIdRoot(trc, (jsid *)addr, "exact stackroot id");
+                    } else if (i == THING_ROOT_PROPERTY_ID) {
+                        MarkIdRoot(trc, ((PropertyId *)addr)->asId(), "exact stackroot property id");
                     } else if (i == THING_ROOT_VALUE) {
                         MarkValueRoot(trc, (Value *)addr, "exact stackroot value");
                     } else if (i == THING_ROOT_SHAPE) {
                         MarkShapeRoot(trc, (Shape **)addr, "exact stackroot shape");
                     } else if (i == THING_ROOT_BASE_SHAPE) {
                         MarkBaseShapeRoot(trc, (BaseShape **)addr, "exact stackroot baseshape");
                     } else if (i == THING_ROOT_TYPE_OBJECT) {
                         MarkTypeObjectRoot(trc, (types::TypeObject **)addr, "exact stackroot typeobject");
@@ -3159,17 +3161,16 @@ EndMarkPhase(JSRuntime *rt)
     }
 
     /*
      * To avoid the black->gray edge, we completely clear the mark bits of all
      * uncollected compartments. This is safe, although it may prevent the
      * cycle collector from collecting some dead objects.
      */
     if (foundBlackGray) {
-        JS_ASSERT(false);
         for (CompartmentsIter c(rt); !c.done(); c.next()) {
             if (!c->isCollecting())
                 c->arenas.unmarkAll();
         }
     }
 
     rt->gcMarker.stop();
 
@@ -3794,23 +3795,25 @@ IsDeterministicGCReason(gcreason::Reason
     return true;
 }
 #endif
 
 static bool
 ShouldCleanUpEverything(JSRuntime *rt, gcreason::Reason reason)
 {
     // During shutdown, we must clean everything up, for the sake of leak
-    // detection. When a runtime has no contexts, or we're doing a forced GC,
-    // those are strong indications that we're shutting down.
+    // detection. When a runtime has no contexts, or we're doing a GC before a
+    // shutdown CC, those are strong indications that we're shutting down.
     //
     // DEBUG_MODE_GC indicates we're discarding code because the debug mode
     // has changed; debug mode affects the results of bytecode analysis, so
     // we need to clear everything away.
-    return !rt->hasContexts() || reason == gcreason::CC_FORCED || reason == gcreason::DEBUG_MODE_GC;
+    return !rt->hasContexts() ||
+           reason == gcreason::SHUTDOWN_CC ||
+           reason == gcreason::DEBUG_MODE_GC;
 }
 
 static void
 Collect(JSRuntime *rt, bool incremental, int64_t budget,
         JSGCInvocationKind gckind, gcreason::Reason reason)
 {
     JS_AbortIfWrongThread(rt);
 
@@ -3819,17 +3822,17 @@ Collect(JSRuntime *rt, bool incremental,
         return;
 #endif
 
     JS_ASSERT_IF(!incremental || budget != SliceBudget::Unlimited, JSGC_INCREMENTAL);
 
 #ifdef JS_GC_ZEAL
     bool restartVerify = rt->gcVerifyData &&
                          rt->gcZeal() == ZealVerifierValue &&
-                         reason != gcreason::CC_FORCED &&
+                         reason != gcreason::SHUTDOWN_CC &&
                          rt->hasContexts();
 
     struct AutoVerifyBarriers {
         JSRuntime *runtime;
         bool restart;
         AutoVerifyBarriers(JSRuntime *rt, bool restart)
           : runtime(rt), restart(restart)
         {
--- a/js/src/jspubtd.h
+++ b/js/src/jspubtd.h
@@ -225,16 +225,17 @@ enum ThingRootKind
     THING_ROOT_OBJECT,
     THING_ROOT_SHAPE,
     THING_ROOT_BASE_SHAPE,
     THING_ROOT_TYPE_OBJECT,
     THING_ROOT_STRING,
     THING_ROOT_SCRIPT,
     THING_ROOT_XML,
     THING_ROOT_ID,
+    THING_ROOT_PROPERTY_ID,
     THING_ROOT_VALUE,
     THING_ROOT_LIMIT
 };
 
 struct ContextFriendFields {
     JSRuntime *const    runtime;
 
     ContextFriendFields(JSRuntime *rt)
--- a/js/src/vm/ObjectImpl.h
+++ b/js/src/vm/ObjectImpl.h
@@ -1261,16 +1261,17 @@ class ObjectImpl : public gc::Cell
          * aligned with the end of its arena and dynamic slots are allocated
          * immediately afterwards. Such cases cannot occur for dense arrays
          * (which have at least two fixed slots) and can only result in a leak.
          */
         return elements != emptyObjectElements && elements != fixedElements();
     }
 
     /* GC support. */
+    static inline ThingRootKind rootKind() { return THING_ROOT_OBJECT; }
     static inline void readBarrier(ObjectImpl *obj);
     static inline void writeBarrierPre(ObjectImpl *obj);
     static inline void writeBarrierPost(ObjectImpl *obj, void *addr);
     inline void privateWriteBarrierPre(void **oldval);
     inline void privateWriteBarrierPost(void **oldval);
     void markChildren(JSTracer *trc);
 
     /* Private data accessors. */
@@ -1354,9 +1355,18 @@ SetElement(JSContext *cx, Handle<ObjectI
            const Value &v, unsigned resolveFlags, bool *succeeded);
 
 extern bool
 HasElement(JSContext *cx, Handle<ObjectImpl*> obj, uint32_t index, unsigned resolveFlags,
            bool *found);
 
 } /* namespace js */
 
+namespace JS {
+template <> struct RootMethods<js::PropertyId>
+{
+    static js::PropertyId initial() { return js::PropertyId(); }
+    static ThingRootKind kind() { return THING_ROOT_PROPERTY_ID; }
+    static bool poisoned(js::PropertyId propid) { return IsPoisonedId(propid.asId()); }
+};
+}
+
 #endif /* ObjectImpl_h__ */
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3625,45 +3625,55 @@ nsXPCComponents_utils_Sandbox::CallOrCon
     if (NS_FAILED(rv))
         return ThrowAndFail(rv, cx, _retval);
 
     *_retval = true;
 
     return rv;
 }
 
-class ContextHolder : public nsISupports
+class ContextHolder : public nsIScriptObjectPrincipal
+                    , public nsIScriptContextPrincipal
 {
 public:
-    ContextHolder(JSContext *aOuterCx, JSObject *aSandbox, bool isChrome);
+    ContextHolder(JSContext *aOuterCx, JSObject *aSandbox, nsIPrincipal *aPrincipal);
     virtual ~ContextHolder();
 
     JSContext * GetJSContext()
     {
         return mJSContext;
     }
 
+    nsIScriptObjectPrincipal * GetObjectPrincipal() { return this; }
+    nsIPrincipal * GetPrincipal() { return mPrincipal; }
+
     NS_DECL_ISUPPORTS
 
 private:
     static JSBool ContextHolderOperationCallback(JSContext *cx);
 
     JSContext* mJSContext;
     JSContext* mOrigCx;
+    nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
-NS_IMPL_ISUPPORTS0(ContextHolder)
+NS_IMPL_ISUPPORTS2(ContextHolder, nsIScriptObjectPrincipal, nsIScriptContextPrincipal)
 
 ContextHolder::ContextHolder(JSContext *aOuterCx,
                              JSObject *aSandbox,
-                             bool isChrome)
+                             nsIPrincipal *aPrincipal)
     : mJSContext(JS_NewContext(JS_GetRuntime(aOuterCx), 1024)),
-      mOrigCx(aOuterCx)
+      mOrigCx(aOuterCx),
+      mPrincipal(aPrincipal)
 {
     if (mJSContext) {
+        bool isChrome;
+        DebugOnly<nsresult> rv = XPCWrapper::GetSecurityManager()->
+                                   IsSystemPrincipal(mPrincipal, &isChrome);
+        MOZ_ASSERT(NS_SUCCEEDED(rv));
         bool allowXML = Preferences::GetBool(isChrome ?
                                              "javascript.options.xml.chrome" :
                                              "javascript.options.xml.content");
 
         JSAutoRequest ar(mJSContext);
         JS_SetOptions(mJSContext,
                       JS_GetOptions(mJSContext) |
                       JSOPTION_DONT_REPORT_UNCAUGHT |
@@ -3811,36 +3821,33 @@ xpc_EvalInSandbox(JSContext *cx, JSObjec
         JSAutoRequest req(cx);
 
         callingScope = JS_GetGlobalForScopeChain(cx);
         if (!callingScope) {
             return NS_ERROR_FAILURE;
         }
     }
 
-    bool isChrome;
-    nsresult rv = XPCWrapper::GetSecurityManager()->IsSystemPrincipal(prin, &isChrome);
-    NS_ENSURE_SUCCESS(rv, rv);
-    nsRefPtr<ContextHolder> sandcx = new ContextHolder(cx, sandbox, isChrome);
+    nsRefPtr<ContextHolder> sandcx = new ContextHolder(cx, sandbox, prin);
     if (!sandcx || !sandcx->GetJSContext()) {
         JS_ReportError(cx, "Can't prepare context for evalInSandbox");
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     if (jsVersion != JSVERSION_DEFAULT)
         JS_SetVersion(sandcx->GetJSContext(), jsVersion);
 
     XPCJSContextStack *stack = XPCJSRuntime::Get()->GetJSContextStack();
     MOZ_ASSERT(stack);
     if (!stack->Push(sandcx->GetJSContext())) {
         JS_ReportError(cx, "Unable to initialize XPConnect with the sandbox context");
         return NS_ERROR_FAILURE;
     }
 
-    rv = NS_OK;
+    nsresult rv = NS_OK;
 
     {
         JSAutoRequest req(sandcx->GetJSContext());
         JSAutoEnterCompartment ac;
 
         if (!ac.enter(sandcx->GetJSContext(), sandbox)) {
             if (stack)
                 unused << stack->Pop();
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -90,16 +90,19 @@
 #include "nsRenderingContext.h"
 
 #ifdef MOZ_XUL
 #include "nsIRootBox.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIXULDocument.h"
 #endif
+#ifdef MOZ_FLEXBOX
+#include "nsFlexContainerFrame.h"
+#endif
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 #include "nsInlineFrame.h"
 #include "nsBlockFrame.h"
 
 #include "nsIScrollableFrame.h"
@@ -324,16 +327,26 @@ NS_NewScrollbarButtonFrame (nsIPresShell
 #ifdef NOISY_FINDFRAME
 static PRInt32 FFWC_totalCount=0;
 static PRInt32 FFWC_doLoop=0;
 static PRInt32 FFWC_doSibling=0;
 static PRInt32 FFWC_recursions=0;
 static PRInt32 FFWC_nextInFlows=0;
 #endif
 
+#ifdef MOZ_FLEXBOX
+// Returns true if aFrame is an anonymous flex item
+static inline bool
+IsAnonymousFlexItem(const nsIFrame* aFrame)
+{
+  const nsIAtom* pseudoType = aFrame->GetStyleContext()->GetPseudo();
+  return pseudoType == nsCSSAnonBoxes::anonymousFlexItem;
+}
+#endif // MOZ_FLEXBOX
+
 static inline nsIFrame*
 GetFieldSetBlockFrame(nsIFrame* aFieldsetFrame)
 {
   // Depends on the fieldset child frame order - see ConstructFieldSetFrame() below.
   nsIFrame* firstChild = aFieldsetFrame->GetFirstPrincipalChild();
   return firstChild && firstChild->GetNextSibling() ? firstChild->GetNextSibling() : firstChild;
 }
 
@@ -361,16 +374,30 @@ IsInlineOutside(nsIFrame* aFrame)
  */
 static bool
 IsInlineFrame(const nsIFrame* aFrame)
 {
   return aFrame->IsFrameOfType(nsIFrame::eLineParticipant);
 }
 
 /**
+ * Returns true iff aFrame explicitly prevents its descendants from floating
+ * (at least, down to the level of descendants which themselves are
+ * float-containing blocks -- those will manage the floating status of any
+ * lower-level descendents inside them, of course).
+ */
+static bool
+ShouldSuppressFloatingOfDescendants(nsIFrame* aFrame)
+{
+  return aFrame->IsFrameOfType(nsIFrame::eMathML) ||
+    aFrame->IsBoxFrame() ||
+    aFrame->GetType() == nsGkAtoms::flexContainerFrame;
+}
+
+/**
  * If any children require a block parent, return the first such child.
  * Otherwise return null.
  */
 static nsIContent*
 AnyKidsNeedBlockParent(nsIFrame *aFrameList)
 {
   for (nsIFrame *k = aFrameList; k; k = k->GetNextSibling()) {
     // Line participants, such as text and inline frames, can't be
@@ -3679,16 +3706,24 @@ nsCSSFrameConstructor::ConstructFrameFro
       aState.PushAbsoluteContainingBlock(nsnull, absoluteSaveState);
     } else if (!(bits & FCDATA_SKIP_ABSPOS_PUSH) &&
                maybeAbsoluteContainingBlockDisplay->IsPositioned()) {
       aState.PushAbsoluteContainingBlock(maybeAbsoluteContainingBlock,
                                          absoluteSaveState);
     }
 
     if (bits & FCDATA_USE_CHILD_ITEMS) {
+      NS_ASSERTION(!ShouldSuppressFloatingOfDescendants(newFrame),
+                   "uh oh -- this frame is supposed to _suppress_ floats, but "
+                   "we're about to push it as a float containing block...");
+
+      nsFrameConstructorSaveState floatSaveState;
+      if (newFrame->IsFloatContainingBlock()) {
+        aState.PushFloatContainingBlock(newFrame, floatSaveState);
+      }
       rv = ConstructFramesFromItemList(aState, aItem.mChildItems, newFrame,
                                        childItems);
     } else {
       // Process the child frames.
       rv = ProcessChildren(aState, content, styleContext, newFrame,
                            !(bits & FCDATA_DISALLOW_GENERATED_CONTENT),
                            childItems,
                            (bits & FCDATA_ALLOW_BLOCK_STYLES) != 0,
@@ -4326,16 +4361,22 @@ nsCSSFrameConstructor::FindDisplayData(c
   static const FrameConstructionDataByInt sDisplayData[] = {
     // To keep the hash table small don't add inline frames (they're
     // typically things like FONT and B), because we can quickly
     // find them if we need to.
     // XXXbz the "quickly" part is a bald-faced lie!
     { NS_STYLE_DISPLAY_INLINE,
       FULL_CTOR_FCDATA(FCDATA_IS_INLINE | FCDATA_IS_LINE_PARTICIPANT,
                        &nsCSSFrameConstructor::ConstructInline) },
+#ifdef MOZ_FLEXBOX
+    { NS_STYLE_DISPLAY_FLEX,
+      FCDATA_DECL(0, NS_NewFlexContainerFrame) },
+    { NS_STYLE_DISPLAY_INLINE_FLEX,
+      FCDATA_DECL(0, NS_NewFlexContainerFrame) },
+#endif // MOZ_FLEXBOX
     { NS_STYLE_DISPLAY_TABLE,
       FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructTable) },
     { NS_STYLE_DISPLAY_INLINE_TABLE,
       FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructTable) },
     { NS_STYLE_DISPLAY_TABLE_CAPTION,
       FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_ALLOW_BLOCK_STYLES |
                   FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_SKIP_ABSPOS_PUSH |
                   FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
@@ -5505,18 +5546,18 @@ nsCSSFrameConstructor::GetAbsoluteContai
 nsIFrame*
 nsCSSFrameConstructor::GetFloatContainingBlock(nsIFrame* aFrame)
 {
   // Starting with aFrame, look for a frame that is a float containing block.
   // IF we hit a mathml frame, bail out; we don't allow floating out of mathml
   // frames, because they don't seem to be able to deal.
   // The logic here needs to match the logic in ProcessChildren()
   for (nsIFrame* containingBlock = aFrame;
-       containingBlock && !containingBlock->IsFrameOfType(nsIFrame::eMathML) &&
-       !containingBlock->IsBoxFrame();
+       containingBlock &&
+         !ShouldSuppressFloatingOfDescendants(containingBlock);
        containingBlock = containingBlock->GetParent()) {
     if (containingBlock->IsFloatContainingBlock()) {
       return containingBlock;
     }
   }
 
   // If we didn't find a containing block, then there just isn't
   // one.... return null
@@ -8940,16 +8981,65 @@ nsCSSFrameConstructor::MaybeRecreateCont
     }
 #endif
     // Good enough to recreate frames for aFrame's parent's content; even if
     // aFrame's parent is a table pseudo, that'll be the right content node.
     *aResult = RecreateFramesForContent(parent->GetContent(), true);
     return true;
   }
 
+#ifdef MOZ_FLEXBOX
+  // Might need to reconstruct things if the removed frame's nextSibling is an
+  // anonymous flex item.  The removed frame might've been what divided two
+  // runs of inline content into two anonymous flex items, which would now
+  // need to be merged.
+  // NOTE: It's fine that we've advanced nextSibling past whitespace (up above);
+  // we're only interested in anonymous flex items here, and those can never
+  // be adjacent to whitespace, since they absorb contiguous runs of inline
+  // non-replaced content (including whitespace).
+  if (nextSibling && IsAnonymousFlexItem(nextSibling)) {
+    NS_ABORT_IF_FALSE(parent->GetType() == nsGkAtoms::flexContainerFrame,
+                      "anonymous flex items should only exist as children "
+                      "of flex container frames");
+#ifdef DEBUG
+    if (gNoisyContentUpdates) {
+      printf("nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval: "
+             "frame=");
+      nsFrame::ListTag(stdout, aFrame);
+      printf(" has an anonymous flex item as its next sibling\n");
+    }
+#endif // DEBUG
+    // Recreate frames for the flex container (the removed frame's parent)
+    *aResult = RecreateFramesForContent(parent->GetContent(), true);
+    return true;
+  }
+
+  // Might need to reconstruct things if the removed frame's nextSibling is
+  // null and its parent is an anonymous flex item. (This might be the last
+  // remaining child of that anonymous flex item, which can then go away.)
+  if (!nextSibling && IsAnonymousFlexItem(parent)) {
+    NS_ABORT_IF_FALSE(parent->GetParent() &&
+                      parent->GetParent()->GetType() == nsGkAtoms::flexContainerFrame,
+                      "anonymous flex items should only exist as children "
+                      "of flex container frames");
+#ifdef DEBUG
+    if (gNoisyContentUpdates) {
+      printf("nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval: "
+             "frame=");
+      nsFrame::ListTag(stdout, aFrame);
+      printf(" has an anonymous flex item as its parent\n");
+    }
+#endif // DEBUG
+    // Recreate frames for the flex container (the removed frame's grandparent)
+    *aResult = RecreateFramesForContent(parent->GetParent()->GetContent(),
+                                        true);
+    return true;
+  }
+#endif // MOZ_FLEXBOX
+
 #ifdef MOZ_XUL
   if (aFrame->GetType() == nsGkAtoms::popupSetFrame) {
     nsIRootBox* rootBox = nsIRootBox::GetRootBox(mPresShell);
     if (rootBox && rootBox->GetPopupSetFrame() == aFrame) {
       *aResult = ReconstructDocElementHierarchy();
       return true;
     }
   }
@@ -9212,16 +9302,126 @@ nsCSSFrameConstructor::sPseudoParentData
   },
   { // Table
     FULL_CTOR_FCDATA(FCDATA_SKIP_FRAMESET | FCDATA_USE_CHILD_ITEMS,
                      &nsCSSFrameConstructor::ConstructTable),
     &nsCSSAnonBoxes::table
   }
 };
 
+#ifdef MOZ_FLEXBOX
+void
+nsCSSFrameConstructor::CreateNeededAnonFlexItems(
+  nsFrameConstructorState& aState,
+  FrameConstructionItemList& aItems,
+  nsIFrame* aParentFrame)
+{
+  NS_ABORT_IF_FALSE(aParentFrame->GetType() == nsGkAtoms::flexContainerFrame,
+                    "Should only be called for items in a flex container frame");
+  if (aItems.IsEmpty()) {
+    return;
+  }
+
+  FCItemIterator iter(aItems);
+  do {
+    // Advance iter past children that don't want to be wrapped
+    if (iter.SkipItemsThatDontNeedAnonFlexItem(aState)) {
+      // Hit the end of the items without finding any remaining children that
+      // need to be wrapped. We're finished!
+      return;
+    }
+
+    // If our next potentially-wrappable child is whitespace, then see if
+    // there's anything wrappable immediately after it. If not, we just drop
+    // the whitespace and move on. (We're not supposed to create any anonymous
+    // flex items that _only_ contain whitespace).
+    if (iter.item().IsWhitespace(aState)) {
+      FCItemIterator afterWhitespaceIter(iter);
+      bool hitEnd = afterWhitespaceIter.SkipWhitespace(aState);
+      bool nextChildNeedsAnonFlexItem =
+        !hitEnd && afterWhitespaceIter.item().NeedsAnonFlexItem(aState);
+
+      if (!nextChildNeedsAnonFlexItem) {
+        // There's nothing after the whitespace that we need to wrap, so we
+        // just drop this run of whitespace.
+        iter.DeleteItemsTo(afterWhitespaceIter);
+        if (hitEnd) {
+          // Nothing left to do -- we're finished!
+          return;
+        }
+        // else, we have a next child and it does not want to be wrapped.  So,
+        // we jump back to the beginning of the loop to skip over that child
+        // (and anything else non-wrappable after it)
+        NS_ABORT_IF_FALSE(!iter.IsDone() &&
+                          !iter.item().NeedsAnonFlexItem(aState),
+                          "hitEnd and/or nextChildNeedsAnonFlexItem lied");
+        continue;
+      }
+    }
+
+    // Now |iter| points to the first child that needs to be wrapped in an
+    // anonymous flex item. Now we see how many children after it also want
+    // to be wrapped in an anonymous flex item.
+    FCItemIterator endIter(iter); // iterator to find the end of the group
+    endIter.SkipItemsThatNeedAnonFlexItem(aState);
+
+    NS_ASSERTION(iter != endIter,
+                 "Should've had at least one wrappable child to seek past");
+
+    // Now, we create the anonymous flex item to contain the children
+    // between |iter| and |endIter|.
+    nsIAtom* pseudoType = nsCSSAnonBoxes::anonymousFlexItem;
+    nsStyleContext* parentStyle = aParentFrame->GetStyleContext();
+    nsIContent* parentContent = aParentFrame->GetContent();
+    nsRefPtr<nsStyleContext> wrapperStyle =
+      mPresShell->StyleSet()->ResolveAnonymousBoxStyle(pseudoType, parentStyle);
+
+    static const FrameConstructionData sBlockFormattingContextFCData =
+      FCDATA_DECL(FCDATA_SKIP_FRAMESET | FCDATA_USE_CHILD_ITEMS,
+                  NS_NewBlockFormattingContext);
+
+    FrameConstructionItem* newItem =
+      new FrameConstructionItem(&sBlockFormattingContextFCData,
+                                // Use the content of our parent frame
+                                parentContent,
+                                // Lie about the tag; it doesn't matter anyway
+                                pseudoType,
+                                iter.item().mNameSpaceID,
+                                // no pending binding
+                                nsnull,
+                                wrapperStyle.forget(),
+                                true);
+
+    newItem->mIsAllInline = newItem->mHasInlineEnds =
+      newItem->mStyleContext->GetStyleDisplay()->IsInlineOutside();
+    newItem->mIsBlock = !newItem->mIsAllInline;
+
+    NS_ABORT_IF_FALSE(!newItem->mIsAllInline && newItem->mIsBlock,
+                      "expecting anonymous flex items to be block-level "
+                      "(this will make a difference when we encounter "
+                      "'flex-align: baseline')");
+
+    // Anonymous flex items induce line boundaries around their
+    // contents.
+    newItem->mChildItems.SetLineBoundaryAtStart(true);
+    newItem->mChildItems.SetLineBoundaryAtEnd(true);
+    // The parent of the items in aItems is also the parent of the items
+    // in mChildItems
+    newItem->mChildItems.SetParentHasNoXBLChildren(
+      aItems.ParentHasNoXBLChildren());
+
+    // Eat up all items between |iter| and |endIter| and put them in our
+    // wrapper. This advances |iter| to point to |endIter|.
+    iter.AppendItemsToList(endIter, newItem->mChildItems);
+
+    iter.InsertItem(newItem);
+  } while (!iter.IsDone());
+}
+#endif // MOZ_FLEXBOX
+
 /*
  * This function works as follows: we walk through the child list (aItems) and
  * find items that cannot have aParentFrame as their parent.  We wrap
  * continuous runs of such items into a FrameConstructionItem for a frame that
  * gets them closer to their desired parents.  For example, a run of non-row
  * children of a row-group will get wrapped in a row.  When we later construct
  * the frame for this wrapper (in this case for the row), it'll be the correct
  * parent for the cells in the set of items we wrapped or we'll wrap cells
@@ -9432,16 +9632,22 @@ nsCSSFrameConstructor::ConstructFramesFr
                                                    FrameConstructionItemList& aItems,
                                                    nsIFrame* aParentFrame,
                                                    nsFrameItems& aFrameItems)
 {
   aItems.SetTriedConstructingFrames();
 
   CreateNeededTablePseudos(aState, aItems, aParentFrame);
 
+#ifdef MOZ_FLEXBOX
+  if (aParentFrame->GetType() == nsGkAtoms::flexContainerFrame) {
+    CreateNeededAnonFlexItems(aState, aItems, aParentFrame);
+  }
+#endif // MOZ_FLEXBOX
+
 #ifdef DEBUG
   for (FCItemIterator iter(aItems); !iter.IsDone(); iter.Next()) {
     NS_ASSERTION(iter.item().DesiredParentType() == GetParentType(aParentFrame),
                  "Needed pseudos didn't get created; expect bad things");
   }
 #endif
 
   for (FCItemIterator iter(aItems); !iter.IsDone(); iter.Next()) {
@@ -9481,18 +9687,17 @@ nsCSSFrameConstructor::ProcessChildren(n
   bool haveFirstLetterStyle = false, haveFirstLineStyle = false;
   if (aAllowBlockStyles) {
     ShouldHaveSpecialBlockStyle(aContent, aStyleContext, &haveFirstLetterStyle,
                                 &haveFirstLineStyle);
   }
 
   // The logic here needs to match the logic in GetFloatContainingBlock()
   nsFrameConstructorSaveState floatSaveState;
-  if (aFrame->IsFrameOfType(nsIFrame::eMathML) ||
-      aFrame->IsBoxFrame()) {
+  if (ShouldSuppressFloatingOfDescendants(aFrame)) {
     aState.PushFloatContainingBlock(nsnull, floatSaveState);
   } else if (aFrame->IsFloatContainingBlock()) {
     aState.PushFloatContainingBlock(aFrame, floatSaveState);
   }
 
   nsFrameConstructorState::PendingBindingAutoPusher pusher(aState,
                                                            aPendingBinding);
 
@@ -10973,17 +11178,77 @@ nsCSSFrameConstructor::WipeContainingBlo
       !(aFrame->GetStateBits() & NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK) &&
       aItems.AnyItemsNeedBlockParent()) {
     RecreateFramesForContent(aFrame->GetContent(), true);
     return true;
   }
 
   nsIFrame* nextSibling = ::GetInsertNextSibling(aFrame, aPrevSibling);
 
-  // Situation #2 is a case when table pseudo-frames don't work out right
+#ifdef MOZ_FLEXBOX
+  // Situation #2 is a flex container frame into which we're inserting new
+  // inline non-replaced children, adjacent to an existing anonymous flex item.
+  if (aFrame->GetType() == nsGkAtoms::flexContainerFrame) {
+    FCItemIterator iter(aItems);
+
+    // Check if we're adding to-be-wrapped content right *after* an existing
+    // anonymous flex item (which would need to absorb this content).
+    if (aPrevSibling && IsAnonymousFlexItem(aPrevSibling) &&
+        iter.item().NeedsAnonFlexItem(aState)) {
+      RecreateFramesForContent(aFrame->GetContent(), true);
+      return true;
+    }
+
+    // Check if we're adding to-be-wrapped content right *before* an existing
+    // anonymous flex item (which would need to absorb this content).
+    if (nextSibling && IsAnonymousFlexItem(nextSibling)) {
+      // Jump to the last entry in the list
+      iter.SetToEnd();
+      iter.Prev();
+      if (iter.item().NeedsAnonFlexItem(aState)) {
+        RecreateFramesForContent(aFrame->GetContent(), true);
+        return true;
+      }
+    }
+  }
+
+  // Situation #3 is an anonymous flex item that's getting new children who
+  // don't want to be wrapped.
+  if (IsAnonymousFlexItem(aFrame)) {
+    nsIFrame* flexContainerFrame = aFrame->GetParent();
+    NS_ABORT_IF_FALSE(flexContainerFrame &&
+                      flexContainerFrame->GetType() == nsGkAtoms::flexContainerFrame,
+                      "anonymous flex items should only exist as children "
+                      "of flex container frames");
+
+    // We need to push a null float containing block to be sure that
+    // "NeedsAnonFlexItem" will know we're not honoring floats for this
+    // inserted content. (In particular, this is necessary in order for
+    // NeedsAnonFlexItem's "GetGeometricParent" call to return the correct
+    // result.) We're not honoring floats on this content because it has the
+    // _flex container_ as its parent in the content tree.
+    nsFrameConstructorSaveState floatSaveState;
+    aState.PushFloatContainingBlock(nsnull, floatSaveState);
+
+    FCItemIterator iter(aItems);
+    // Skip over things that _do_ need an anonymous flex item, because
+    // they're perfectly happy to go here -- they won't cause a reframe.
+    if (!iter.SkipItemsThatNeedAnonFlexItem(aState)) {
+      // We hit something that _doesn't_ need an anonymous flex item!
+      // Rebuild the flex container to bust it out.
+      RecreateFramesForContent(flexContainerFrame->GetContent(), true);
+      return true;
+    }
+
+    // If we get here, then everything in |aItems| needs to be wrapped in
+    // an anonymous flex item.  That's where it's already going - good!
+  }
+#endif // MOZ_FLEXBOX
+
+  // Situation #4 is a case when table pseudo-frames don't work out right
   ParentType parentType = GetParentType(aFrame);
   // If all the kids want a parent of the type that aFrame is, then we're all
   // set to go.  Indeed, there won't be any table pseudo-frames created between
   // aFrame and the kids, so those won't need to be merged with any table
   // pseudo-frames that might already be kids of aFrame.  If aFrame itself is a
   // table pseudo-frame, then all the kids in this list would have wanted a
   // frame of that type wrapping them anyway, so putting them inside it is ok.
   if (!aItems.AllWantParentType(parentType)) {
@@ -11805,16 +12070,69 @@ Iterator::SkipItemsWantingParentType(Par
     Next();
     if (IsDone()) {
       return true;
     }
   }
   return false;
 }
 
+#ifdef MOZ_FLEXBOX
+bool
+nsCSSFrameConstructor::FrameConstructionItem::
+  NeedsAnonFlexItem(const nsFrameConstructorState& aState)
+{
+  if (mFCData->mBits & FCDATA_IS_LINE_PARTICIPANT) {
+    // This will be an inline non-replaced box.
+    return true;
+  }
+
+  if (!(mFCData->mBits & FCDATA_DISALLOW_OUT_OF_FLOW) &&
+      aState.GetGeometricParent(mStyleContext->GetStyleDisplay(), nsnull)) {
+    // We're abspos or fixedpos, which means we'll spawn a placeholder which
+    // we'll need to wrap in an anonymous flex item.  So, we just treat
+    // _this_ frame as if _it_ needs to be wrapped in an anonymous flex item,
+    // and then when we spawn the placeholder, it'll end up in the right spot.
+    return true;
+  }
+
+  return false;
+}
+
+inline bool
+nsCSSFrameConstructor::FrameConstructionItemList::
+Iterator::SkipItemsThatNeedAnonFlexItem(
+  const nsFrameConstructorState& aState)
+{
+  NS_PRECONDITION(!IsDone(), "Shouldn't be done yet");
+  while (item().NeedsAnonFlexItem(aState)) {
+    Next();
+    if (IsDone()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+inline bool
+nsCSSFrameConstructor::FrameConstructionItemList::
+Iterator::SkipItemsThatDontNeedAnonFlexItem(
+  const nsFrameConstructorState& aState)
+{
+  NS_PRECONDITION(!IsDone(), "Shouldn't be done yet");
+  while (!(item().NeedsAnonFlexItem(aState))) {
+    Next();
+    if (IsDone()) {
+      return true;
+    }
+  }
+  return false;
+}
+#endif // MOZ_FLEXBOX
+
 inline bool
 nsCSSFrameConstructor::FrameConstructionItemList::
 Iterator::SkipWhitespace(nsFrameConstructorState& aState)
 {
   NS_PRECONDITION(!IsDone(), "Shouldn't be done yet");
   NS_PRECONDITION(item().IsWhitespace(aState), "Not pointing to whitespace?");
   do {
     Next();
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -911,16 +911,30 @@ private:
       }
       void SetToEnd() { mCurrent = mEnd; }
 
       // Skip over all items that want a parent type different from the given
       // one.  Return whether the iterator is done after doing that.  The
       // iterator must not be done when this is called.
       inline bool SkipItemsWantingParentType(ParentType aParentType);
 
+#ifdef MOZ_FLEXBOX
+      // Skip over non-replaced inline frames and positioned frames.
+      // Return whether the iterator is done after doing that.
+      // The iterator must not be done when this is called.
+      inline bool SkipItemsThatNeedAnonFlexItem(
+        const nsFrameConstructorState& aState);
+
+      // Skip to the first frame that is a non-replaced inline or is
+      // positioned.  Return whether the iterator is done after doing that.
+      // The iterator must not be done when this is called.
+      inline bool SkipItemsThatDontNeedAnonFlexItem(
+        const nsFrameConstructorState& aState);
+#endif // MOZ_FLEXBOX
+
       // Skip over whitespace.  Return whether the iterator is done after doing
       // that.  The iterator must not be done, and must be pointing to a
       // whitespace item when this is called.
       inline bool SkipWhitespace(nsFrameConstructorState& aState);
 
       // Remove the item pointed to by this iterator from its current list and
       // Append it to aTargetList.  This iterator is advanced to point to the
       // next item in its list.  aIter must not be done.  aOther must not be
@@ -1025,16 +1039,22 @@ private:
         NS_RELEASE(mContent);
       }
     }
 
     ParentType DesiredParentType() {
       return FCDATA_DESIRED_PARENT_TYPE(mFCData->mBits);
     }
 
+    // Indicates whether (when in a flexbox container) this item needs to be
+    // wrapped in an anonymous block.
+#ifdef MOZ_FLEXBOX
+    bool NeedsAnonFlexItem(const nsFrameConstructorState& aState);
+#endif // MOZ_FLEXBOX
+
     // Don't call this unless the frametree really depends on the answer!
     // Especially so for generated content, where we don't want to reframe
     // things.
     bool IsWhitespace(nsFrameConstructorState& aState) const;
 
     bool IsLineBoundary() const {
       return mIsBlock || (mFCData->mBits & FCDATA_IS_LINE_BREAK);
     }
@@ -1093,16 +1113,29 @@ private:
     // Child frame construction items.
     FrameConstructionItemList mChildItems;
 
   private:
     FrameConstructionItem(const FrameConstructionItem& aOther) MOZ_DELETE; /* not implemented */
   };
 
   /**
+   * Function to create the anonymous flex items that we need.
+   * aParentFrame _must_ be a nsFlexContainerFrame -- the caller is responsible
+   * for checking this.
+   * @param aItems the child frame construction items before pseudo creation
+   * @param aParentFrame the flex container frame
+   */
+#ifdef MOZ_FLEXBOX
+  void CreateNeededAnonFlexItems(nsFrameConstructorState& aState,
+                                    FrameConstructionItemList& aItems,
+                                    nsIFrame* aParentFrame);
+#endif // MOZ_FLEXBOX
+
+  /**
    * Function to create the table pseudo items we need.
    * @param aItems the child frame construction items before pseudo creation
    * @param aParentFrame the parent frame we're creating pseudos for
    */
   inline void CreateNeededTablePseudos(nsFrameConstructorState& aState,
                                        FrameConstructionItemList& aItems,
                                        nsIFrame* aParentFrame);
 
--- a/layout/base/nsStyleConsts.h
+++ b/layout/base/nsStyleConsts.h
@@ -387,16 +387,20 @@ static inline mozilla::css::Side operato
 #define NS_STYLE_DISPLAY_GRID_GROUP             22
 #define NS_STYLE_DISPLAY_GRID_LINE              23
 #define NS_STYLE_DISPLAY_STACK                  24
 #define NS_STYLE_DISPLAY_INLINE_STACK           25
 #define NS_STYLE_DISPLAY_DECK                   26
 #define NS_STYLE_DISPLAY_POPUP                  27
 #define NS_STYLE_DISPLAY_GROUPBOX               28
 #endif
+#ifdef MOZ_FLEXBOX
+#define NS_STYLE_DISPLAY_FLEX                   29
+#define NS_STYLE_DISPLAY_INLINE_FLEX            30
+#endif // MOZ_FLEXBOX
 
 // See nsStyleDisplay
 #define NS_STYLE_FLOAT_NONE                     0
 #define NS_STYLE_FLOAT_LEFT                     1
 #define NS_STYLE_FLOAT_RIGHT                    2
 
 // See nsStyleFont
 // We should eventually stop using the NS_STYLE_* variants here.
--- a/layout/generic/Makefile.in
+++ b/layout/generic/Makefile.in
@@ -88,16 +88,22 @@ CPPSRCS		= \
 		nsSubDocumentFrame.cpp \
 		nsTextFrameThebes.cpp \
 		nsTextFrameUtils.cpp \
 		TextOverflow.cpp \
 		nsTextRunTransformations.cpp \
 		nsViewportFrame.cpp \
 		$(NULL)
 
+ifdef MOZ_FLEXBOX
+CPPSRCS		+= \
+		nsFlexContainerFrame.cpp \
+		$(NULL)
+endif
+
 ifdef MOZ_MEDIA
 CPPSRCS		+= \
 		nsVideoFrame.cpp \
 		$(NULL)
 endif
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CMMSRCS		+= \
new file mode 100644
--- /dev/null
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/* This Source Code is subject to the terms of the Mozilla Public License
+ * version 2.0 (the "License"). You can obtain a copy of the License at
+ * http://mozilla.org/MPL/2.0/. */
+
+/* rendering object for CSS display: -moz-flex */
+
+#include "nsFlexContainerFrame.h"
+#include "nsPresContext.h"
+#include "nsStyleContext.h"
+#include "prlog.h"
+
+#ifdef PR_LOGGING 
+static PRLogModuleInfo* nsFlexContainerFrameLM = PR_NewLogModule("nsFlexContainerFrame");
+#endif /* PR_LOGGING */
+
+NS_IMPL_FRAMEARENA_HELPERS(nsFlexContainerFrame)
+
+nsIFrame*
+NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
+                         nsStyleContext* aContext)
+{
+  return new (aPresShell) nsFlexContainerFrame(aContext);
+}
+
+//----------------------------------------------------------------------
+
+/* virtual */
+nsFlexContainerFrame::~nsFlexContainerFrame()
+{
+}
+
+NS_QUERYFRAME_HEAD(nsFlexContainerFrame)
+  NS_QUERYFRAME_ENTRY(nsFlexContainerFrame)
+NS_QUERYFRAME_TAIL_INHERITING(nsFlexContainerFrameSuper)
+
+void
+nsFlexContainerFrame::DestroyFrom(nsIFrame* aDestructRoot)
+{
+  DestroyAbsoluteFrames(aDestructRoot);
+  nsFlexContainerFrameSuper::DestroyFrom(aDestructRoot);
+}
+
+nsIAtom*
+nsFlexContainerFrame::GetType() const
+{
+  return nsGkAtoms::flexContainerFrame;
+}
+
+#ifdef DEBUG
+NS_IMETHODIMP
+nsFlexContainerFrame::GetFrameName(nsAString& aResult) const
+{
+  return MakeFrameName(NS_LITERAL_STRING("FlexContainer"), aResult);
+}
+#endif // DEBUG
new file mode 100644
--- /dev/null
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+
+/* This Source Code is subject to the terms of the Mozilla Public License
+ * version 2.0 (the "License"). You can obtain a copy of the License at
+ * http://mozilla.org/MPL/2.0/. */
+
+/* rendering object for CSS display: -moz-flex */
+
+#ifndef nsFlexContainerFrame_h___
+#define nsFlexContainerFrame_h___
+
+#include "nsContainerFrame.h"
+#include "mozilla/Types.h"
+
+nsIFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
+                                   nsStyleContext* aContext);
+
+typedef nsContainerFrame nsFlexContainerFrameSuper;
+
+class nsFlexContainerFrame : public nsFlexContainerFrameSuper {
+  NS_DECL_FRAMEARENA_HELPERS
+  NS_DECL_QUERYFRAME_TARGET(nsFlexContainerFrame)
+  NS_DECL_QUERYFRAME
+
+  // Factory method:
+  friend nsIFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
+                                            nsStyleContext* aContext);
+
+  // nsIFrame overrides
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
+#ifdef DEBUG
+  NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
+#endif
+
+protected:
+  // Protected constructor & destructor
+  nsFlexContainerFrame(nsStyleContext* aContext) : nsFlexContainerFrameSuper(aContext) {}
+  virtual ~nsFlexContainerFrame();
+
+  // Protected nsIFrame overrides:
+  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+
+};
+
+#endif /* nsFlexContainerFrame_h___ */
--- a/layout/generic/nsFrameIdList.h
+++ b/layout/generic/nsFrameIdList.h
@@ -17,16 +17,19 @@ FRAME_ID(nsComboboxDisplayFrame)
 FRAME_ID(nsContainerFrame)
 FRAME_ID(nsContinuingTextFrame)
 FRAME_ID(nsDeckFrame)
 FRAME_ID(nsDocElementBoxFrame)
 FRAME_ID(nsFieldSetFrame)
 FRAME_ID(nsFileControlFrame)
 FRAME_ID(nsFirstLetterFrame)
 FRAME_ID(nsFirstLineFrame)
+#ifdef MOZ_FLEXBOX
+FRAME_ID(nsFlexContainerFrame)
+#endif // MOZ_FLEXBOX
 FRAME_ID(nsFormControlFrame)
 FRAME_ID(nsFrame)
 FRAME_ID(nsGfxButtonControlFrame)
 FRAME_ID(nsGfxCheckboxControlFrame)
 FRAME_ID(nsGfxRadioControlFrame)
 FRAME_ID(nsGridRowGroupFrame)
 FRAME_ID(nsGridRowLeafFrame)
 FRAME_ID(nsGroupBoxFrame)
--- a/layout/mathml/nsMathMLmoFrame.cpp
+++ b/layout/mathml/nsMathMLmoFrame.cpp
@@ -334,24 +334,34 @@ nsMathMLmoFrame::ProcessOperatorData()
       if (!prevSibling && nextSibling)
         form = NS_MATHML_OPERATOR_FORM_PREFIX;
       else if (prevSibling && !nextSibling)
         form = NS_MATHML_OPERATOR_FORM_POSTFIX;
     }
     mFlags &= ~NS_MATHML_OPERATOR_FORM; // clear the old form bits
     mFlags |= form;
 
-    // lookup the operator dictionary
-    float lspace = 0.0f;
-    float rspace = 0.0f;
-    nsAutoString data;
-    mMathMLChar.GetData(data);
-    bool found = nsMathMLOperators::LookupOperator(data, form, &mFlags, &lspace, &rspace);
-    if (found && (lspace || rspace)) {
-      // cache the default values of lspace & rspace that we get from the dictionary.
+    // Use the default value suggested by the MathML REC.
+    // http://www.w3.org/TR/MathML/chapter3.html#presm.mo.attrs
+    // thickmathspace = 5/18em
+    float lspace = 5.0/18.0;
+    float rspace = 5.0/18.0;
+    if (NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags)) {
+      // mMathMLChar has been reset in ProcessTextData so we can not find it
+      // in the operator dictionary. The operator dictionary always uses
+      // lspace = rspace = 0 for invisible operators.
+      lspace = rspace = 0.0;
+    } else {
+      // lookup the operator dictionary
+      nsAutoString data;
+      mMathMLChar.GetData(data);
+      nsMathMLOperators::LookupOperator(data, form, &mFlags, &lspace, &rspace);
+    }
+    if (lspace || rspace) {
+      // Cache the default values of lspace and rspace.
       // since these values are relative to the 'em' unit, convert to twips now
       nscoord em;
       nsRefPtr<nsFontMetrics> fm;
       nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
       GetEmHeight(fm, em);
 
       mEmbellishData.leadingSpace = NSToCoordRound(lspace * em);
       mEmbellishData.trailingSpace = NSToCoordRound(rspace * em);
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/mo-lspace-rspace-ref.html
@@ -0,0 +1,43 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>mo-lspace-rspace</title>
+  </head>
+
+  <body>
+
+    <p>
+      <!-- not in the operator dictionary -->
+      <math>
+        <mtext>_</mtext>
+        <mspace width="thickmathspace" height="0" depth="0"></mspace>
+        <mtext>MO</mtext>
+        <mspace width="thickmathspace" height="0" depth="0"></mspace>
+        <mtext>_</mtext>
+      </math>
+    </p>
+
+    <p>
+      <!-- operator.\u223F.infix = lspace:3 rspace:3 # sine wave -->
+      <math>
+        <mtext>_</mtext>
+        <mspace width="thinmathspace" height="0" depth="0"></mspace>
+        <mtext>&#x0223F;</mtext>
+        <mspace width="thinmathspace" height="0" depth="0"></mspace>
+        <mtext>_</mtext>
+      </math>
+    </p>
+
+    <p>
+      <!-- Invisible operator -->
+      <math>
+        <mtext>_</mtext>
+        <mtext>&#x02061;</mtext>
+        <mtext>_</mtext>
+      </math>
+    </p>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/mo-lspace-rspace.html
@@ -0,0 +1,39 @@
+<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
+<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>mo-lspace-rspace</title>
+  </head>
+
+  <body>
+
+    <p>
+      <!-- not in the operator dictionary -->
+      <math>
+        <mtext>_</mtext>
+        <mo>MO</mo>
+        <mtext>_</mtext>
+      </math>
+    </p>
+
+    <p>
+      <!-- operator.\u223F.infix = lspace:3 rspace:3 # sine wave -->
+      <math>
+        <mtext>_</mtext>
+        <mo>&#x0223F;</mo>
+        <mtext>_</mtext>
+      </math>
+    </p>
+
+    <p>
+      <!-- Invisible operator -->
+      <math>
+        <mtext>_</mtext>
+        <mo>&#x02061;</mo>
+        <mtext>_</mtext>
+      </math>
+    </p>
+
+  </body>
+</html>
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -96,9 +96,10 @@ fails == mstyle-5.xhtml mstyle-5-ref.xht
 != link-1.xhtml link-ref.xhtml
 == munderover-empty-scripts.html munderover-empty-scripts-ref.html
 == positive-namedspace.html positive-namedspace-ref.html
 == mtable-width.html mtable-width-ref.html
 == maction-selection.html maction-selection-ref.html
 == maction-dynamic-embellished-op.html maction-dynamic-embellished-op-ref.html
 == maction-dynamic-1.html maction-dynamic-1-ref.html
 == maction-dynamic-2.html maction-dynamic-2-ref.html
+== mo-lspace-rspace.html mo-lspace-rspace-ref.html
 == maction-dynamic-3.html maction-dynamic-3-ref.html
--- a/layout/style/nsCSSAnonBoxList.h
+++ b/layout/style/nsCSSAnonBoxList.h
@@ -57,16 +57,20 @@ CSS_ANON_BOX(pageContent, ":-moz-pagecon
 CSS_ANON_BOX(pageSequence, ":-moz-page-sequence")
 CSS_ANON_BOX(scrolledContent, ":-moz-scrolled-content")
 CSS_ANON_BOX(scrolledCanvas, ":-moz-scrolled-canvas")
 CSS_ANON_BOX(scrolledPageSequence, ":-moz-scrolled-page-sequence")
 CSS_ANON_BOX(columnContent, ":-moz-column-content")
 CSS_ANON_BOX(viewport, ":-moz-viewport")
 CSS_ANON_BOX(viewportScroll, ":-moz-viewport-scroll")
 
+// Inside a flex container, a contiguous run of non-replaced inline children
+// gets wrapped in an anonymous block, which is then treated as a flex item.
+CSS_ANON_BOX(anonymousFlexItem, ":-moz-anonymous-flex-item")
+
 #ifdef MOZ_XUL
 CSS_ANON_BOX(moztreecolumn, ":-moz-tree-column")
 CSS_ANON_BOX(moztreerow, ":-moz-tree-row")
 CSS_ANON_BOX(moztreeseparator, ":-moz-tree-separator")
 CSS_ANON_BOX(moztreecell, ":-moz-tree-cell")
 CSS_ANON_BOX(moztreeindentation, ":-moz-tree-indentation")
 CSS_ANON_BOX(moztreeline, ":-moz-tree-line")
 CSS_ANON_BOX(moztreetwisty, ":-moz-tree-twisty")
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -69,16 +69,19 @@ CSS_KEY(-moz-eventreerow, _moz_eventreer
 CSS_KEY(-moz-ethiopic-halehame, _moz_ethiopic_halehame)
 CSS_KEY(-moz-ethiopic-numeric, _moz_ethiopic_numeric)
 CSS_KEY(-moz-ethiopic-halehame-am, _moz_ethiopic_halehame_am)
 CSS_KEY(-moz-ethiopic-halehame-ti-er, _moz_ethiopic_halehame_ti_er)
 CSS_KEY(-moz-ethiopic-halehame-ti-et, _moz_ethiopic_halehame_ti_et)
 CSS_KEY(-moz-field, _moz_field)
 CSS_KEY(-moz-fieldtext, _moz_fieldtext)
 CSS_KEY(-moz-fit-content, _moz_fit_content)
+#ifdef MOZ_FLEXBOX
+CSS_KEY(-moz-flex, _moz_flex)
+#endif // MOZ_FLEXBOX
 CSS_KEY(-moz-grabbing, _moz_grabbing)
 CSS_KEY(-moz-grab, _moz_grab)
 CSS_KEY(-moz-grid-group, _moz_grid_group)
 CSS_KEY(-moz-grid-line, _moz_grid_line)
 CSS_KEY(-moz-grid, _moz_grid)
 CSS_KEY(-moz-groupbox, _moz_groupbox)
 CSS_KEY(-moz-gujarati, _moz_gujarati)
 CSS_KEY(-moz-gurmukhi, _moz_gurmukhi)
@@ -87,16 +90,19 @@ CSS_KEY(-moz-hidden-unscrollable, _moz_h
 CSS_KEY(-moz-hangul, _moz_hangul)
 CSS_KEY(-moz-hyperlinktext, _moz_hyperlinktext)
 CSS_KEY(-moz-html-cellhighlight, _moz_html_cellhighlight)
 CSS_KEY(-moz-html-cellhighlighttext, _moz_html_cellhighlighttext)
 CSS_KEY(-moz-image-rect, _moz_image_rect)
 CSS_KEY(-moz-info, _moz_info)
 CSS_KEY(-moz-initial, _moz_initial)
 CSS_KEY(-moz-inline-box, _moz_inline_box)
+#ifdef MOZ_FLEXBOX
+CSS_KEY(-moz-inline-flex, _moz_inline_flex)
+#endif // MOZ_FLEXBOX
 CSS_KEY(-moz-inline-grid, _moz_inline_grid)
 CSS_KEY(-moz-inline-stack, _moz_inline_stack)
 CSS_KEY(-moz-isolate, _moz_isolate)
 CSS_KEY(-moz-japanese-formal, _moz_japanese_formal)
 CSS_KEY(-moz-japanese-informal, _moz_japanese_informal)
 CSS_KEY(-moz-kannada, _moz_kannada)
 CSS_KEY(-moz-khmer, _moz_khmer)
 CSS_KEY(-moz-lao, _moz_lao)
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -883,16 +883,20 @@ const PRInt32 nsCSSProps::kDisplayKTable
   eCSSKeyword__moz_grid_group,    NS_STYLE_DISPLAY_GRID_GROUP,
   eCSSKeyword__moz_grid_line,     NS_STYLE_DISPLAY_GRID_LINE,
   eCSSKeyword__moz_stack,         NS_STYLE_DISPLAY_STACK,
   eCSSKeyword__moz_inline_stack,  NS_STYLE_DISPLAY_INLINE_STACK,
   eCSSKeyword__moz_deck,          NS_STYLE_DISPLAY_DECK,
   eCSSKeyword__moz_popup,         NS_STYLE_DISPLAY_POPUP,
   eCSSKeyword__moz_groupbox,      NS_STYLE_DISPLAY_GROUPBOX,
 #endif
+#ifdef MOZ_FLEXBOX
+  eCSSKeyword__moz_flex,          NS_STYLE_DISPLAY_FLEX,
+  eCSSKeyword__moz_inline_flex,   NS_STYLE_DISPLAY_INLINE_FLEX,
+#endif // MOZ_FLEXBOX
   eCSSKeyword_UNKNOWN,-1
 };
 
 const PRInt32 nsCSSProps::kEmptyCellsKTable[] = {
   eCSSKeyword_show,                 NS_STYLE_TABLE_EMPTY_CELLS_SHOW,
   eCSSKeyword_hide,                 NS_STYLE_TABLE_EMPTY_CELLS_HIDE,
   eCSSKeyword__moz_show_background, NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND,
   eCSSKeyword_UNKNOWN,-1
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -120,28 +120,38 @@ static void EnsureBlockDisplay(PRUint8& 
 {
   // see if the display value is already a block
   switch (display) {
   case NS_STYLE_DISPLAY_NONE :
     // never change display:none *ever*
   case NS_STYLE_DISPLAY_TABLE :
   case NS_STYLE_DISPLAY_BLOCK :
   case NS_STYLE_DISPLAY_LIST_ITEM :
+#ifdef MOZ_FLEXBOX
+  case NS_STYLE_DISPLAY_FLEX :
+#endif // MOZ_FLEXBOX
     // do not muck with these at all - already blocks
     // This is equivalent to nsStyleDisplay::IsBlockOutside.  (XXX Maybe we
     // should just call that?)
     // This needs to match the check done in
     // nsCSSFrameConstructor::FindMathMLData for <math>.
     break;
 
   case NS_STYLE_DISPLAY_INLINE_TABLE :
     // make inline tables into tables
     display = NS_STYLE_DISPLAY_TABLE;
     break;
 
+#ifdef MOZ_FLEXBOX
+  case NS_STYLE_DISPLAY_INLINE_FLEX:
+    // make inline flex containers into flex containers
+    display = NS_STYLE_DISPLAY_FLEX;
+    break;
+#endif // MOZ_FLEXBOX
+
   default :
     // make it a block
     display = NS_STYLE_DISPLAY_BLOCK;
   }
 }
 
 static nscoord CalcLengthWith(const nsCSSValue& aValue,
                               nscoord aFontSize,
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1591,25 +1591,31 @@ struct nsStyleDisplay {
            NS_STYLE_DISPLAY_INLINE_BLOCK == mDisplay;
     // Should TABLE_CELL and TABLE_CAPTION go here?  They have
     // block frames nested inside of them.
     // (But please audit all callers before changing.)
   }
 
   bool IsBlockOutside() const {
     return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
+#ifdef MOZ_FLEXBOX
+           NS_STYLE_DISPLAY_FLEX == mDisplay ||
+#endif // MOZ_FLEXBOX
            NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
            NS_STYLE_DISPLAY_TABLE == mDisplay;
   }
 
   static bool IsDisplayTypeInlineOutside(PRUint8 aDisplay) {
     return NS_STYLE_DISPLAY_INLINE == aDisplay ||
            NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay ||
            NS_STYLE_DISPLAY_INLINE_TABLE == aDisplay ||
            NS_STYLE_DISPLAY_INLINE_BOX == aDisplay ||
+#ifdef MOZ_FLEXBOX
+           NS_STYLE_DISPLAY_INLINE_FLEX == aDisplay ||
+#endif // MOZ_FLEXBOX
            NS_STYLE_DISPLAY_INLINE_GRID == aDisplay ||
            NS_STYLE_DISPLAY_INLINE_STACK == aDisplay;
   }
 
   bool IsInlineOutside() const {
     return IsDisplayTypeInlineOutside(mDisplay);
   }
 
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -1959,17 +1959,37 @@ var gCSSProperties = {
 	},
 	"display": {
 		domProp: "display",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "inline" ],
 		/* XXX none will really mess with other properties */
 		prerequisites: { "float": "none", "position": "static" },
-		other_values: [ "block", "list-item", "inline-block", "table", "inline-table", "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption", "none" ],
+		other_values: [
+			"block",
+			"list-item",
+			"inline-block",
+			"table",
+			"inline-table",
+			"table-row-group",
+			"table-header-group",
+			"table-footer-group",
+			"table-row",
+			"table-column-group",
+			"table-column",
+			"table-cell",
+			"table-caption",
+/* XXXdholbert In builds with MOZ_FLEXBOX enabled, this should be uncommented.
+   (This would be #ifdef MOZ_FLEXBOX, if that worked in JS files.)
+			"-moz-flex",
+			"-moz-inline-flex",
+*/
+			"none"
+		],
 		invalid_values: []
 	},
 	"empty-cells": {
 		domProp: "emptyCells",
 		inherited: true,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "show" ],
 		other_values: [ "hide", "-moz-show-background" ],
--- a/layout/style/ua.css
+++ b/layout/style/ua.css
@@ -160,16 +160,22 @@
   text-overflow: inherit;
   /* inherit the outer frame's display, otherwise we turn into an inline */
   display: inherit !important;
   /* Carry through our parent's height so that %-height children get
   their heights set */
   height: 100%;
 }
 
+*|*::-moz-anonymous-flex-item {
+  /* Anonymous blocks that wrap contiguous runs of inline non-replaced
+   * content inside of a flex container. */
+  display: block;
+}
+
 *|*::-moz-page-sequence, *|*::-moz-scrolled-page-sequence {
   /* Collection of pages in print/print preview. Visual styles may only appear
    * in print preview. */
   display: block !important;
   background: -moz-linear-gradient(top, #606060, #8a8a8a) fixed;
   height: 100%;
 }
 
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -21,21 +21,18 @@ pref("toolkit.browser.cacheRatioHeight",
 
 // How long before a content view (a handle to a remote scrollable object)
 // expires.
 pref("toolkit.browser.contentViewExpire", 3000);
 
 pref("toolkit.defaultChromeURI", "chrome://browser/content/browser.xul");
 pref("browser.chromeURL", "chrome://browser/content/");
 
-pref("browser.tabs.warnOnClose", true);
 pref("browser.tabs.remote", false);
 
-pref("toolkit.screen.lock", false);
-
 // From libpref/src/init/all.js, extended to allow a slightly wider zoom range.
 pref("zoom.minPercent", 20);
 pref("zoom.maxPercent", 400);
 pref("toolkit.zoomManager.zoomValues", ".2,.3,.5,.67,.8,.9,1,1.1,1.2,1.33,1.5,1.7,2,2.4,3,4");
 
 // Mobile will use faster, less durable mode.
 pref("toolkit.storage.synchronous", 0);
 
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -42,34 +42,16 @@
 
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-feature android:name="android.hardware.camera" android:required="false"/>
     <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
 
     <!-- App requires OpenGL ES 2.0 -->
     <uses-feature android:glEsVersion="0x00020000" android:required="true" />
 
-    <compatible-screens>
-        <!-- all small size screens -->
-        <screen android:screenSize="small" android:screenDensity="ldpi" />
-        <screen android:screenSize="small" android:screenDensity="mdpi" />
-        <screen android:screenSize="small" android:screenDensity="hdpi" />
-        <screen android:screenSize="small" android:screenDensity="xhdpi" />
-        <!-- all normal size screens -->
-        <screen android:screenSize="normal" android:screenDensity="ldpi" />
-        <screen android:screenSize="normal" android:screenDensity="mdpi" />
-        <screen android:screenSize="normal" android:screenDensity="hdpi" />
-        <screen android:screenSize="normal" android:screenDensity="xhdpi" />
-        <!-- all large size screens -->
-        <screen android:screenSize="large" android:screenDensity="ldpi" />
-        <screen android:screenSize="large" android:screenDensity="mdpi" />
-        <screen android:screenSize="large" android:screenDensity="hdpi" />
-        <screen android:screenSize="large" android:screenDensity="xhdpi" />
-    </compatible-screens>
-
     <application android:label="@MOZ_APP_DISPLAYNAME@"
 		 android:icon="@drawable/icon"
                  android:name="org.mozilla.gecko.GeckoApplication"
 #if MOZILLA_OFFICIAL
 		 android:debuggable="false">
 #else
 		 android:debuggable="true">
 #endif
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -616,16 +616,15 @@ abstract public class BrowserApp extends
         share.setEnabled(!(scheme.equals("about") || scheme.equals("chrome") ||
                            scheme.equals("file") || scheme.equals("resource")));
 
         // Disable save as PDF for about:home and xul pages
         saveAsPDF.setEnabled(!(tab.getURL().equals("about:home") ||
                                tab.getContentType().equals("application/vnd.mozilla.xul+xml")));
 
         // Disable find in page for about:home, since it won't work on Java content
-        if (!tab.getURL().equals("about:home"))
-            findInPage.setEnabled(true);
+        findInPage.setEnabled(!tab.getURL().equals("about:home"));
 
         charEncoding.setVisible(GeckoPreferences.getCharEncodingState());
 
         return true;
     }
 }
--- a/mobile/android/base/DoorHangerPopup.java
+++ b/mobile/android/base/DoorHangerPopup.java
@@ -34,17 +34,18 @@ public class DoorHangerPopup extends Pop
         super(aContext);
         mContext = aContext;
         mInflated = false;
    }
 
     private void init() {
         setBackgroundDrawable(new BitmapDrawable());
         setOutsideTouchable(true);
-        setWindowLayoutMode(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        setWindowLayoutMode(GeckoApp.mAppContext.isTablet() ? ViewGroup.LayoutParams.WRAP_CONTENT : ViewGroup.LayoutParams.FILL_PARENT,
+            ViewGroup.LayoutParams.WRAP_CONTENT);
 
         LayoutInflater inflater = LayoutInflater.from(mContext);
         RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.doorhangerpopup, null);
         mContent = (LinearLayout) layout.findViewById(R.id.doorhanger_container);
         
         setContentView(layout);
         mInflated = true;
     }
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -504,16 +504,17 @@ abstract public class GeckoApp
             R.id.bookmark,
             R.id.forward,
             R.id.save_as_pdf,
             R.id.share,
             R.id.char_encoding,
             R.id.find_in_page,
             R.id.addons,
             R.id.downloads,
+            R.id.apps,
             R.id.site_settings
         };
 
         for (int id : ids) {
             if (aMenu.findItem(id) == null)
                 continue;
             aMenu.findItem(id).setVisible(false);
         }
@@ -687,16 +688,19 @@ abstract public class GeckoApp
                 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Permissions:Get", null));
                 return true;
             case R.id.addons:
                 loadUrlInTab("about:addons");
                 return true;
             case R.id.downloads:
                 loadUrlInTab("about:downloads");
                 return true;
+            case R.id.apps:
+                loadUrlInTab("about:apps");
+                return true;
             case R.id.char_encoding:
                 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("CharEncoding:Get", null));
                 return true;
             case R.id.find_in_page:
                 mFindInPageBar.show();
                 return true;
             case R.id.desktop_mode:
                 Tab selectedTab = Tabs.getInstance().getSelectedTab();
@@ -1219,17 +1223,17 @@ abstract public class GeckoApp
                     return;
                 Log.i(LOGTAG, "Open " + url + " (" + origin + ")");
                 startActivity(intent);
             } else if (event.equals("WebApps:Install")) {
                 String name = message.getString("name");
                 String launchPath = message.getString("launchPath");
                 String iconURL = message.getString("iconURL");
                 String uniqueURI = message.getString("uniqueURI");
-                GeckoAppShell.createShortcut(name, launchPath, uniqueURI, iconURL, "webapp");
+                GeckoAppShell.installWebApp(name, launchPath, uniqueURI, iconURL);
             } else if (event.equals("WebApps:Uninstall")) {
                 String uniqueURI = message.getString("uniqueURI");
                 GeckoAppShell.uninstallWebApp(uniqueURI);
             } else if (event.equals("DesktopMode:Changed")) {
                 int tabId = message.getInt("tabId");
                 boolean desktopMode = message.getBoolean("desktopMode");
                 final Tab tab = Tabs.getInstance().getTab(tabId);
                 if (tab == null)
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -840,16 +840,45 @@ public class GeckoAppShell
                     intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, aURI);
 
                 intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
                 GeckoApp.mAppContext.sendBroadcast(intent);
             }
         });
     }
 
+    public static void installWebApp(String aTitle, String aURI, String aUniqueURI, String aIconURL) {
+        int index = WebAppAllocator.getInstance(GeckoApp.mAppContext).findAndAllocateIndex(aUniqueURI);
+        GeckoProfile profile = GeckoProfile.get(GeckoApp.mAppContext, "webapp" + index);
+        File prefs = profile.getFile("prefs.js");
+
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            in = GeckoApp.mAppContext.getResources().openRawResource(R.raw.webapp_prefs_js);
+            out = new FileOutputStream(prefs);
+            byte buf[]=new byte[1024];
+            int len;
+            while ((len = in.read(buf)) > 0) {
+                out.write(buf, 0, len);
+            }
+        } catch(FileNotFoundException ex) {
+        } catch(IOException ex) {
+        } finally {
+            try {
+                if (out != null)
+                    out.close();
+                if (in != null)
+                    in.close();
+            } catch(IOException ex) {
+            }
+        }
+        createShortcut(aTitle, aURI, aUniqueURI, aIconURL, "webapp");
+    }
+
     public static void uninstallWebApp(final String uniqueURI) {
         // On uninstall, we need to do a couple of things:
         //   1. nuke the running app process.
         //   2. nuke the profile that was assigned to that webapp
         getHandler().post(new Runnable() {
             public void run() {
                 int index = WebAppAllocator.getInstance(GeckoApp.mAppContext).releaseIndexForApp(uniqueURI);
 
--- a/mobile/android/base/GeckoProfile.java
+++ b/mobile/android/base/GeckoProfile.java
@@ -138,16 +138,24 @@ public final class GeckoProfile {
                 Log.d(LOGTAG, "Found profile dir: " + mDir.getAbsolutePath());
             }
         } catch (IOException ioe) {
             Log.e(LOGTAG, "Error getting profile dir", ioe);
         }
         return mDir;
     }
 
+    public File getFile(String aFile) {
+        File f = getDir();
+        if (f == null)
+            return null;
+
+        return new File(f, aFile);
+    }
+
     public File getFilesDir() {
         return mContext.getFilesDir();
     }
 
     public boolean shouldRestoreSession() {
         Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - start check sessionstore.js exists");
         File dir = getDir();
         if (dir == null)
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -286,25 +286,27 @@ RES_LAYOUT = \
   $(NULL)
  
 RES_LAYOUT_LAND_V14 = \
   res/layout-land-v14/browser_toolbar.xml \
   $(NULL)
 
 RES_LAYOUT_XLARGE = \
   res/layout-xlarge/browser_toolbar.xml \
+  res/layout-xlarge/doorhangerpopup.xml \
   res/layout-xlarge/gecko_app.xml \
   res/layout-xlarge/remote_tabs_child.xml \
   res/layout-xlarge/remote_tabs_group.xml \
   res/layout-xlarge/tabs_panel_toolbar.xml \
   res/layout-xlarge/tabs_row.xml \
   $(NULL)
 
 RES_LAYOUT_SW600DP = \
   res/layout-sw600dp/browser_toolbar.xml \
+  res/layout-sw600dp/doorhangerpopup.xml \
   res/layout-sw600dp/gecko_app.xml \
   res/layout-sw600dp/remote_tabs_child.xml \
   res/layout-sw600dp/remote_tabs_group.xml \
   res/layout-sw600dp/tabs_panel_toolbar.xml \
   res/layout-sw600dp/tabs_row.xml \
   $(NULL)
 
 RES_VALUES = \
@@ -865,16 +867,20 @@ RES_COLOR = \
   res/color/menu_item_title.xml \
   $(NULL)
 
 RES_MENU = \
   res/menu/awesomebar_contextmenu.xml \
   res/menu/titlebar_contextmenu.xml \
   $(NULL)
 
+RES_RAW = \
+  res/raw/webapp_prefs_js \
+  $(NULL)
+
 JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar
 
 ifdef MOZ_CRASHREPORTER
 FENNEC_PP_JAVA_FILES += CrashReporter.java
 MOZ_ANDROID_DRAWABLES += mobile/android/base/resources/drawable/crash_reporter.png
 RES_LAYOUT += res/layout/crash_reporter.xml
 endif
 
@@ -921,17 +927,17 @@ MOZ_ANDROID_DRAWABLES += \
   mobile/android/base/resources/drawable/tabs_tray_active_selector.xml          \
   mobile/android/base/resources/drawable/tabs_tray_default_selector.xml         \
   mobile/android/base/resources/drawable/tabs_tray_list_divider.xml             \
   mobile/android/base/resources/drawable/shadow.png                             \
   $(NULL)
 
 MOZ_ANDROID_DRAWABLES += $(shell if test -e $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/android-resources.mn; then cat $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/android-resources.mn | tr '\n' ' ';  fi)
 
-RESOURCES=$(RES_LAYOUT) $(RES_LAYOUT_LAND_V14) $(RES_LAYOUT_XLARGE) $(RES_LAYOUT_SW600DP) $(RES_VALUES) $(RES_VALUES_V11) $(RES_VALUES_XLARGE) $(RES_VALUES_SW600DP) $(RES_VALUES_LAND_V14) $(RES_VALUES_SW600DP_V14) $(RES_XML) $(RES_ANIM) $(RES_DRAWABLE_NODPI) $(RES_DRAWABLE_BASE) $(RES_DRAWABLE_LDPI) $(RES_DRAWABLE_HDPI) $(RES_DRAWABLE_MDPI_V11) $(RES_DRAWABLE_HDPI_V11) $(RES_DRAWABLE_XHDPI_V11) $(RES_DRAWABLE_LAND_V14) $(RES_DRAWABLE_LAND_MDPI_V14) $(RES_DRAWABLE_LAND_HDPI_V14) $(RES_DRAWABLE_LAND_XHDPI_V14) $(RES_DRAWABLE_XLARGE_MDPI) $(RES_DRAWABLE_XLARGE_HDPI) $(RES_DRAWABLE_XLARGE_XHDPI) $(RES_DRAWABLE_SW600DP_MDPI) $(RES_DRAWABLE_SW600DP_HDPI) $(RES_DRAWABLE_SW600DP_XHDPI) $(RES_COLOR) $(RES_MENU)
+RESOURCES=$(RES_LAYOUT) $(RES_LAYOUT_LAND_V14) $(RES_LAYOUT_XLARGE) $(RES_LAYOUT_SW600DP) $(RES_VALUES) $(RES_VALUES_V11) $(RES_VALUES_XLARGE) $(RES_VALUES_SW600DP) $(RES_VALUES_LAND_V14) $(RES_VALUES_SW600DP_V14) $(RES_XML) $(RES_ANIM) $(RES_DRAWABLE_NODPI) $(RES_DRAWABLE_BASE) $(RES_DRAWABLE_LDPI) $(RES_DRAWABLE_HDPI) $(RES_DRAWABLE_MDPI_V11) $(RES_DRAWABLE_HDPI_V11) $(RES_DRAWABLE_XHDPI_V11) $(RES_DRAWABLE_LAND_V14) $(RES_DRAWABLE_LAND_MDPI_V14) $(RES_DRAWABLE_LAND_HDPI_V14) $(RES_DRAWABLE_LAND_XHDPI_V14) $(RES_DRAWABLE_XLARGE_MDPI) $(RES_DRAWABLE_XLARGE_HDPI) $(RES_DRAWABLE_XLARGE_XHDPI) $(RES_DRAWABLE_SW600DP_MDPI) $(RES_DRAWABLE_SW600DP_HDPI) $(RES_DRAWABLE_SW600DP_XHDPI) $(RES_COLOR) $(RES_MENU) $(RES_RAW)
 
 RES_DIRS= \
   res/layout              \
   res/layout-land-v14     \
   res/layout-xlarge       \
   res/layout-sw600dp      \
   res/values              \
   res/values-v11          \
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -42,16 +42,20 @@
 
 <!ENTITY history_today_section "Today">
 <!ENTITY history_yesterday_section "Yesterday">
 <!ENTITY history_week_section "7 days ago">
 <!ENTITY history_older_section "Older than 7 days">
 
 <!ENTITY reload "Reload">
 <!ENTITY forward "Forward">
+<!ENTITY menu "Menu">
+<!ENTITY back "Back">
+<!ENTITY stop "Stop">
+<!ENTITY site_security "Site Security">
 
 <!ENTITY close_tab "Close Tab">
 <!ENTITY new_tab "New Tab">
 <!-- Localization note (num_tabs) : Number of tabs is always more than one. 
      We can't use android plural forms, sadly. See bug #753859. -->
 <!ENTITY num_tabs "&#037;d tabs">
 <!ENTITY new_tab_opened "New tab opened">
 
@@ -87,16 +91,17 @@
 <!ENTITY pref_sync "Sync">
 <!ENTITY pref_search_suggestions "Show search suggestions">
 <!ENTITY pref_import_android "Import from Android">
 
 <!ENTITY quit "Quit">
 
 <!ENTITY addons "Add-ons">
 <!ENTITY downloads "Downloads">
+<!ENTITY apps "Apps">
 <!ENTITY char_encoding "Character Encoding">
 
 <!ENTITY share "Share">
 <!ENTITY share_title "Share via">
 <!ENTITY save_as_pdf "Save as PDF">
 <!ENTITY find_in_page "Find in Page">
 <!ENTITY desktop_mode "Request Desktop Site">
 
--- a/mobile/android/base/locales/en-US/sync_strings.dtd
+++ b/mobile/android/base/locales/en-US/sync_strings.dtd
@@ -36,16 +36,18 @@
 <!ENTITY sync.input.server.label 'Server URL'>
   
 <!-- Setup Fail -->
 <!ENTITY sync.title.fail.label 'Cannot Set Up &syncBrand.shortName.label;'>
 <!ENTITY sync.subtitle.fail.label '&syncBrand.fullName.label; could not connect to the server. Would you like to try again?'>
 <!ENTITY sync.button.tryagain.label 'Try again'>
 <!ENTITY sync.button.manual.label 'Manual Setup'>
 <!ENTITY sync.subtitle.nointernet.label 'No internet connection available.'>
+<!ENTITY sync.subtitle.failaccount.label 'Account creation on your device failed.'>
+<!ENTITY sync.subtitle.failmultiple.label 'Do you have more than one Firefox installed? Currently, &syncBrand.fullName.label; only supports one Firefox installation at a time. Please uninstall other instances to use &syncBrand.shortName.label;.'>
   
 <!-- Setup Success -->
 <!ENTITY sync.title.success.label 'Setup Complete'>
 <!ENTITY sync.subtitle.success.label1 'Your data is now being downloaded in the background. You can go to Settings to manage your account, or start browsing with &brandShortName;.'>
 <!ENTITY sync.settings.label 'Settings'>
 <!ENTITY sync.subtitle.manage.label1 'Your &syncBrand.fullName.label; account is already set up. You can go to Settings to manage your account, or launch &brandShortName;.'>
 
 <!-- Pair Device -->
--- a/mobile/android/base/resources/layout-land-v14/browser_toolbar.xml
+++ b/mobile/android/base/resources/layout-land-v14/browser_toolbar.xml
@@ -7,19 +7,21 @@
               android:id="@+id/browser_toolbar"
               style="@style/BrowserToolbar">
 
     <RelativeLayout android:id="@+id/address_bar"
                     style="@style/AddressBar"
                     android:background="@drawable/address_bar_bg">
 
         <ImageButton android:id="@+id/back"
+                     android:contentDescription="@string/back"
                      style="@style/AddressBar.ImageButton.Unused"/>
 
         <ImageButton android:id="@+id/forward"
+                     android:contentDescription="@string/forward"
                      style="@style/AddressBar.ImageButton.Unused"/>
 
         <LinearLayout android:id="@+id/menu_items"
                       android:layout_width="0dip"
                       android:layout_height="0dip"
                       android:visibility="gone"/>
 
         <ImageView android:id="@+id/spacer"
@@ -46,16 +48,17 @@
                      android:gravity="center_horizontal"/>
 
         <ImageButton android:id="@+id/menu"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="@dimen/browser_toolbar_height"
                      android:layout_toLeftOf="@id/spacer"
                      android:gravity="center_vertical"
                      android:src="@drawable/menu"
+                     android:contentDescription="@string/menu"
                      android:background="@drawable/action_bar_button"
                      android:paddingLeft="10dip"
                      android:paddingRight="10dip"
                      android:visibility="gone"/>
         
         <Button android:id="@+id/awesome_bar"
                 style="@style/AddressBar.Button"
                 android:layout_width="fill_parent"
@@ -91,30 +94,33 @@
                       android:layout_alignRight="@id/awesome_bar"
                       android:orientation="horizontal">
 
             <ImageButton android:id="@+id/reader"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/reader"
+                         android:contentDescription="@string/reader_mode"
                          android:visibility="gone"/>
 
             <ImageButton android:id="@+id/site_security"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/site_security_level"
+                         android:contentDescription="@string/site_security"
                          android:visibility="gone"/>
 
             <ImageButton android:id="@+id/stop"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/urlbar_stop"
+                         android:contentDescription="@string/stop"
                          android:visibility="gone"/>
 
         </LinearLayout>
 
          <ImageView android:id="@+id/shadow"
                     android:layout_width="fill_parent"
                     android:layout_height="2dp"
                     android:layout_alignParentBottom="true"
--- a/mobile/android/base/resources/layout-sw600dp/browser_toolbar.xml
+++ b/mobile/android/base/resources/layout-sw600dp/browser_toolbar.xml
@@ -30,16 +30,17 @@
                      android:gravity="center_horizontal"/>
 
         <ImageButton android:id="@+id/menu"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="56dip"
                      android:layout_alignParentRight="true"
                      android:gravity="center_vertical"
                      android:src="@drawable/menu"
+                     android:contentDescription="@string/menu"
                      android:background="@drawable/action_bar_button"
                      android:paddingLeft="14dip"
                      android:paddingRight="14dip"
                      android:visibility="gone"/>
 
         <LinearLayout android:id="@+id/menu_items"
                       android:layout_width="wrap_content"
                       android:layout_height="fill_parent"
@@ -68,26 +69,28 @@
         <ImageButton android:id="@+id/forward"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="64dip"
                      android:layout_height="40dip"
                      android:layout_centerVertical="true"
                      android:layout_alignLeft="@id/awesome_bar"
                      android:paddingLeft="22dp"
                      android:src="@drawable/ic_menu_forward"
+                     android:contentDescription="@string/forward"
                      android:background="@drawable/address_bar_forward_button"/>
 
         <ImageButton android:id="@+id/back"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="50dip"
                      android:layout_height="50dip"
                      android:layout_centerVertical="true"
                      android:layout_marginLeft="-28dp"
                      android:layout_alignLeft="@id/awesome_bar"
                      android:src="@drawable/ic_menu_back"
+                     android:contentDescription="@string/back"
                      android:background="@drawable/address_bar_back_button"/>
 
         <ImageButton android:id="@+id/favicon"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="21.33dip"
                      android:layout_height="21.33dip"
                      android:layout_marginLeft="10dip"
                      android:layout_centerVertical="true"
@@ -101,30 +104,33 @@
                       android:layout_alignRight="@id/awesome_bar"
                       android:orientation="horizontal">
 
             <ImageButton android:id="@+id/reader"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/reader"
+                         android:contentDescription="@string/reader_mode"
                          android:visibility="gone"/>
 
             <ImageButton android:id="@+id/site_security"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/site_security_level"
+                         android:contentDescription="@string/site_security"
                          android:visibility="gone"/>
 
             <ImageButton android:id="@+id/stop"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/urlbar_stop"
+                         android:contentDescription="@string/stop"
                          android:visibility="gone"/>
 
         </LinearLayout>
 
          <ImageView android:id="@+id/shadow"
                     android:layout_width="fill_parent"
                     android:layout_height="2dp"
                     android:layout_alignParentBottom="true"
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/layout-sw600dp/doorhangerpopup.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content">
+
+    <ScrollView android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="24dip"
+                android:layout_alignParentTop="true"
+                android:minWidth="200dip"
+                android:maxWidth="600dip"
+                android:background="@drawable/doorhanger_popup_bg">
+
+        <LinearLayout android:id="@+id/doorhanger_container"
+                      android:layout_width="fill_parent"
+                      android:layout_height="wrap_content"
+                      android:orientation="vertical"/>
+
+    </ScrollView>
+
+    <ImageView android:layout_width="44dip"
+               android:layout_height="16dip"
+               android:layout_marginLeft="4dip"
+               android:layout_marginTop="9dip"
+               android:layout_alignParentTop="true"
+               android:src="@drawable/doorhanger_arrow"
+               android:scaleType="fitXY"/>
+
+</RelativeLayout>
--- a/mobile/android/base/resources/layout-xlarge/browser_toolbar.xml
+++ b/mobile/android/base/resources/layout-xlarge/browser_toolbar.xml
@@ -30,16 +30,17 @@
                      android:gravity="center_horizontal"/>
 
         <ImageButton android:id="@+id/menu"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="56dip"
                      android:layout_alignParentRight="true"
                      android:gravity="center_vertical"
                      android:src="@drawable/menu"
+                     android:contentDescription="@string/menu"
                      android:background="@drawable/action_bar_button"
                      android:paddingLeft="14dip"
                      android:paddingRight="14dip"
                      android:visibility="gone"/>
 
         <LinearLayout android:id="@+id/menu_items"
                       android:layout_width="wrap_content"
                       android:layout_height="fill_parent"
@@ -68,26 +69,28 @@
         <ImageButton android:id="@+id/forward"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="64dip"
                      android:layout_height="40dip"
                      android:layout_centerVertical="true"
                      android:layout_alignLeft="@id/awesome_bar"
                      android:paddingLeft="22dp"
                      android:src="@drawable/ic_menu_forward"
+                     android:contentDescription="@string/forward"
                      android:background="@drawable/address_bar_forward_button"/>
 
         <ImageButton android:id="@+id/back"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="50dip"
                      android:layout_height="50dip"
                      android:layout_centerVertical="true"
                      android:layout_marginLeft="-28dp"
                      android:layout_alignLeft="@id/awesome_bar"
                      android:src="@drawable/ic_menu_back"
+                     android:contentDescription="@string/back"
                      android:background="@drawable/address_bar_back_button"/>
 
         <ImageButton android:id="@+id/favicon"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="21.33dip"
                      android:layout_height="21.33dip"
                      android:layout_marginLeft="10dip"
                      android:layout_centerVertical="true"
@@ -101,30 +104,33 @@
                       android:layout_alignRight="@id/awesome_bar"
                       android:orientation="horizontal">
 
             <ImageButton android:id="@+id/reader"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/reader"
+                         android:contentDescription="@string/reader_mode"
                          android:visibility="gone"/>
 
             <ImageButton android:id="@+id/site_security"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/site_security_level"
+                         android:contentDescription="@string/site_security"
                          android:visibility="gone"/>
 
             <ImageButton android:id="@+id/stop"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/urlbar_stop"
+                         android:contentDescription="@string/stop"
                          android:visibility="gone"/>
 
         </LinearLayout>
 
          <ImageView android:id="@+id/shadow"
                     android:layout_width="fill_parent"
                     android:layout_height="2dp"
                     android:layout_alignParentBottom="true"
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/layout-xlarge/doorhangerpopup.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content">
+
+    <ScrollView android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="24dip"
+                android:layout_alignParentTop="true"
+                android:minWidth="200dip"
+                android:maxWidth="600dip"
+                android:background="@drawable/doorhanger_popup_bg">
+
+        <LinearLayout android:id="@+id/doorhanger_container"
+                      android:layout_width="fill_parent"
+                      android:layout_height="wrap_content"
+                      android:orientation="vertical"/>
+
+    </ScrollView>
+
+    <ImageView android:layout_width="44dip"
+               android:layout_height="16dip"
+               android:layout_marginLeft="4dip"
+               android:layout_marginTop="9dip"
+               android:layout_alignParentTop="true"
+               android:src="@drawable/doorhanger_arrow"
+               android:scaleType="fitXY"/>
+
+</RelativeLayout>
--- a/mobile/android/base/resources/layout/browser_toolbar.xml
+++ b/mobile/android/base/resources/layout/browser_toolbar.xml
@@ -7,19 +7,21 @@
               android:id="@+id/browser_toolbar"
               style="@style/BrowserToolbar">
 
     <RelativeLayout android:id="@+id/address_bar"
                     style="@style/AddressBar"
                     android:background="@drawable/address_bar_bg">
 
         <ImageButton android:id="@+id/back"
+                     android:contentDescription="@string/back"
                      style="@style/AddressBar.ImageButton.Unused"/>
 
         <ImageButton android:id="@+id/forward"
+                     android:contentDescription="@string/forward"
                      style="@style/AddressBar.ImageButton.Unused"/>
 
         <LinearLayout android:id="@+id/menu_items"
                       android:layout_width="0dip"
                       android:layout_height="0dip"
                       android:visibility="gone"/>
                       
         <ImageView android:id="@+id/spacer"
@@ -46,16 +48,17 @@
                      android:gravity="center_horizontal"/>
 
         <ImageButton android:id="@+id/menu"
                      style="@style/AddressBar.ImageButton"
                      android:layout_width="@dimen/browser_toolbar_height"
                      android:layout_toLeftOf="@id/spacer"
                      android:gravity="center_vertical"
                      android:src="@drawable/menu"
+                     android:contentDescription="@string/menu"
                      android:background="@drawable/action_bar_button"
                      android:paddingLeft="12dip"
                      android:paddingRight="12dip"
                      android:visibility="gone"/>
         
         <Button android:id="@+id/awesome_bar"
                 style="@style/AddressBar.Button"
                 android:layout_width="fill_parent"
@@ -91,30 +94,33 @@
                       android:layout_alignRight="@id/awesome_bar"
                       android:orientation="horizontal">
 
             <ImageButton android:id="@+id/reader"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/reader"
+                         android:contentDescription="@string/reader_mode"
                          android:visibility="gone"/>
 
             <ImageButton android:id="@+id/site_security"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/site_security_level"
+                         android:contentDescription="@string/site_security"
                          android:visibility="gone"/>
 
             <ImageButton android:id="@+id/stop"
                          style="@style/AddressBar.ImageButton"
                          android:layout_width="24dip"
                          android:layout_height="24dip"
                          android:src="@drawable/urlbar_stop"
+                         android:contentDescription="@string/stop"
                          android:visibility="gone"/>
 
         </LinearLayout>
 
          <ImageView android:id="@+id/shadow"
                     android:layout_width="fill_parent"
                     android:layout_height="2dp"
                     android:layout_alignParentBottom="true"
--- a/mobile/android/base/resources/layout/sync_setup_failure.xml
+++ b/mobile/android/base/resources/layout/sync_setup_failure.xml
@@ -11,23 +11,32 @@
   <ImageView
     style="@style/SyncTopIcon" />
   <TextView
     style="@style/SyncTextTitle"
     android:text="@string/sync_title_fail" />
   </LinearLayout>
 
   <TextView
+    android:id="@+id/failure_subtitle1"
     style="@style/SyncTextItem"
     android:layout_below="@id/failure_top"
-    android:layout_above="@+id/failure_bottom"
     android:padding="20dp"
     android:text="@string/sync_subtitle_fail" />
+
+  <TextView
+    android:id="@+id/failure_subtitle2"
+    style="@style/SyncTextItem"
+    android:layout_below="@id/failure_subtitle1"
+    android:paddingLeft="20dp"
+    android:paddingRight="20dp"
+    android:text="@string/sync_subtitle_failmultiple" />
+
   <LinearLayout
-    android:id="@id/failure_bottom"
+    android:id="@+id/failure_bottom"
     style="@style/SyncBottom"
     android:orientation="horizontal" >
 
     <Button
       style="@style/SyncButton"
       android:onClick="tryAgainClickHandler"
       android:text="@string/sync_button_tryagain" />
 
--- a/mobile/android/base/resources/menu-sw600dp/gecko_menu.xml.in
+++ b/mobile/android/base/resources/menu-sw600dp/gecko_menu.xml.in
@@ -45,16 +45,19 @@
           gecko:title="@string/site_settings_title" />
 
     <item gecko:id="@+id/addons"
           gecko:title="@string/addons"/>
 
     <item gecko:id="@+id/downloads"
           gecko:title="@string/downloads"/>
 
+    <item gecko:id="@+id/apps"
+          gecko:title="@string/apps"/>
+
     <item gecko:id="@+id/char_encoding"
           gecko:visible="false"
           gecko:title="@string/char_encoding"/>
 
     <item gecko:id="@+id/settings"
           gecko:title="@string/settings" />
 
 #ifdef MOZ_PROFILING
--- a/mobile/android/base/resources/menu-v11/gecko_menu.xml.in
+++ b/mobile/android/base/resources/menu-v11/gecko_menu.xml.in
@@ -42,16 +42,19 @@
           gecko:title="@string/site_settings_title" />
 
     <item gecko:id="@+id/addons"
           gecko:title="@string/addons"/>
 
     <item gecko:id="@+id/downloads"
           gecko:title="@string/downloads"/>
 
+    <item gecko:id="@+id/apps"
+          gecko:title="@string/apps"/>
+
     <item gecko:id="@+id/char_encoding"
           gecko:visible="false"
           gecko:title="@string/char_encoding"/>
 
     <item gecko:id="@+id/settings"
           gecko:title="@string/settings" />
 
 #ifdef MOZ_PROFILING
--- a/mobile/android/base/resources/menu-xlarge/gecko_menu.xml.in
+++ b/mobile/android/base/resources/menu-xlarge/gecko_menu.xml.in
@@ -45,16 +45,19 @@
           gecko:title="@string/site_settings_title" />
 
     <item gecko:id="@+id/addons"
           gecko:title="@string/addons"/>
 
     <item gecko:id="@+id/downloads"
           gecko:title="@string/downloads"/>
 
+    <item gecko:id="@+id/apps"
+          gecko:title="@string/apps"/>
+
     <item gecko:id="@+id/char_encoding"
           gecko:visible="false"
           gecko:title="@string/char_encoding"/>
 
     <item gecko:id="@+id/settings"
           gecko:title="@string/settings" />
 
 #ifdef MOZ_PROFILING
--- a/mobile/android/base/resources/menu/gecko_menu.xml.in
+++ b/mobile/android/base/resources/menu/gecko_menu.xml.in
@@ -40,16 +40,19 @@
           android:title="@string/site_settings_title" />
 
     <item android:id="@+id/addons"
           android:title="@string/addons"/>
 
     <item android:id="@+id/downloads"
           android:title="@string/downloads"/>
 
+    <item android:id="@+id/apps"
+          android:title="@string/apps"/>
+
     <item android:id="@+id/char_encoding"
           android:visible="false"
           android:title="@string/char_encoding"/>
 
     <item android:id="@+id/settings"
           android:title="@string/settings" />
 
 #ifdef MOZ_PROFILING
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/raw/webapp_prefs_js
@@ -0,0 +1,22 @@
+/* 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/. */
+
+pref("browser.download.folderList", 1);
+
+// Disable all add-on locations other than the profile (which can't be disabled this way)
+pref("extensions.enabledScopes", 1);
+// Auto-disable any add-ons that are "dropped in" to the profile
+pref("extensions.autoDisableScopes", 1);
+// Disable add-on installation via the web-exposed APIs
+pref("xpinstall.enabled", false);
+
+// Blocklist preferences
+pref("extensions.blocklist.enabled", true);
+pref("extensions.blocklist.interval", 86400);
+// Controls what level the blocklist switches from warning about items to forcibly
+// blocking them.
+pref("extensions.blocklist.level", 2);
+pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%PING_COUNT%/%TOTAL_PING_COUNT%/%DAYS_SINCE_LAST_PING%/");
+pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
+pref("extensions.blocklist.itemURL", "https://addons.mozilla.org/%LOCALE%/%APP%/blocked/%blockID%");
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -94,22 +94,27 @@
   <string name="pref_font_size_large">&pref_font_size_large;</string>
   <string name="pref_font_size_xlarge">&pref_font_size_xlarge;</string>
   <string name="pref_sync">&pref_sync;</string>
   <string name="pref_search_suggestions">&pref_search_suggestions;</string>
   <string name="pref_import_android">&pref_import_android;</string>
 
   <string name="reload">&reload;</string>
   <string name="forward">&forward;</string>
+  <string name="menu">&menu;</string>
+  <string name="back">&back;</string>
+  <string name="stop">&stop;</string>
+  <string name="site_security">&site_security;</string>
   <string name="close_tab">&close_tab;</string>
   <string name="new_tab">&new_tab;</string>
   <string name="new_tab_opened">&new_tab_opened;</string>
   <string name="num_tabs">&num_tabs;</string>
   <string name="addons">&addons;</string>
   <string name="downloads">&downloads;</string>
+  <string name="apps">&apps;</string>
   <string name="char_encoding">&char_encoding;</string>
   <!-- This string only appears in developer builds, which
        is why it is not localizable. -->
   <string name="toggle_profiling">Toggle Profiling</string>
 
   <string name="site_settings_title">&site_settings_title;</string>
   <string name="site_settings_cancel">&site_settings_cancel;</string>
   <string name="site_settings_clear">&site_settings_clear;</string>
--- a/mobile/android/base/sync/setup/Constants.java
+++ b/mobile/android/base/sync/setup/Constants.java
@@ -32,18 +32,19 @@ public class Constants {
    * <p>
    * Corresponding value should be a String JSON-encoding an object, the keys of
    * which are the stage names to skip. For example:
    * <code>"{ \"stageToSkip\": 0 }"</code>.
    */
   public static final String EXTRAS_KEY_STAGES_TO_SKIP = "skip";
 
   // Constants for Activities.
-  public static final String INTENT_EXTRA_IS_SETUP = "isSetup";
-  public static final String INTENT_EXTRA_IS_PAIR  = "isPair";
+  public static final String INTENT_EXTRA_IS_SETUP        = "isSetup";
+  public static final String INTENT_EXTRA_IS_PAIR         = "isPair";
+  public static final String INTENT_EXTRA_IS_ACCOUNTERROR = "isAccountError";
 
   public static final int FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION =
     Intent.FLAG_ACTIVITY_REORDER_TO_FRONT |
     Intent.FLAG_ACTIVITY_NO_ANIMATION;
 
   // Constants for Account Authentication.
   public static final String AUTH_NODE_DEFAULT    = "https://auth.services.mozilla.com/";
   public static final String AUTH_NODE_PATHNAME   = "user/";
--- a/mobile/android/base/sync/setup/activities/AccountActivity.java
+++ b/mobile/android/base/sync/setup/activities/AccountActivity.java
@@ -248,20 +248,17 @@ public class AccountActivity extends Acc
       public void run() {
         Account account = SyncAccounts.createSyncAccount(syncAccount);
         boolean isSuccess = (account != null);
         if (!isSuccess) {
           setResult(RESULT_CANCELED);
           runOnUiThread(new Runnable() {
             @Override
             public void run() {
-              // Use default error.
-              // TODO: Bug 766499: Show specific error message when Android fails on Account creation.
-              Logger.debug(LOG_TAG, "displayFailure()");
-              displayFailure(AuthenticationResult.FAILURE_OTHER);
+              displayFailure(AuthenticationResult.FAILURE_ACCOUNT);
             }
           });
           return;
         }
 
         // Account created successfully.
         clearErrors();
 
@@ -289,32 +286,39 @@ public class AccountActivity extends Acc
       progressDialog.dismiss();
     }
   }
 
   private void displayFailure(final AuthenticationResult result) {
     runOnUiThread(new Runnable() {
       @Override
       public void run() {
+        Intent intent;
         switch (result) {
         case FAILURE_USERNAME:
           // No such username. Don't leak whether the username exists.
         case FAILURE_PASSWORD:
           findViewById(R.id.cred_error).setVisibility(View.VISIBLE);
           usernameInput.requestFocus();
           break;
         case FAILURE_SERVER:
           findViewById(R.id.server_error).setVisibility(View.VISIBLE);
           serverInput.requestFocus();
           break;
+        case FAILURE_ACCOUNT:
+          intent = new Intent(mContext, SetupFailureActivity.class);
+          intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
+          intent.putExtra(Constants.INTENT_EXTRA_IS_ACCOUNTERROR, true);
+          startActivity(intent);
+          break;
         case FAILURE_OTHER:
         default:
           // Display default error screen.
           Logger.debug(LOG_TAG, "displaying default failure.");
-          Intent intent = new Intent(mContext, SetupFailureActivity.class);
+          intent = new Intent(mContext, SetupFailureActivity.class);
           intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
           startActivity(intent);
         }
       }
     });
     return;
   }
 
--- a/mobile/android/base/sync/setup/activities/SetupFailureActivity.java
+++ b/mobile/android/base/sync/setup/activities/SetupFailureActivity.java
@@ -1,35 +1,53 @@
 /* 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/. */
 
 package org.mozilla.gecko.sync.setup.activities;
 
 import org.mozilla.gecko.R;
+import org.mozilla.gecko.sync.setup.Constants;
 
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
+import android.widget.TextView;
 
 public class SetupFailureActivity extends Activity {
   private Context mContext;
 
   @Override
   public void onCreate(Bundle savedInstanceState) {
     setTheme(R.style.SyncTheme);
     super.onCreate(savedInstanceState);
     setContentView(R.layout.sync_setup_failure);
     mContext = this.getApplicationContext();
+
+    // Modify general error message if necessary.
+    Bundle extras = this.getIntent().getExtras();
+    if (extras != null) {
+      boolean isAccountError = extras.getBoolean(Constants.INTENT_EXTRA_IS_ACCOUNTERROR);
+      if (isAccountError) {
+        TextView subtitle1 = (TextView) findViewById(R.id.failure_subtitle1);
+        // Display error for multiple accounts.
+        // TODO: Remove when Bug 761206 is resolved (support for multiple versions).
+        TextView subtitle2 = (TextView) findViewById(R.id.failure_subtitle2);
+        subtitle1.setText(getString(R.string.sync_subtitle_failaccount));
+        subtitle2.setVisibility(View.VISIBLE);
+        subtitle2.setText(getString(R.string.sync_subtitle_failmultiple));
+      }
+    }
   }
 
   public void manualClickHandler(View target) {
     Intent intent = new Intent(mContext, AccountActivity.class);
+    intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
     startActivity(intent);
     overridePendingTransition(0, 0);
     finish();
   }
 
   public void tryAgainClickHandler(View target) {
     finish();
   }
--- a/mobile/android/base/sync/setup/activities/SetupSyncActivity.java
+++ b/mobile/android/base/sync/setup/activities/SetupSyncActivity.java
@@ -74,16 +74,23 @@ public class SetupSyncActivity extends A
     setTheme(R.style.SyncTheme);
     Logger.info(LOG_TAG, "Called SetupSyncActivity.onCreate.");
     super.onCreate(savedInstanceState);
 
     // Set Activity variables.
     mContext = getApplicationContext();
     Logger.debug(LOG_TAG, "AccountManager.get(" + mContext + ")");
     mAccountManager = AccountManager.get(mContext);
+
+    // Set "screen on" flag for this activity. Screen will not automatically dim as long as this
+    // activity is at the top of the stack.
+    // Attempting to set this flag more than once causes hanging, so we set it here, not in onResume().
+    Window w = getWindow();
+    w.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    Logger.debug(LOG_TAG, "Successfully set screen-on flag.");
   }
 
   @Override
   public void onResume() {
     Logger.info(LOG_TAG, "Called SetupSyncActivity.onResume.");
     super.onResume();
 
     if (!hasInternet()) {
@@ -100,21 +107,16 @@ public class SetupSyncActivity extends A
         finishResume(accts);
       }
     });
   }
 
   public void finishResume(Account[] accts) {
     Logger.debug(LOG_TAG, "Finishing Resume after fetching accounts.");
 
-    // Set "screen on" flag.
-    Logger.debug(LOG_TAG, "Setting screen-on flag.");
-    Window w = getWindow();
-    w.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-
     if (accts.length == 0) { // Start J-PAKE for pairing if no accounts present.
       Logger.debug(LOG_TAG, "No accounts; starting J-PAKE receiver.");
       displayReceiveNoPin();
       if (jClient != null) {
         // Mark previous J-PAKE as finished. Don't bother propagating back up to this Activity.
         jClient.finished = true;
       }
       jClient = new JPakeClient(this);
@@ -426,48 +428,53 @@ public class SetupSyncActivity extends A
           resultBundle.putString(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNTTYPE_SYNC);
           resultBundle.putString(AccountManager.KEY_AUTHTOKEN, Constants.ACCOUNTTYPE_SYNC);
           setAccountAuthenticatorResult(resultBundle);
         }
         displayResultAndFinish(isSuccess);
       }
     });
   }
+
   /*
    * Helper functions
    */
-
   private void activateButton(Button button, boolean toActivate) {
     button.setEnabled(toActivate);
     button.setClickable(toActivate);
   }
 
   private void enablePinEntry(boolean toEnable) {
     row1.setEnabled(toEnable);
     row2.setEnabled(toEnable);
     row3.setEnabled(toEnable);
   }
 
   /**
    * Displays Sync account setup result to user.
    *
    * @param isSetup
-   *          true is account was set up successfully, false otherwise.
+   *          true if account was set up successfully, false otherwise.
    */
   private void displayResult(boolean isSuccess) {
     Intent intent = null;
     if (isSuccess) {
       intent = new Intent(mContext, SetupSuccessActivity.class);
-    }  else {
+      intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
+      intent.putExtra(Constants.INTENT_EXTRA_IS_SETUP, !pairWithPin);
+      startActivity(intent);
+      finish();
+    } else {
       intent = new Intent(mContext, SetupFailureActivity.class);
+      intent.putExtra(Constants.INTENT_EXTRA_IS_ACCOUNTERROR, true);
+      intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
+      intent.putExtra(Constants.INTENT_EXTRA_IS_SETUP, !pairWithPin);
+      startActivity(intent);
+      // Do not finish, so user can retry setup by hitting "back."
     }
-    intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
-    intent.putExtra(Constants.INTENT_EXTRA_IS_SETUP, !pairWithPin);
-    startActivity(intent);
-    finish();
   }
 
   /**
    * Validate PIN entry fields to check if the three PIN entry fields are all
    * filled in.
    *
    * @return true, if all PIN fields have 4 characters, false otherwise
    */
--- a/mobile/android/base/sync/setup/auth/AuthenticationResult.java
+++ b/mobile/android/base/sync/setup/auth/AuthenticationResult.java
@@ -1,9 +1,9 @@
 /* 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/. */
 
 package org.mozilla.gecko.sync.setup.auth;
 
 public enum AuthenticationResult {
-  SUCCESS, FAILURE_USERNAME, FAILURE_PASSWORD, FAILURE_SERVER, FAILURE_OTHER
+  SUCCESS, FAILURE_USERNAME, FAILURE_PASSWORD, FAILURE_SERVER, FAILURE_ACCOUNT, FAILURE_OTHER
 }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1410,16 +1410,22 @@ var SelectionHandler = {
 
   observe: function sh_observe(aSubject, aTopic, aData) {
     let data = JSON.parse(aData);
 
     if (this._active)
       this.endSelection(data.x, data.y);
   },
 
+  notifySelectionChanged: function sh_notifySelectionChanged(aDoc, aSel, aReason) {
+    // If the selection was removed, call endSelection() to clean up
+    if (aSel == "" && aReason == Ci.nsISelectionListener.NO_REASON)
+      this.endSelection();
+  },
+
   // aX/aY are in top-level window browser coordinates
   startSelection: function sh_startSelection(aElement, aX, aY) {
     // Clear out any existing selection
     if (this._active)
       this.endSelection();
 
     // Get the element's view
     this._view = aElement.ownerDocument.defaultView;
@@ -1455,56 +1461,56 @@ var SelectionHandler = {
     }
 
     // If there isn't an appropriate selection, bail
     if (!selection.rangeCount || !selection.getRangeAt(0) || !selection.toString().trim().length) {
       selection.collapseToStart();
       return;
     }
 
+    // Add a listener to end the selection if it's removed programatically
+    selection.QueryInterface(Ci.nsISelectionPrivate).addSelectionListener(this);
+
     // Initialize the cache
     this.cache = {};
     this.updateCacheForSelection();
-    this.updateCacheOffset();
 
     this.showHandles();
     this._active = true;
   },
 
   // aX/aY are in top-level window browser coordinates
   moveSelection: function sh_moveSelection(aIsStartHandle, aX, aY) {
-    let contentWindow = BrowserApp.selectedBrowser.contentWindow;
-    
     /* XXX bug 765367: Because the handles are in the document, the element
        will always be the handle the user touched. These checks are disabled
        until we can figure out a way to get the element under the handle.
+    let contentWindow = BrowserApp.selectedBrowser.contentWindow;
     let element = ElementTouchHelper.elementFromPoint(contentWindow, aX, aY);
     if (!element)
       element = ElementTouchHelper.anyElementFromPoint(contentWindow, aX, aY);
 
     // The element can be null if it's outside the viewport. We also want
     // to avoid setting focus in a textbox [Bugs 654352 & 667243] and limit
     // the selection to the initial content window (don't leave or enter iframes).
     if (!element || element instanceof Ci.nsIDOMHTMLInputElement ||
                     element instanceof Ci.nsIDOMHTMLTextAreaElement ||
                     element.ownerDocument.defaultView != this._view)
       return;
     */
 
     // Update the handle position as it's dragged
     if (aIsStartHandle) {
-      this._start.style.left = aX + this.cache.offset.x + "px";
-      this._start.style.top = aY + this.cache.offset.y + "px";
+      this._start.style.left = aX + this._view.scrollX + "px";
+      this._start.style.top = aY + this._view.scrollY + "px";
     } else {
-      this._end.style.left = aX + this.cache.offset.x + "px";
-      this._end.style.top = aY + this.cache.offset.y + "px";
+      this._end.style.left = aX + this._view.scrollX + "px";
+      this._end.style.top = aY + this._view.scrollY + "px";
     }
 
-    // Send mouse events to the top-level window
-    let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+    let cwu = this._view.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
 
     // The handles work the same on both LTR and RTL pages, but the underlying selection
     // works differently, so we need to reverse how we send mouse events on RTL pages.
     if (this._isRTL) {
       // Position the caret at the end handle using a fake mouse click
       if (!aIsStartHandle)
         this._sendEndMouseEvents(cwu, false);
 
@@ -1573,57 +1579,73 @@ var SelectionHandler = {
       return;
 
     cwu.sendMouseEventToWindow("mousedown", x, y, 0, 0, useShift ? Ci.nsIDOMNSEvent.SHIFT_MASK : 0, true);
     cwu.sendMouseEventToWindow("mouseup", x, y, 0, 0, useShift ? Ci.nsIDOMNSEvent.SHIFT_MASK : 0, true);
   },
 
   // aX/aY are in top-level window browser coordinates
   endSelection: function sh_endSelection(aX, aY) {
+    if (!this._active)
+      return;
+
+    this._active = false;
     this.hideHandles();
 
     let selectedText = "";
     if (this._view) {
       let selection = this._view.getSelection();
       if (selection) {
         selectedText = selection.toString().trim();
         selection.removeAllRanges();
+        selection.QueryInterface(Ci.nsISelectionPrivate).removeSelectionListener(this);
       }
     }
 
     // Only try copying text if there's text to copy!
     if (arguments.length == 2 && selectedText.length) {
       let contentWindow = BrowserApp.selectedBrowser.contentWindow;
       let element = ElementTouchHelper.elementFromPoint(contentWindow, aX, aY);
       if (!element)
         element = ElementTouchHelper.anyElementFromPoint(contentWindow, aX, aY);
 
       // Only try copying text if the tap happens in the same view
       if (element.ownerDocument.defaultView == this._view) {
-        let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
-        let scrollX = {}, scrollY = {};
-        cwu.getScrollXY(false, scrollX, scrollY);
-
-        // aX/aY already accounts for the top-level scroll, add that back from the cache.offset values
-        let pointInSelection = (aX - this.cache.offset.x + scrollX.value > this.cache.rect.left &&
-                                aX - this.cache.offset.x + scrollX.value < this.cache.rect.right) &&
-                               (aY - this.cache.offset.y + scrollY.value > this.cache.rect.top &&
-                                aY - this.cache.offset.y + scrollY.value < this.cache.rect.bottom);
+        let offset = this._getViewOffset();
+        let pointInSelection = (aX - offset.x > this.cache.rect.left  &&
+                                aX - offset.x < this.cache.rect.right) &&
+                               (aY - offset.y > this.cache.rect.top &&
+                                aY - offset.y < this.cache.rect.bottom);
         if (pointInSelection) {
           let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
           clipboard.copyString(selectedText);
           NativeWindow.toast.show(Strings.browser.GetStringFromName("selectionHelper.textCopied"), "short");
         }
       }
     }
 
     this._isRTL = false;
     this._view = null;
     this.cache = null;
-    this._active = false;
+  },
+
+  _getViewOffset: function sh_getViewOffset() {
+    let offset = { x: 0, y: 0 };
+    let win = this._view;
+
+    // Recursively look through frames to compute the total position offset.
+    while (win.frameElement) {
+      let rect = win.frameElement.getBoundingClientRect();
+      offset.x += rect.left;
+      offset.y += rect.top;
+
+      win = win.parent;
+    }
+
+    return offset;
   },
 
   // Returns true if the selection has been reversed. Takes optional aIsStartHandle
   // param to decide whether the selection has been reversed.
   updateCacheForSelection: function sh_updateCacheForSelection(aIsStartHandle) {
     let range = this._view.getSelection().getRangeAt(0);
     this.cache.rect = range.getBoundingClientRect();
 
@@ -1639,48 +1661,24 @@ var SelectionHandler = {
     }
 
     this.cache.start = start;
     this.cache.end = end;
 
     return selectionReversed;
   },
 
-  updateCacheOffset: function sh_updateCacheOffset() {
-    let offset = { x: 0, y: 0 };
-    let cwu = null, scrollX = {}, scrollY = {};
-    let win = this._view;
-
-    // Recursively look through frames to compute the total scroll offset. This is
-    // necessary for positioning the handles correctly.
-    while (win) {
-      cwu = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
-      cwu.getScrollXY(false, scrollX, scrollY);
-
-      offset.x += scrollX.value;
-      offset.y += scrollY.value;
-
-      // Break if there are no more frames to process
-      if (!win.frameElement)
-        break;
-
-      win = win.frameElement.contentWindow;
-    }
-
-    this.cache.offset = offset;
-  },
-
   // Adjust start/end positions to account for scroll, and account for the dimensions of the
   // handle elements to ensure the handles point exactly at the ends of the selection.
   positionHandles: function sh_positionHandles() {
-    this._start.style.left = (this.cache.start.x + this.cache.offset.x - this.HANDLE_WIDTH - this.HANDLE_PADDING) + "px";
-    this._start.style.top = (this.cache.start.y + this.cache.offset.y - this.HANDLE_VERTICAL_OFFSET) + "px";
-
-    this._end.style.left = (this.cache.end.x + this.cache.offset.x - this.HANDLE_PADDING) + "px";
-    this._end.style.top = (this.cache.end.y + this.cache.offset.y - this.HANDLE_VERTICAL_OFFSET) + "px";
+    this._start.style.left = (this.cache.start.x + this._view.scrollX - this.HANDLE_WIDTH - this.HANDLE_PADDING) + "px";
+    this._start.style.top = (this.cache.start.y + this._view.scrollY - this.HANDLE_VERTICAL_OFFSET) + "px";
+
+    this._end.style.left = (this.cache.end.x + this._view.scrollX - this.HANDLE_PADDING) + "px";
+    this._end.style.top = (this.cache.end.y + this._view.scrollY - this.HANDLE_VERTICAL_OFFSET) + "px";
   },
 
   showHandles: function sh_showHandles() {
     let doc = this._view.document;
     this._start = doc.getAnonymousElementByAttribute(doc.documentElement, "anonid", "selection-handle-start");
     this._end = doc.getAnonymousElementByAttribute(doc.documentElement, "anonid", "selection-handle-end");
 
     if (!this._start || !this._end) {
@@ -1727,19 +1725,16 @@ var SelectionHandler = {
 
   handleEvent: function sh_handleEvent(aEvent) {
     let isStartHandle = (aEvent.target == this._start);
 
     switch (aEvent.type) {
       case "touchstart":
         aEvent.preventDefault();
 
-        // Update the offset in case we scrolled between touches
-        this.updateCacheOffset();
-
         let touch = aEvent.changedTouches[0];
         this._touchId = touch.identifier;
 
         // Keep track of what part of the handle the user touched
         let rect = aEvent.target.getBoundingClientRect();
         this._touchDelta = { x: touch.clientX - rect.left,
                              y: touch.clientY - rect.top };
 
--- a/mobile/android/sync/strings.xml.in
+++ b/mobile/android/sync/strings.xml.in
@@ -30,16 +30,18 @@
   <string name="sync_input_server">&sync.input.server.label;</string>
   
   <!-- Setup Fail -->
   <string name="sync_title_fail">&sync.title.fail.label;</string>
   <string name="sync_subtitle_fail">&sync.subtitle.fail.label;</string>
   <string name="sync_button_tryagain">&sync.button.tryagain.label;</string>
   <string name="sync_button_manual">&sync.button.manual.label;</string>
   <string name="sync_subtitle_nointernet">&sync.subtitle.nointernet.label;</string>
+  <string name="sync_subtitle_failaccount">&sync.subtitle.failaccount.label;</string>
+  <string name="sync_subtitle_failmultiple">&sync.subtitle.failmultiple.label;</string>
   
   <!-- Setup Success -->
   <string name="sync_title_success">&sync.title.success.label;</string>
   <string name="sync_subtitle_success">&sync.subtitle.success.label1;</string>
   <string name="sync_settings">&sync.settings.label;</string>
   <string name="sync_subtitle_manage">&sync.subtitle.manage.label1;</string>
   
   <!-- Pair Device -->
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -753,16 +753,24 @@ nsHttpTransaction::Close(nsresult reason
                 reason = NS_ERROR_NET_RESET;
             }
         }
 
         // honor the sticky connection flag...
         if (mCaps & NS_HTTP_STICKY_CONNECTION)
             relConn = false;
     }
+
+    // mTimings.responseEnd is normally recorded based on the end of a
+    // HTTP delimiter such as chunked-encodings or content-length. However,
+    // EOF or an error still require an end time be recorded.
+    if (TimingEnabled() &&
+        mTimings.responseEnd.IsNull() && !mTimings.responseStart.IsNull())
+        mTimings.responseEnd = mozilla::TimeStamp::Now();
+
     if (relConn && mConnection)
         NS_RELEASE(mConnection);
 
     mStatus = reason;
     mTransactionDone = true; // forcibly flag the transaction as complete
     mClosed = true;
 
     // release some resources that we no longer need
--- a/nsprpub/configure.in
+++ b/nsprpub/configure.in
@@ -1872,17 +1872,17 @@ tools are selected during the Xcode/Deve
         RC=rc.exe
         GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb'
         OBJ_SUFFIX=obj
         LIB_SUFFIX=lib
         DLL_SUFFIX=dll
 
         # Determine compiler version
         changequote(,)
-        _MSMT_VER_FILTER='s|.*[^!-~]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
+        _MSVC_VER_FILTER='s|.* \([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p'
         changequote([,])
         CC_VERSION=`"${CC}" -v 2>&1 | sed -ne "$_MSVC_VER_FILTER"`
         _CC_MAJOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $1 }'`
         _CC_MINOR_VERSION=`echo ${CC_VERSION} | awk -F\. '{ print $2 }'`
         _CC_RELEASE=`echo ${CC_VERSION} | awk -F\. '{ print $3 }'`
         _CC_BUILD=`echo ${CC_VERSION} | awk -F\. '{ print $4 }'`
         MSC_VER=${_CC_MAJOR_VERSION}${_CC_MINOR_VERSION}
 
--- a/testing/mochitest/jar.mn
+++ b/testing/mochitest/jar.mn
@@ -18,12 +18,13 @@ mochikit.jar:
   content/tests/SimpleTest/MozillaLogger.js (tests/SimpleTest/MozillaLogger.js)
   content/tests/SimpleTest/LogController.js (tests/SimpleTest/LogController.js)
   content/tests/SimpleTest/setup.js (tests/SimpleTest/setup.js)
   content/tests/SimpleTest/SimpleTest.js (tests/SimpleTest/SimpleTest.js)
   content/tests/SimpleTest/test.css (tests/SimpleTest/test.css)
   content/tests/SimpleTest/TestRunner.js (tests/SimpleTest/TestRunner.js)
   content/tests/SimpleTest/WindowSnapshot.js (tests/SimpleTest/WindowSnapshot.js)
   content/tests/SimpleTest/MockObjects.js (tests/SimpleTest/MockObjects.js)
+  content/tests/SimpleTest/NativeKeyCodes.js (tests/SimpleTest/NativeKeyCodes.js)
   content/tests/SimpleTest/docshell_helpers.js (../../docshell/test/chrome/docshell_helpers.js)
 
 % resource mochikit %modules/
   modules/MockFilePicker.jsm (MockFilePicker.jsm)
--- a/testing/mochitest/tests/SimpleTest/Makefile.in
+++ b/testing/mochitest/tests/SimpleTest/Makefile.in
@@ -17,14 +17,15 @@ include $(topsrcdir)/config/rules.mk
 			TestRunner.js \
 			setup.js \
 			EventUtils.js \
 			ChromeUtils.js \
 			WindowSnapshot.js \
 			specialpowersAPI.js \
 			SpecialPowersObserverAPI.js \
 			MockObjects.js \
+			NativeKeyCodes.js \
 			$(DEPTH)/docshell/test/chrome/docshell_helpers.js \
 			$(NULL)
 
 libs:: $(_SIMPLETEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/$(relativesrcdir)
 
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/tests/SimpleTest/NativeKeyCodes.js
@@ -0,0 +1,343 @@
+/**
+ * This file defines all virtual keycodes for
+ * nsIDOMWindowUtils.sendNativeKeyEvent()
+ * These values are defined in each platform's SDK or documents.
+ */
+
+// Windows
+
+const WIN_VK_LBUTTON                    = 0x01;
+const WIN_VK_RBUTTON                    = 0x02;
+const WIN_VK_CANCEL                     = 0x03;
+const WIN_VK_MBUTTON                    = 0x04;
+const WIN_VK_XBUTTON1                   = 0x05;
+const WIN_VK_XBUTTON2                   = 0x06;
+const WIN_VK_BACK                       = 0x08;
+const WIN_VK_TAB                        = 0x09;
+const WIN_VK_CLEAR                      = 0x0C;
+const WIN_VK_RETURN                     = 0x0D;
+const WIN_VK_SHIFT                      = 0x10;
+const WIN_VK_CONTROL                    = 0x11;
+const WIN_VK_MENU                       = 0x12;
+const WIN_VK_PAUSE                      = 0x13;
+const WIN_VK_CAPITAL                    = 0x14;
+const WIN_VK_KANA                       = 0x15;
+const WIN_VK_HANGUEL                    = 0x15;
+const WIN_VK_HANGUL                     = 0x15;
+const WIN_VK_JUNJA                      = 0x17;
+const WIN_VK_FINAL                      = 0x18;
+const WIN_VK_HANJA                      = 0x19;
+const WIN_VK_KANJI                      = 0x19;
+const WIN_VK_ESCAPE                     = 0x1B;
+const WIN_VK_CONVERT                    = 0x1C;
+const WIN_VK_NONCONVERT                 = 0x1D;
+const WIN_VK_ACCEPT                     = 0x1E;
+const WIN_VK_MODECHANGE                 = 0x1F;
+const WIN_VK_SPACE                      = 0x20;
+const WIN_VK_PRIOR                      = 0x21;
+const WIN_VK_NEXT                       = 0x22;
+const WIN_VK_END                        = 0x23;
+const WIN_VK_HOME                       = 0x24;
+const WIN_VK_LEFT                       = 0x25;
+const WIN_VK_UP                         = 0x26;
+const WIN_VK_RIGHT                      = 0x27;
+const WIN_VK_DOWN                       = 0x28;
+const WIN_VK_SELECT                     = 0x29;
+const WIN_VK_PRINT                      = 0x2A;
+const WIN_VK_EXECUTE                    = 0x2B;
+const WIN_VK_SNAPSHOT                   = 0x2C;
+const WIN_VK_INSERT                     = 0x2D;
+const WIN_VK_DELETE                     = 0x2E;
+const WIN_VK_HELP                       = 0x2F;
+const WIN_VK_0                          = 0x30;
+const WIN_VK_1                          = 0x31;
+const WIN_VK_2                          = 0x32;
+const WIN_VK_3                          = 0x33;
+const WIN_VK_4                          = 0x34;
+const WIN_VK_5                          = 0x35;
+const WIN_VK_6                          = 0x36;
+const WIN_VK_7                          = 0x37;
+const WIN_VK_8                          = 0x38;
+const WIN_VK_9                          = 0x39;
+const WIN_VK_A                          = 0x41;
+const WIN_VK_B                          = 0x42;
+const WIN_VK_C                          = 0x43;
+const WIN_VK_D                          = 0x44;
+const WIN_VK_E                          = 0x45;
+const WIN_VK_F                          = 0x46;
+const WIN_VK_G                          = 0x47;
+const WIN_VK_H                          = 0x48;
+const WIN_VK_I                          = 0x49;
+const WIN_VK_J                          = 0x4A;
+const WIN_VK_K                          = 0x4B;
+const WIN_VK_L                          = 0x4C;
+const WIN_VK_M                          = 0x4D;
+const WIN_VK_N                          = 0x4E;
+const WIN_VK_O                          = 0x4F;
+const WIN_VK_P                          = 0x50;
+const WIN_VK_Q                          = 0x51;
+const WIN_VK_R                          = 0x52;
+const WIN_VK_S                          = 0x53;
+const WIN_VK_T                          = 0x54;
+const WIN_VK_U                          = 0x55;
+const WIN_VK_V                          = 0x56;
+const WIN_VK_W                          = 0x57;
+const WIN_VK_X                          = 0x58;
+const WIN_VK_Y                          = 0x59;
+const WIN_VK_Z                          = 0x5A;
+const WIN_VK_LWIN                       = 0x5B;
+const WIN_VK_RWIN                       = 0x5C;
+const WIN_VK_APPS                       = 0x5D;
+const WIN_VK_SLEEP                      = 0x5F;
+const WIN_VK_NUMPAD0                    = 0x60;
+const WIN_VK_NUMPAD1                    = 0x61;
+const WIN_VK_NUMPAD2                    = 0x62;
+const WIN_VK_NUMPAD3                    = 0x63;
+const WIN_VK_NUMPAD4                    = 0x64;
+const WIN_VK_NUMPAD5                    = 0x65;
+const WIN_VK_NUMPAD6                    = 0x66;
+const WIN_VK_NUMPAD7                    = 0x67;
+const WIN_VK_NUMPAD8                    = 0x68;
+const WIN_VK_NUMPAD9                    = 0x69;
+const WIN_VK_MULTIPLY                   = 0x6A;
+const WIN_VK_ADD                        = 0x6B;
+const WIN_VK_SEPARATOR                  = 0x6C;
+const WIN_VK_OEM_NEC_SEPARATE           = 0x6C;
+const WIN_VK_SUBTRACT                   = 0x6D;
+const WIN_VK_DECIMAL                    = 0x6E;
+const WIN_VK_DIVIDE                     = 0x6F;
+const WIN_VK_F1                         = 0x70;
+const WIN_VK_F2                         = 0x71;
+const WIN_VK_F3                         = 0x72;
+const WIN_VK_F4                         = 0x73;
+const WIN_VK_F5                         = 0x74;
+const WIN_VK_F6                         = 0x75;
+const WIN_VK_F7                         = 0x76;
+const WIN_VK_F8                         = 0x77;
+const WIN_VK_F9                         = 0x78;
+const WIN_VK_F10                        = 0x79;
+const WIN_VK_F11                        = 0x7A;
+const WIN_VK_F12                        = 0x7B;
+const WIN_VK_F13                        = 0x7C;
+const WIN_VK_F14                        = 0x7D;
+const WIN_VK_F15                        = 0x7E;
+const WIN_VK_F16                        = 0x7F;
+const WIN_VK_F17                        = 0x80;
+const WIN_VK_F18                        = 0x81;
+const WIN_VK_F19                        = 0x82;
+const WIN_VK_F20                        = 0x83;
+const WIN_VK_F21                        = 0x84;
+const WIN_VK_F22                        = 0x85;
+const WIN_VK_F23                        = 0x86;
+const WIN_VK_F24                        = 0x87;
+const WIN_VK_NUMLOCK                    = 0x90;
+const WIN_VK_SCROLL                     = 0x91;
+const WIN_VK_OEM_FJ_JISHO               = 0x92;
+const WIN_VK_OEM_NEC_EQUAL              = 0x92;
+const WIN_VK_OEM_FJ_MASSHOU             = 0x93;
+const WIN_VK_OEM_FJ_TOUROKU             = 0x94;
+const WIN_VK_OEM_FJ_LOYA                = 0x95;
+const WIN_VK_OEM_FJ_ROYA                = 0x96;
+const WIN_VK_LSHIFT                     = 0xA0;
+const WIN_VK_RSHIFT                     = 0xA1;
+const WIN_VK_LCONTROL                   = 0xA2;
+const WIN_VK_RCONTROL                   = 0xA3;
+const WIN_VK_LMENU                      = 0xA4;
+const WIN_VK_RMENU                      = 0xA5;
+const WIN_VK_BROWSER_BACK               = 0xA6;
+const WIN_VK_BROWSER_FORWARD            = 0xA7;
+const WIN_VK_BROWSER_REFRESH            = 0xA8;
+const WIN_VK_BROWSER_STOP               = 0xA9;
+const WIN_VK_BROWSER_SEARCH             = 0xAA;
+const WIN_VK_BROWSER_FAVORITES          = 0xAB;
+const WIN_VK_BROWSER_HOME               = 0xAC;
+const WIN_VK_VOLUME_MUTE                = 0xAD;
+const WIN_VK_VOLUME_DOWN                = 0xAE;
+const WIN_VK_VOLUME_UP                  = 0xAF;
+const WIN_VK_MEDIA_NEXT_TRACK           = 0xB0;
+const WIN_VK_OEM_FJ_000                 = 0xB0;
+const WIN_VK_MEDIA_PREV_TRACK           = 0xB1;
+const WIN_VK_OEM_FJ_EUQAL               = 0xB1;
+const WIN_VK_MEDIA_STOP                 = 0xB2;
+const WIN_VK_MEDIA_PLAY_PAUSE           = 0xB3;
+const WIN_VK_OEM_FJ_00                  = 0xB3;
+const WIN_VK_LAUNCH_MAIL                = 0xB4;
+const WIN_VK_LAUNCH_MEDIA_SELECT        = 0xB5;
+const WIN_VK_LAUNCH_APP1                = 0xB6;
+const WIN_VK_LAUNCH_APP2                = 0xB7;
+const WIN_VK_OEM_1                      = 0xBA;
+const WIN_VK_OEM_PLUS                   = 0xBB;
+const WIN_VK_OEM_COMMA                  = 0xBC;
+const WIN_VK_OEM_MINUS                  = 0xBD;
+const WIN_VK_OEM_PERIOD                 = 0xBE;
+const WIN_VK_OEM_2                      = 0xBF;
+const WIN_VK_OEM_3                      = 0xC0;
+const WIN_VK_OEM_4                      = 0xDB;
+const WIN_VK_OEM_5                      = 0xDC;
+const WIN_VK_OEM_6                      = 0xDD;
+const WIN_VK_OEM_7                      = 0xDE;
+const WIN_VK_OEM_8                      = 0xDF;
+const WIN_VK_OEM_NEC_DP1                = 0xE0;
+const WIN_VK_OEM_AX                     = 0xE1;
+const WIN_VK_OEM_NEC_DP2                = 0xE1;
+const WIN_VK_OEM_102                    = 0xE2;
+const WIN_VK_OEM_NEC_DP3                = 0xE2;
+const WIN_VK_ICO_HELP                   = 0xE3;
+const WIN_VK_OEM_NEC_DP4                = 0xE3;
+const WIN_VK_ICO_00                     = 0xE4;
+const WIN_VK_PROCESSKEY                 = 0xE5;
+const WIN_VK_ICO_CLEAR                  = 0xE6;
+const WIN_VK_PACKET                     = 0xE7;
+const WIN_VK_ERICSSON_BASE              = 0xE8;
+const WIN_VK_OEM_RESET                  = 0xE9;
+const WIN_VK_OEM_JUMP                   = 0xEA;
+const WIN_VK_OEM_PA1                    = 0xEB;
+const WIN_VK_OEM_PA2                    = 0xEC;
+const WIN_VK_OEM_PA3                    = 0xED;
+const WIN_VK_OEM_WSCTRL                 = 0xEE;
+const WIN_VK_OEM_CUSEL                  = 0xEF;
+const WIN_VK_OEM_ATTN                   = 0xF0;
+const WIN_VK_OEM_FINISH                 = 0xF1;
+const WIN_VK_OEM_COPY                   = 0xF2;
+const WIN_VK_OEM_AUTO                   = 0xF3;
+const WIN_VK_OEM_ENLW                   = 0xF4;
+const WIN_VK_OEM_BACKTAB                = 0xF5;
+const WIN_VK_ATTN                       = 0xF6;
+const WIN_VK_CRSEL                      = 0xF7;
+const WIN_VK_EXSEL                      = 0xF8;
+const WIN_VK_EREOF                      = 0xF9;
+const WIN_VK_PLAY                       = 0xFA;
+const WIN_VK_ZOOM                       = 0xFB;
+const WIN_VK_NONAME                     = 0xFC;
+const WIN_VK_PA1                        = 0xFD;
+const WIN_VK_OEM_CLEAR                  = 0xFE;
+
+// Mac
+
+const MAC_VK_ANSI_A                     = 0x00;
+const MAC_VK_ANSI_S                     = 0x01;
+const MAC_VK_ANSI_D                     = 0x02;
+const MAC_VK_ANSI_F                     = 0x03;
+const MAC_VK_ANSI_H                     = 0x04;
+const MAC_VK_ANSI_G                     = 0x05;
+const MAC_VK_ANSI_Z                     = 0x06;
+const MAC_VK_ANSI_X                     = 0x07;
+const MAC_VK_ANSI_C                     = 0x08;
+const MAC_VK_ANSI_V                     = 0x09;
+const MAC_VK_ISO_Section                = 0x0A;
+const MAC_VK_ANSI_B                     = 0x0B;
+const MAC_VK_ANSI_Q                     = 0x0C;
+const MAC_VK_ANSI_W                     = 0x0D;
+const MAC_VK_ANSI_E                     = 0x0E;
+const MAC_VK_ANSI_R                     = 0x0F;
+const MAC_VK_ANSI_Y                     = 0x10;
+const MAC_VK_ANSI_T                     = 0x11;
+const MAC_VK_ANSI_1                     = 0x12;
+const MAC_VK_ANSI_2                     = 0x13;
+const MAC_VK_ANSI_3                     = 0x14;
+const MAC_VK_ANSI_4                     = 0x15;
+const MAC_VK_ANSI_6                     = 0x16;
+const MAC_VK_ANSI_5                     = 0x17;
+const MAC_VK_ANSI_Equal                 = 0x18;
+const MAC_VK_ANSI_9                     = 0x19;
+const MAC_VK_ANSI_7                     = 0x1A;
+const MAC_VK_ANSI_Minus                 = 0x1B;
+const MAC_VK_ANSI_8                     = 0x1C;
+const MAC_VK_ANSI_0                     = 0x1D;
+const MAC_VK_ANSI_RightBracket          = 0x1E;
+const MAC_VK_ANSI_O                     = 0x1F;
+const MAC_VK_ANSI_U                     = 0x20;
+const MAC_VK_ANSI_LeftBracket           = 0x21;
+const MAC_VK_ANSI_I                     = 0x22;
+const MAC_VK_ANSI_P                     = 0x23;
+const MAC_VK_Return                     = 0x24;
+const MAC_VK_ANSI_L                     = 0x25;
+const MAC_VK_ANSI_J                     = 0x26;
+const MAC_VK_ANSI_Quote                 = 0x27;
+const MAC_VK_ANSI_K                     = 0x28;
+const MAC_VK_ANSI_Semicolon             = 0x29;
+const MAC_VK_ANSI_Backslash             = 0x2A;
+const MAC_VK_ANSI_Comma                 = 0x2B;
+const MAC_VK_ANSI_Slash                 = 0x2C;
+const MAC_VK_ANSI_N                     = 0x2D;
+const MAC_VK_ANSI_M                     = 0x2E;
+const MAC_VK_ANSI_Period                = 0x2F;
+const MAC_VK_Tab                        = 0x30;
+const MAC_VK_Space                      = 0x31;
+const MAC_VK_ANSI_Grave                 = 0x32;
+const MAC_VK_Delete                     = 0x33;
+const MAC_VK_PC_Backspace               = 0x33;
+const MAC_VK_Powerbook_KeypadEnter      = 0x34;
+const MAC_VK_Escape                     = 0x35;
+const MAC_VK_RightCommand               = 0x36;
+const MAC_VK_Command                    = 0x37;
+const MAC_VK_Shift                      = 0x38;
+const MAC_VK_CapsLock                   = 0x39;
+const MAC_VK_Option                     = 0x3A;
+const MAC_VK_Control                    = 0x3B;
+const MAC_VK_RightShift                 = 0x3C;
+const MAC_VK_RightOption                = 0x3D;
+const MAC_VK_RightControl               = 0x3E;
+const MAC_VK_Function                   = 0x3F;
+const MAC_VK_F17                        = 0x40;
+const MAC_VK_ANSI_KeypadDecimal         = 0x41;
+const MAC_VK_ANSI_KeypadMultiply        = 0x43;
+const MAC_VK_ANSI_KeypadPlus            = 0x45;
+const MAC_VK_ANSI_KeypadClear           = 0x47;
+const MAC_VK_VolumeUp                   = 0x48;
+const MAC_VK_VolumeDown                 = 0x49;
+const MAC_VK_Mute                       = 0x4A;
+const MAC_VK_ANSI_KeypadDivide          = 0x4B;
+const MAC_VK_ANSI_KeypadEnter           = 0x4C;
+const MAC_VK_ANSI_KeypadMinus           = 0x4E;
+const MAC_VK_F18                        = 0x4F;
+const MAC_VK_F19                        = 0x50;
+const MAC_VK_ANSI_KeypadEquals          = 0x51;
+const MAC_VK_ANSI_Keypad0               = 0x52;
+const MAC_VK_ANSI_Keypad1               = 0x53;
+const MAC_VK_ANSI_Keypad2               = 0x54;
+const MAC_VK_ANSI_Keypad3               = 0x55;
+const MAC_VK_ANSI_Keypad4               = 0x56;
+const MAC_VK_ANSI_Keypad5               = 0x57;
+const MAC_VK_ANSI_Keypad6               = 0x58;
+const MAC_VK_ANSI_Keypad7               = 0x59;
+const MAC_VK_F20                        = 0x5A;
+const MAC_VK_ANSI_Keypad8               = 0x5B;
+const MAC_VK_ANSI_Keypad9               = 0x5C;
+const MAC_VK_JIS_Yen                    = 0x5D;
+const MAC_VK_JIS_Underscore             = 0x5E;
+const MAC_VK_JIS_KeypadComma            = 0x5F;
+const MAC_VK_F5                         = 0x60;
+const MAC_VK_F6                         = 0x61;
+const MAC_VK_F7                         = 0x62;
+const MAC_VK_F3                         = 0x63;
+const MAC_VK_F8                         = 0x64;
+const MAC_VK_F9                         = 0x65;
+const MAC_VK_JIS_Eisu                   = 0x66;
+const MAC_VK_F11                        = 0x67;
+const MAC_VK_JIS_Kana                   = 0x68;
+const MAC_VK_F13                        = 0x69;
+const MAC_VK_PC_PrintScreen             = 0x69;
+const MAC_VK_F16                        = 0x6A;
+const MAC_VK_PC_ScrollLock              = 0x6A;
+const MAC_VK_F14                        = 0x6B;
+const MAC_VK_PC_Pause                   = 0x6B;
+const MAC_VK_F10                        = 0x6D;
+const MAC_VK_F12                        = 0x6F;
+const MAC_VK_F15                        = 0x71;
+const MAC_VK_Help                       = 0x72;
+const MAC_VK_PC_Insert                  = 0x72;
+const MAC_VK_Home                       = 0x73;
+const MAC_VK_PageUp                     = 0x74;
+const MAC_VK_ForwardDelete              = 0x75;
+const MAC_VK_PC_Delete                  = 0x75;
+const MAC_VK_F4                         = 0x76;
+const MAC_VK_End                        = 0x77;
+const MAC_VK_F2                         = 0x78;
+const MAC_VK_PageDown                   = 0x79;
+const MAC_VK_F1                         = 0x7A;
+const MAC_VK_LeftArrow                  = 0x7B;
+const MAC_VK_RightArrow                 = 0x7C;
+const MAC_VK_DownArrow                  = 0x7D;
+const MAC_VK_UpArrow                    = 0x7E;
+
--- a/testing/xpcshell/xpcshell.ini
+++ b/testing/xpcshell/xpcshell.ini
@@ -120,8 +120,10 @@ run-if.config = ipc
 [include:modules/libpref/test/unit_ipc/xpcshell.ini]
 [include:netwerk/test/unit_ipc/xpcshell.ini]
 [include:netwerk/cookie/test/unit_ipc/xpcshell.ini]
 [include:toolkit/components/contentprefs/tests/unit_ipc/xpcshell.ini]
 [include:uriloader/exthandler/tests/unit_ipc/xpcshell.ini]
 
 [include:modules/libmar/tests/unit/xpcshell.ini]
 skip-if = os == "android"
+
+[include:tools/profiler/tests/xpcshell.ini]
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -46,17 +46,16 @@
       <children includes="toolbarbutton"/>
     </content>
 
     <implementation implements="nsIAccessibleProvider, nsIAutoCompleteInput, nsIDOMXULMenuListElement">
       <field name="mController">null</field>
       <field name="mSearchNames">null</field>
       <field name="mIgnoreInput">false</field>
       <field name="mEnterEvent">null</field>
-      <field name="mConsumeRollupEvent">false</field>
 
       <field name="_searchBeginHandler">null</field>
       <field name="_searchCompleteHandler">null</field>
       <field name="_textEnteredHandler">null</field>
       <field name="_textRevertedHandler">null</field>
 
       <constructor><![CDATA[
         this.mController = Components.classes["@mozilla.org/autocomplete/controller;1"].
@@ -159,19 +158,16 @@
 
       <property name="searchParam"
                 onget="return this.getAttribute('autocompletesearchparam') || '';"
                 onset="this.setAttribute('autocompletesearchparam', val); return val;"/>
 
       <property name="searchCount" readonly="true"
                 onget="this.initSearchNames(); return this.mSearchNames.length;"/>
 
-      <property name="consumeRollupEvent" readonly="true"
-                onget="return this.mConsumeRollupEvent;"/>
-
       <!-- This is the maximum number of drop-down rows we get when we
             hit the drop marker beside fields that have it (like the URLbar).-->
       <field name="maxDropMarkerRows" readonly="true">14</field>
 
       <method name="getSearchAt">
         <parameter name="aIndex"/>
         <body><![CDATA[
           this.initSearchNames();
@@ -360,34 +356,34 @@
       <method name="openPopup">
         <body><![CDATA[
           this.popup.openAutocompletePopup(this, this);
         ]]></body>
       </method>
 
       <method name="closePopup">
         <body><![CDATA[
-          this.mConsumeRollupEvent = false;
+          this.popup.setAttribute("consumeoutsideclicks", "false");
           this.popup.closePopup();
         ]]></body>
       </method>
 
       <method name="showHistoryPopup">
         <body><![CDATA[
           // history dropmarker pushed state
           function cleanup(popup) {
             popup.removeEventListener("popupshowing", onShow, false);
           }
           function onShow(event) {
             var popup = event.target, input = popup.input;
             cleanup(popup);
             input.setAttribute("open", "true");
             function onHide() {
               input.removeAttribute("open");
-              input.mConsumeRollupEvent = false;
+              popup.setAttribute("consumeoutsideclicks", "false");
               popup.removeEventListener("popuphiding", onHide, false);
             }
             popup.addEventListener("popuphiding", onHide, false);
           }
           this.popup.addEventListener("popupshowing", onShow, false);
           setTimeout(cleanup, 1000, this.popup);
 
           // Store our "normal" maxRows on the popup, so that it can reset the
@@ -397,17 +393,17 @@
           // Increase our maxRows temporarily, since we want the dropdown to
           // be bigger in this case. The popup's popupshowing/popuphiding
           // handlers will take care of resetting this.
           this.maxRows = this.maxDropMarkerRows;
 
           // Ensure that we have focus.
           if (!this.focused)
             this.focus();
-          this.mConsumeRollupEvent = true;
+          this.popup.setAttribute("consumeoutsideclicks", "true");
           this.attachController();
           this.mController.startSearch("");
         ]]></body>
       </method>
 
       <method name="toggleHistoryPopup">
         <body><![CDATA[
           if (!this.popup.mPopupOpen)
@@ -601,17 +597,17 @@
   </binding>
 
   <binding id="autocomplete-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-base-popup">
     <resources>
       <stylesheet src="chrome://global/skin/tree.css"/>
       <stylesheet src="chrome://global/skin/autocomplete.css"/>
     </resources>
 
-    <content ignorekeys="true" level="top">
+    <content ignorekeys="true" level="top" consumeoutsideclicks="false">
       <xul:tree anonid="tree" class="autocomplete-tree plain" hidecolumnpicker="true" flex="1" seltype="single">
         <xul:treecols anonid="treecols">
           <xul:treecol id="treecolAutoCompleteValue" class="autocomplete-treecol" flex="1" overflow="true"/>
         </xul:treecols>
         <xul:treechildren class="autocomplete-treebody"/>
       </xul:tree>
     </content>
 
@@ -752,22 +748,16 @@
             var docViewer = docShell.contentViewer.QueryInterface(Components.interfaces.nsIMarkupDocumentViewer);
             var width = (rect.right - rect.left) * docViewer.fullZoom;
             this.setAttribute("width", width > 100 ? width : 100);
 
             // Adjust the direction of the autocomplete popup list based on the textbox direction, bug 649840
             var popupDirection = aElement.ownerDocument.defaultView.getComputedStyle(aElement).direction;
             this.style.direction = popupDirection;
 
-            // setConsumeRollupEvent() before we call openPopup()
-            var nsIPopupBO = Components.interfaces.nsIPopupBoxObject;
-            this.popupBoxObject.setConsumeRollupEvent(
-              this.mInput.consumeRollupEvent ?
-                nsIPopupBO.ROLLUP_CONSUME :
-                nsIPopupBO.ROLLUP_NO_CONSUME);
             this.openPopup(aElement, "after_start", 0, 0, false, false);
           }
         ]]></body>
       </method>
 
       <method name="invalidate">
         <body><![CDATA[
           this.adjustHeight();
@@ -940,17 +930,17 @@
     </handlers>
   </binding>
 
   <binding id="autocomplete-rich-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-base-popup">
     <resources>
       <stylesheet src="chrome://global/skin/autocomplete.css"/>
     </resources>
 
-    <content ignorekeys="true" level="top">
+    <content ignorekeys="true" level="top" consumeoutsideclicks="false">
       <xul:richlistbox anonid="richlistbox" class="autocomplete-richlistbox" flex="1"/>
       <xul:hbox>
         <children/>
       </xul:hbox>
     </content>
 
     <implementation implements="nsIAutoCompletePopup">
       <field name="_currentIndex">0</field>
@@ -996,22 +986,16 @@
             // clear any previous selection, see bugs 400671 and 488357
             this.selectedIndex = -1;
 
             var width = aElement.getBoundingClientRect().width;
             this.setAttribute("width", width > 100 ? width : 100);
             // invalidate() depends on the width attribute
             this._invalidate();
 
-            // setConsumeRollupEvent() before we call openPopup()
-            var nsIPopupBO = Components.interfaces.nsIPopupBoxObject;
-            this.popupBoxObject.setConsumeRollupEvent(
-              this.mInput.consumeRollupEvent ?
-                nsIPopupBO.ROLLUP_CONSUME :
-                nsIPopupBO.ROLLUP_NO_CONSUME);
             this.openPopup(aElement, "after_start", 0, 0, false, false);
           }
         ]]>
         </body>
       </method>
 
       <method name="invalidate">
         <body>
--- a/toolkit/content/widgets/button.xml
+++ b/toolkit/content/widgets/button.xml
@@ -338,17 +338,17 @@
     <resources>
       <stylesheet src="chrome://global/skin/button.css"/>
     </resources>
 
     <content>
       <children includes="observes|template|menupopup|panel|tooltip"/>
       <xul:button class="box-inherit button-menubutton-button"
                   anonid="button" flex="1" allowevents="true"
-                  xbl:inherits="disabled,crop,image,label,accessKey,command,
+                  xbl:inherits="disabled,crop,image,label,accesskey,command,
                                 buttonover,buttondown,align,dir,pack,orient">
         <children/>
       </xul:button>
       <xul:dropmarker class="button-menubutton-dropmarker" xbl:inherits="open,disabled,label"/>
     </content>
   </binding>
   
   <binding id="button-image" display="xul:button"
--- a/toolkit/mozapps/update/test/TestAUSReadStrings.cpp
+++ b/toolkit/mozapps/update/test/TestAUSReadStrings.cpp
@@ -9,16 +9,18 @@
  */
 #ifdef XP_WIN
   #include <windows.h>
   #define NS_main wmain
   #define NS_tstrrchr wcsrchr
   #define NS_tsnprintf _snwprintf
   #define NS_T(str) L ## str
   #define PATH_SEPARATOR_CHAR L'\\'
+  // On Windows, argv[0] can also have forward slashes instead
+  #define ALT_PATH_SEPARATOR_CHAR L'/'
 #else
   #include <unistd.h>
   #define NS_main main
   #define NS_tstrrchr strrchr
   #define NS_tsnprintf snprintf
   #define NS_T(str) str
 #ifdef XP_OS2
   #define PATH_SEPARATOR_CHAR '\\'
@@ -91,16 +93,21 @@ int NS_main(int argc, NS_tchar **argv)
   printf("Running TestAUSReadStrings tests\n");
 
   int rv = 0;
   int retval;
   NS_tchar inifile[MAXPATHLEN];
   StringTable testStrings;
 
   NS_tchar *slash = NS_tstrrchr(argv[0], PATH_SEPARATOR_CHAR);
+#ifdef ALT_PATH_SEPARATOR_CHAR
+  NS_tchar *altslash = NS_tstrrchr(argv[0], ALT_PATH_SEPARATOR_CHAR);
+  slash = (slash > altslash) ? slash : altslash;
+#endif // ALT_PATH_SEPARATOR_CHAR
+
   if (!slash) {
     fail("%s | unable to find platform specific path separator (check 1)", TEST_NAME);
     return 20;
   }
 
   *(++slash) = '\0';
   // Test success when the ini file exists with both Title and Info in the
   // Strings section and the values for Title and Info.
--- a/tools/profiler/Makefile.in
+++ b/tools/profiler/Makefile.in
@@ -3,16 +3,19 @@
 # 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/.
 
 DEPTH       = ../..
 topsrcdir	  = @top_srcdir@
 srcdir      = @srcdir@
 VPATH       = $(srcdir)
+relativesrcdir = tools/profiler
+
+XPCSHELL_TESTS = tests
 
 include $(DEPTH)/config/autoconf.mk
 
 EXPORTS = sampler.h
 
 ifdef MOZ_ENABLE_PROFILER_SPS
 EXPORTS += \
   sps_sampler.h \
--- a/tools/profiler/TableTicker.cpp
+++ b/tools/profiler/TableTicker.cpp
@@ -234,20 +234,19 @@ public:
 
     JSObject *profile = b.CreateObject();
     JSObject *samples = b.CreateArray();
     b.DefineProperty(profile, "samples", samples);
 
     JSObject *sample = NULL;
     JSObject *frames = NULL;
 
-    int oldReadPos = mReadPos;
-    while (mReadPos != mLastFlushPos) {
-      ProfileEntry entry = mEntries[mReadPos];
-      mReadPos = (mReadPos + 1) % mEntrySize;
+    int readPos = mReadPos;
+    while (readPos != mLastFlushPos) {
+      ProfileEntry entry = mEntries[readPos];
       switch (entry.mTagName) {
         case 's':
           sample = b.CreateObject();
           b.DefineProperty(sample, "name", (const char*)entry.mTagData);
           frames = b.CreateArray();
           b.DefineProperty(sample, "frames", frames);
           b.ArrayPush(samples, sample);
           break;
@@ -262,18 +261,18 @@ public:
               // extend 32-bit addresses starting with 0xFXXXXXX.
               unsigned long long pc = (unsigned long long)(uintptr_t)entry.mTagPtr;
               snprintf(tagBuff, 1024, "%#llx", pc);
               b.DefineProperty(frame, "location", tagBuff);
               b.ArrayPush(frames, frame);
             }
           }
       }
+      readPos = (readPos + 1) % mEntrySize;
     }
-    mReadPos = oldReadPos;
 
     return profile;
   }
 
   ProfileStack* GetStack()
   {
     return mStack;
   }
@@ -761,44 +760,53 @@ const char** mozilla_sampler_get_feature
 
   return features;
 }
 
 // Values are only honored on the first start
 void mozilla_sampler_start(int aProfileEntries, int aInterval,
                            const char** aFeatures, uint32_t aFeatureCount)
 {
+  if (!stack_key_initialized)
+    mozilla_sampler_init();
+
   ProfileStack *stack = tlsStack.get();
   if (!stack) {
     ASSERT(false);
     return;
   }
 
   mozilla_sampler_stop();
 
   TableTicker *t = new TableTicker(aInterval, aProfileEntries, stack,
                                    aFeatures, aFeatureCount);
   tlsTicker.set(t);
   t->Start();
 }
 
 void mozilla_sampler_stop()
 {
+  if (!stack_key_initialized)
+    mozilla_sampler_init();
+
   TableTicker *t = tlsTicker.get();
   if (!t) {
     return;
   }
 
   t->Stop();
   delete t;
   tlsTicker.set(NULL);
 }
 
 bool mozilla_sampler_is_active()
 {
+  if (!stack_key_initialized)
+    mozilla_sampler_init();
+
   TableTicker *t = tlsTicker.get();
   if (!t) {
     return false;
   }
 
   return t->IsActive();
 }
 
--- a/tools/profiler/nsIProfiler.idl
+++ b/tools/profiler/nsIProfiler.idl
@@ -3,17 +3,17 @@
  * 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/. */
  
 #include "nsISupports.idl"
 
 [scriptable, uuid(e388fded-1321-41af-a988-861a2bc5cfc3)]
 interface nsIProfiler : nsISupports
 {
-  void StartProfiler(in PRUint32 aInterval, in PRUint32 aEntries,
+  void StartProfiler(in PRUint32 aEntries, in PRUint32 aInterval,
                       [array, size_is(aFeatureCount)] in string aFeatures,
                       in PRUint32 aFeatureCount);
   void StopProfiler();
   string GetProfile();
   [implicit_jscontext]
   jsval getProfileData();
   boolean IsActive();
   void GetResponsivenessTimes(out PRUint32 aCount, [retval, array, size_is(aCount)] out double aResult);
--- a/tools/profiler/nsProfiler.cpp
+++ b/tools/profiler/nsProfiler.cpp
@@ -21,20 +21,20 @@ NS_IMPL_ISUPPORTS1(nsProfiler, nsIProfil
 
 
 nsProfiler::nsProfiler()
 {
 }
 
 
 NS_IMETHODIMP
-nsProfiler::StartProfiler(PRUint32 aInterval, PRUint32 aEntries,
+nsProfiler::StartProfiler(PRUint32 aEntries, PRUint32 aInterval,
                           const char** aFeatures, PRUint32 aFeatureCount)
 {
-  SAMPLER_START(aInterval, aEntries, aFeatures, aFeatureCount);
+  SAMPLER_START(aEntries, aInterval, aFeatures, aFeatureCount);
 #ifdef MOZ_INSTRUMENT_EVENT_LOOP
   mozilla::InitEventTracing();
 #endif
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsProfiler::StopProfiler()
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/head_profiler.js
@@ -0,0 +1,7 @@
+/* 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/. */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/test_get_features.js
@@ -0,0 +1,18 @@
+/* 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/. */
+  
+function run_test() {
+  // If we can't get the profiler component then assume gecko was
+  // built without it and pass all the tests
+  var profilerCc = Cc["@mozilla.org/tools/profiler;1"];
+  if (!profilerCc)
+    return;
+
+  var profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
+  if (!profiler)
+    return;
+
+  var profilerFeatures = profiler.GetFeatures([]);
+  do_check_true(profilerFeatures != null);
+}
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/test_run.js
@@ -0,0 +1,48 @@
+/* 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/. */
+
+function run_test() {
+  // If we can't get the profiler component then assume gecko was
+  // built without it and pass all the tests
+  var profilerCc = Cc["@mozilla.org/tools/profiler;1"];
+  if (!profilerCc)
+    return;
+
+  var profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
+  if (!profiler)
+    return;
+
+  do_check_true(!profiler.IsActive());
+
+  profiler.StartProfiler(1000, 10, [], 0);
+
+  do_check_true(profiler.IsActive());
+
+  do_test_pending();
+
+  do_timeout(1000, function wait() {
+    // Check responsiveness
+    var resp = profiler.GetResponsivenessTimes({});
+    do_check_true(resp.length > 10);
+
+    // Check text profile format
+    var profileStr = profiler.GetProfile();
+    do_check_true(profileStr.length > 10);
+
+    // check json profile format
+    var profileObj = profiler.getProfileData();
+    do_check_neq(profileObj, null);
+    do_check_neq(profileObj.threads, null);
+    do_check_true(profileObj.threads.length >= 1);
+    do_check_neq(profileObj.threads[0].samples, null);
+    // NOTE: The number of samples will be empty since we
+    //       don't have any labels in the xpcshell code
+
+    profiler.StopProfiler();
+    do_check_true(!profiler.IsActive());
+    do_test_finished();
+  });
+
+
+}
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/test_shared_library.js
@@ -0,0 +1,23 @@
+/* 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/. */
+
+function run_test() {
+  // If we can't get the profiler component then assume gecko was
+  // built without it and pass all the tests
+  var profilerCc = Cc["@mozilla.org/tools/profiler;1"];
+  if (!profilerCc)
+    return;
+
+  var profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
+  if (!profiler)
+    return;
+
+  var sharedStr = profiler.getSharedLibraryInformation();
+  sharedStr = sharedStr.toLowerCase();
+
+  // Let's not hardcode anything too specific
+  // just some sanity checks.
+  do_check_neq(sharedStr, null);
+  do_check_neq(sharedStr, "");
+}
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/test_start.js
@@ -0,0 +1,25 @@
+/* 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/. */
+  
+function run_test() {
+  // If we can't get the profiler component then assume gecko was
+  // built without it and pass all the tests
+  var profilerCc = Cc["@mozilla.org/tools/profiler;1"];
+  if (!profilerCc)
+    return;
+
+  var profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
+  if (!profiler)
+    return;
+
+  do_check_true(!profiler.IsActive());
+
+  profiler.StartProfiler(10, 100, [], 0);
+
+  do_check_true(profiler.IsActive());
+
+  profiler.StopProfiler();
+
+  do_check_true(!profiler.IsActive());
+}
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/xpcshell.ini
@@ -0,0 +1,10 @@
+[DEFAULT]
+head = head_profiler.js
+tail =
+
+[test_start.js]
+skip-if = true
+[test_get_features.js]
+[test_shared_library.js]
+[test_run.js]
+skip-if = true
--- a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp
+++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp
@@ -25,17 +25,17 @@ nsMIMEInfoAndroid::LoadUriInternal(nsIUR
   nsCString uriSpec;
   aURI->GetSpec(uriSpec);
 
   nsCString uriScheme;
   aURI->GetScheme(uriScheme);
 
   if (mozilla::AndroidBridge::Bridge())
     return mozilla::AndroidBridge::Bridge()->
-      OpenUriExternal(uriSpec, mType.Equals(uriScheme) ? EmptyCString() : mType) ? NS_OK : NS_ERROR_FAILURE;
+      OpenUriExternal(uriSpec, (mType.Equals(uriScheme) || mType.Equals(uriSpec)) ? EmptyCString() : mType) ? NS_OK : NS_ERROR_FAILURE;
 
   return NS_ERROR_FAILURE;
 }
 
 
 bool
 nsMIMEInfoAndroid::GetMimeInfoForMimeType(const nsACString& aMimeType,
                                           nsMIMEInfoAndroid** aMimeInfo)
--- a/widget/gonk/Framebuffer.cpp
+++ b/widget/gonk/Framebuffer.cpp
@@ -34,16 +34,17 @@ namespace mozilla {
 namespace Framebuffer {
 
 static int sFd = -1;
 static size_t sMappedSize;
 static struct fb_var_screeninfo sVi;
 static size_t sActiveBuffer;
 typedef vector<nsRefPtr<gfxImageSurface> > BufferVector;
 BufferVector* sBuffers;
+static gfxIntSize *sScreenSize = nsnull;
 
 BufferVector& Buffers() { return *sBuffers; }
 
 bool
 SetGraphicsMode()
 {
     ScopedClose fd(open("/dev/tty0", O_RDWR | O_SYNC));
     if (0 > fd.get()) {
@@ -52,17 +53,17 @@ SetGraphicsMode()
     } else if (ioctl(fd.get(), KDSETMODE, (void*) KD_GRAPHICS)) {
         LOG("Error setting graphics mode on /dev/tty0");
         return false;
     }
     return true;
 }
 
 bool
-Open(nsIntSize* aScreenSize)
+Open()
 {
     if (0 <= sFd)
         return true;
 
     if (!SetGraphicsMode())
         return false;
 
     ScopedClose fd(open("/dev/graphics/fb0", O_RDWR));
@@ -93,63 +94,70 @@ Open(nsIntSize* aScreenSize)
     sFd = fd.get();
     fd.forget();
 
     // The android porting doc requires a /dev/graphics/fb0 device
     // that's double buffered with r5g6b5 format.  Hence the
     // hard-coded numbers here.
     gfxASurface::gfxImageFormat format = gfxASurface::ImageFormatRGB16_565;
     int bytesPerPixel = gfxASurface::BytePerPixelFromFormat(format);
-    gfxIntSize size(sVi.xres, sVi.yres);
-    long stride = size.width * bytesPerPixel;
-    size_t numFrameBytes = stride * size.height;
+    if (!sScreenSize) {
+        sScreenSize = new gfxIntSize(sVi.xres, sVi.yres);
+    }
+    long stride = sScreenSize->width * bytesPerPixel;
+    size_t numFrameBytes = stride * sScreenSize->height;
 
     sBuffers = new BufferVector(2);
     unsigned char* data = static_cast<unsigned char*>(mem);
     for (size_t i = 0; i < 2; ++i, data += numFrameBytes) {
       memset(data, 0, numFrameBytes);
-      Buffers()[i] = new gfxImageSurface(data, size, stride, format);
+      Buffers()[i] = new gfxImageSurface(data, *sScreenSize, stride, format);
     }
 
     // Clear the framebuffer to a known state.
     Present(nsIntRect());
 
-    *aScreenSize = size;
     return true;
 }
 
 bool
 GetSize(nsIntSize *aScreenSize) {
-    if (0 <= sFd)
+    // If the framebuffer has been opened, we should always have the size.
+    if (0 <= sFd || sScreenSize) {
+        *aScreenSize = *sScreenSize;
         return true;
+    }
 
     ScopedClose fd(open("/dev/graphics/fb0", O_RDWR));
     if (0 > fd.get()) {
         LOG("Error opening framebuffer device");
         return false;
     }
 
     if (0 > ioctl(fd.get(), FBIOGET_VSCREENINFO, &sVi)) {
         LOG("Error getting variable screeninfo");
         return false;
     }
 
-    *aScreenSize = gfxIntSize(sVi.xres, sVi.yres);
+    sScreenSize = new gfxIntSize(sVi.xres, sVi.yres);
+    *aScreenSize = *sScreenSize;
     return true;
 }
 
 void
 Close()
 {
     if (0 > sFd)
         return;
 
     munmap(Buffers()[0]->Data(), sMappedSize);
     delete sBuffers;
     sBuffers = NULL;
+    delete sScreenSize;
+    sScreenSize = NULL;
 
     close(sFd);
     sFd = -1;
 }
 
 gfxASurface*
 BackBuffer()
 {
--- a/widget/gonk/Framebuffer.h
+++ b/widget/gonk/Framebuffer.h
@@ -21,26 +21,27 @@ namespace Framebuffer {
 // -- ready to paint next frame --
 //  nsRefPtr<gfxASurface> backBuffer = BackBuffer();
 //  // ...
 //  Paint(backBuffer);
 //  // ...
 //  Present();
 //
 
-// Return true if the fbdev was successfully opened, along with the
-// dimensions of the screen.  If this fails, the result of all further
-// calls is undefined.  Open() is idempotent.
-bool Open(nsIntSize* aScreenSize);
+// Return true if the fbdev was successfully opened.  If this fails, 
+// the result of all further calls is undefined.  Open() is idempotent.
+bool Open();
 
 // After Close(), the result of all further calls is undefined.
 // Close() is idempotent, and Open() can be called again after
 // Close().
 void Close();
 
+// Return true if the fbdev was successfully opened or the size was
+// already cached.
 bool GetSize(nsIntSize *aScreenSize);
 
 // Return the buffer to be drawn into, that will be the next frame.
 gfxASurface* BackBuffer();
 
 // Swap the front buffer for the back buffer.  |aUpdated| is the
 // region of the back buffer that was repainted.
 void Present(const nsIntRegion& aUpdated);
--- a/widget/gonk/nsWindow.cpp
+++ b/widget/gonk/nsWindow.cpp
@@ -44,16 +44,17 @@ static gfxMatrix sRotationMatrix;
 
 static nsRefPtr<GLContext> sGLContext;
 static nsTArray<nsWindow *> sTopWindows;
 static nsWindow *gWindowToRedraw = nsnull;
 static nsWindow *gFocusedWindow = nsnull;
 static android::FramebufferNativeWindow *gNativeWindow = nsnull;
 static bool sFramebufferOpen;
 static bool sUsingOMTC;
+static bool sScreenInitialized;
 static nsRefPtr<gfxASurface> sOMTCSurface;
 static pthread_t sFramebufferWatchThread;
 
 namespace {
 
 class ScreenOnOffEvent : public nsRunnable {
 public:
     ScreenOnOffEvent(bool on)
@@ -115,56 +116,41 @@ static void *frameBufferWatcher(void *) 
     
     return NULL;
 }
 
 } // anonymous namespace
 
 nsWindow::nsWindow()
 {
-    if (!sGLContext && !sFramebufferOpen && !sUsingOMTC) {
+    if (!sScreenInitialized) {
         // workaround Bug 725143
         hal::SetScreenEnabled(true);
 
         // Watching screen on/off state by using a pthread
         // which implicitly calls exit() when the main thread ends
         if (pthread_create(&sFramebufferWatchThread, NULL, frameBufferWatcher, NULL)) {
             NS_RUNTIMEABORT("Failed to create framebufferWatcherThread, aborting...");
         }
 
         sUsingOMTC = UseOffMainThreadCompositing();
 
+        if (sUsingOMTC) {
+          sOMTCSurface = new gfxImageSurface(gfxIntSize(1, 1),
+                                             gfxASurface::ImageFormatRGB24);
+        }
+
         // We (apparently) don't have a way to tell if allocating the
         // fbs succeeded or failed.
         gNativeWindow = new android::FramebufferNativeWindow();
-        if (sUsingOMTC) {
-            nsIntSize screenSize;
-            bool gotFB = Framebuffer::GetSize(&screenSize);
-            MOZ_ASSERT(gotFB);
-            gScreenBounds = nsIntRect(nsIntPoint(0, 0), screenSize);
 
-            sOMTCSurface = new gfxImageSurface(gfxIntSize(1, 1),
-                gfxASurface::ImageFormatRGB24);
-        } else {
-            sGLContext = GLContextProvider::CreateForWindow(this);
-            // CreateForWindow sets up gScreenBounds
-            if (!sGLContext) {
-                LOG("Failed to create GL context for fb, trying /dev/graphics/fb0");
-
-                // We can't delete gNativeWindow.
-
-                nsIntSize screenSize;
-                sFramebufferOpen = Framebuffer::Open(&screenSize);
-                gScreenBounds = nsIntRect(nsIntPoint(0, 0), screenSize);
-                if (!sFramebufferOpen) {
-                    LOG("Failed to mmap fb(?!?), aborting ...");
-                    NS_RUNTIMEABORT("Can't open GL context and can't fall back on /dev/graphics/fb0 ...");
-                }
-            }
-        }
+        nsIntSize screenSize;
+        bool gotFB = Framebuffer::GetSize(&screenSize);
+        MOZ_ASSERT(gotFB);
+        gScreenBounds = nsIntRect(nsIntPoint(0, 0), screenSize);
 
         char propValue[PROPERTY_VALUE_MAX];
         property_get("ro.sf.hwrotation", propValue, "0");
         sPhysicalScreenRotation = atoi(propValue) / 90;
 
         // Unlike nsScreenGonk::SetRotation(), only support 0 and 180 as there
         // are no known screens that are mounted at 90 or 270 at the moment.
         switch (sPhysicalScreenRotation) {
@@ -176,16 +162,18 @@ nsWindow::nsWindow()
             sRotationMatrix.Rotate(M_PI);
             break;
         default:
             MOZ_NOT_REACHED("Unknown rotation");
             break;
         }
         sVirtualBounds = gScreenBounds;
 
+        sScreenInitialized = true;
+
         nsAppShell::NotifyScreenInitialized();
     }
 }
 
 nsWindow::~nsWindow()
 {
 }
 
@@ -487,41 +475,56 @@ nsWindow::GetLayerManager(PLayersChild* 
                           LayerManagerPersistence aPersistence,
                           bool* aAllowRetaining)
 {
     if (aAllowRetaining)
         *aAllowRetaining = true;
     if (mLayerManager)
         return mLayerManager;
 
+      // Set mUseAcceleratedRendering here to make it consistent with
+      // nsBaseWidget::GetLayerManager
+    mUseAcceleratedRendering = GetShouldAccelerate();
+    if (!mUseAcceleratedRendering) {
+        sFramebufferOpen = Framebuffer::Open();
+        if (!sFramebufferOpen) {
+            LOG("Failed to mmap fb(?!?), aborting ...");
+            NS_RUNTIMEABORT("Can't open GL context and can't fall back on /dev/graphics/fb0 ...");
+        }
+    }
+
     nsWindow *topWindow = sTopWindows[0];
 
     if (!topWindow) {
         LOG(" -- no topwindow\n");
         return nsnull;
     }
 
     if (sUsingOMTC) {
         CreateCompositor();
         if (mLayerManager)
             return mLayerManager;
     }
 
+    DebugOnly<nsIntRect> fbBounds = gScreenBounds;
+    sGLContext = GLContextProvider::CreateForWindow(this);
+    MOZ_ASSERT(fbBounds.value == gScreenBounds);
     if (sGLContext) {
         nsRefPtr<LayerManagerOGL> layerManager = new LayerManagerOGL(this);
 
-        if (layerManager->Initialize(sGLContext))
+        if (layerManager->Initialize(sGLContext)) {
             mLayerManager = layerManager;
-        else
+            return mLayerManager;
+        } else {
             LOG("Could not create OGL LayerManager");
-    } else {
-        MOZ_ASSERT(sFramebufferOpen);
-        mLayerManager = new BasicShadowLayerManager(this);
+        }
     }
 
+    mLayerManager = new BasicShadowLayerManager(this);
+
     return mLayerManager;
 }
 
 gfxASurface *
 nsWindow::GetThebesSurface()
 {
     /* This is really a dummy surface; this is only used when doing reflow, because
      * we need a RenderingContext to measure text against.
--- a/widget/tests/test_bug428405.xul
+++ b/widget/tests/test_bug428405.xul
@@ -4,16 +4,17 @@
 
 <window id="window1" title="Test Bug 428405"
   onload="setGlobals(); loadFirstTab();"
   xmlns:html="http://www.w3.org/1999/xhtml"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
   <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/NativeKeyCodes.js"/>
 
   <tabbox id="tabbox" flex="100%">
     <tabs>
       <tab label="Tab 1"/>
       <tab label="Tab 2"/>
     </tabs>
     <tabpanels flex="100%">
       <browser onload="configureFirstTab();" id="tab1browser" flex="100%"/>
@@ -141,21 +142,21 @@
     // latter make this test succeed when it should fail.
 
     // The 'aNativeKeyCode', 'aCharacters' and 'aUnmodifiedCharacters'
     // parameters used below (in synthesizeNativeReturnKey() and
     // synthesizeNativeCmdOptY()) were confirmed accurate using the
     // DebugEventsPlugin v1.01 from bmo bug 441880.
 
     function synthesizeNativeReturnKey() {
-      gUtils.sendNativeKeyEvent(0, 36, 0, "\u000a", "\u000a");
+      gUtils.sendNativeKeyEvent(0, MAC_VK_Return, 0, "\u000a", "\u000a");
     }
 
     function synthesizeNativeCmdOptY() {
-      gUtils.sendNativeKeyEvent(0, 16, 0x5000, "y", "y");
+      gUtils.sendNativeKeyEvent(0, MAC_VK_ANSI_Y, 0x5000, "y", "y");
     }
 
   ]]></script>
 
   <!-- test results are displayed in the html:body -->
   <body xmlns="http://www.w3.org/1999/xhtml">
     <p id="display"></p>
     <div id="content" style="display: none"></div>
--- a/widget/tests/test_key_event_counts.xul
+++ b/widget/tests/test_key_event_counts.xul
@@ -6,16 +6,17 @@
      or they get processed twice. This test tests some of those scenarios. -->
 
 <window id="window1" title="Test Key Event Counts" onload="runTest()"
   xmlns:html="http://www.w3.org/1999/xhtml"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
   <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/NativeKeyCodes.js"/>
 
   <!-- test results are displayed in the html:body -->
   <body xmlns="http://www.w3.org/1999/xhtml">
     <p id="display"></p>
     <div id="content" style="display: none"></div>
     <pre id="test"></pre>
   </body>
 
@@ -34,26 +35,26 @@
 
       var domWindowUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
                              getInterface(Components.interfaces.nsIDOMWindowUtils);
 
       window.addEventListener("keypress", onKeyPress, false);
 
       // Test ctrl-tab
       gKeyPressEventCount = 0;
-      domWindowUtils.sendNativeKeyEvent(0, 48, 0x0400, "\t", "\t");
+      domWindowUtils.sendNativeKeyEvent(0, MAC_VK_Tab, 0x0400, "\t", "\t");
       is(gKeyPressEventCount, 1);
 
       // Test cmd+shift+a
       gKeyPressEventCount = 0;
-      domWindowUtils.sendNativeKeyEvent(0, 0, 0x4000 | 0x0100, "a", "A");
+      domWindowUtils.sendNativeKeyEvent(0, MAC_VK_ANSI_A, 0x4000 | 0x0100, "a", "A");
       is(gKeyPressEventCount, 1);
 
       // Test cmd-;
       gKeyPressEventCount = 0;
-      domWindowUtils.sendNativeKeyEvent(0, 41, 0x4000, ";", ";");
+      domWindowUtils.sendNativeKeyEvent(0, MAC_VK_ANSI_Semicolon, 0x4000, ";", ";");
       is(gKeyPressEventCount, 1);
 
       window.removeEventListener("keypress", onKeyPress, false);
     }
   ]]></script>
 
 </window>
--- a/widget/tests/test_keycodes.xul
+++ b/widget/tests/test_keycodes.xul
@@ -5,16 +5,18 @@
 <window title="Key event tests"
   onload="runTest()"
   xmlns:html="http://www.w3.org/1999/xhtml"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <title>Key event tests</title>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/NativeKeyCodes.js" />
 
 <keyset>
   <key id="unshiftedKey" key=";" modifiers="accel" oncommand="this.activeCount++"/>
   <key id="shiftedKey" key=":" modifiers="accel" oncommand="this.activeCount++"/>
   <key id="commandOptionF" key='f' modifiers="accel,alt" oncommand="this.activeCount++"/>
   <key id="question" key='?' modifiers="accel" oncommand="this.activeCount++"/>
   <key id="unshiftedX" key="x" modifiers="accel" oncommand="this.activeCount++"/>
   <key id="shiftedX" key="X" modifiers="accel,shift" oncommand="this.activeCount++"/>
@@ -358,1692 +360,1694 @@ function runKeyEventTests()
     // preferences widget to enable other keyboard layouts and select them from the
     // input menu to see what keyboard events they generate.
     // Note that it's possible to send bogus key events here, e.g.
     // {keyCode:0, chars:"z", unmodifiedChars:"P"} --- sendNativeKeyEvent
     // makes no attempt to verify that the keyCode matches the characters. So only
     // test key event records that you saw Cocoa send.
 
     // Ctrl keys
-    testKey({layout:"US", keyCode:0, ctrl:1, chars:"\u0001", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, ctrl:1, chars:"\u0001", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0, ctrl:1, shift:1, chars:"\u0001", unmodifiedChars:"A"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, ctrl:1, shift:1, chars:"\u0001", unmodifiedChars:"A"},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL);
 
     // Alt keys
-    testKey({layout:"US", keyCode:0, alt:1, chars:"\u00e5", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, alt:1, chars:"\u00e5", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00e5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0, alt:1, shift:1, chars:"\u00c5", unmodifiedChars:"A"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, alt:1, shift:1, chars:"\u00c5", unmodifiedChars:"A"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00c5", SHOULD_DELIVER_ALL);
     
     // Command keys
-    testKey({layout:"US", keyCode:0, command:1, chars:"a", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, command:1, chars:"a", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
     // Shift-cmd gives us the shifted character
-    testKey({layout:"US", keyCode:0, command:1, shift:1, chars:"a", unmodifiedChars:"A"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, command:1, shift:1, chars:"a", unmodifiedChars:"A"},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
     // Ctrl-cmd gives us the unshifted character
-    testKey({layout:"US", keyCode:0, command:1, ctrl:1, chars:"\u0001", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, command:1, ctrl:1, chars:"\u0001", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
     // Alt-cmd gives us the shifted character
-    testKey({layout:"US", keyCode:0, command:1, alt:1, chars:"\u00e5", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, command:1, alt:1, chars:"\u00e5", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00e5", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0, command:1, alt:1, shift:1, chars:"\u00c5", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, command:1, alt:1, shift:1, chars:"\u00c5", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00c5", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
 
     // Greek ctrl keys produce Latin charcodes
-    testKey({layout:"Greek", keyCode:0, ctrl:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, ctrl:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL);
-    testKey({layout:"Greek", keyCode:0, ctrl:1, shift:1, chars:"\u0001", unmodifiedChars:"\u0391"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, ctrl:1, shift:1, chars:"\u0001", unmodifiedChars:"\u0391"},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL);
 
     // Greek command keys
-    testKey({layout:"Greek", keyCode:0, command:1, chars:"a", unmodifiedChars:"\u03b1"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, command:1, chars:"a", unmodifiedChars:"\u03b1"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
     // Shift-cmd gives us the shifted character
-    testKey({layout:"Greek", keyCode:0, command:1, shift:1, chars:"a", unmodifiedChars:"\u0391"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, command:1, shift:1, chars:"a", unmodifiedChars:"\u0391"},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
     // Ctrl-cmd gives us the unshifted character
-    testKey({layout:"Greek", keyCode:0, command:1, ctrl:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, command:1, ctrl:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
     // Alt-cmd gives us the shifted character
-    testKey({layout:"Greek", keyCode:0, command:1, alt:1, chars:"\u00a8", unmodifiedChars:"\u03b1"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, command:1, alt:1, chars:"\u00a8", unmodifiedChars:"\u03b1"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00a8", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"Greek", keyCode:0, command:1, alt:1, shift:1, chars:"\u00b9", unmodifiedChars:"\u0391"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, command:1, alt:1, shift:1, chars:"\u00b9", unmodifiedChars:"\u0391"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00b9", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
 
     // German
-    testKey({layout:"German", keyCode:0, chars:"a", unmodifiedChars:"a"},
+    testKey({layout:"German", keyCode:MAC_VK_ANSI_A, chars:"a", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL);
-    testKey({layout:"German", keyCode:33, chars:"\u00fc", unmodifiedChars:"\u00fc"},
+    testKey({layout:"German", keyCode:MAC_VK_ANSI_LeftBracket, chars:"\u00fc", unmodifiedChars:"\u00fc"},
             0, "\u00fc", SHOULD_DELIVER_ALL);
-    testKey({layout:"German", keyCode:27, chars:"\u00df", unmodifiedChars:"\u00df"},
+    testKey({layout:"German", keyCode:MAC_VK_ANSI_Minus, chars:"\u00df", unmodifiedChars:"\u00df"},
             nsIDOMKeyEvent.DOM_VK_QUESTION_MARK, "\u00df", SHOULD_DELIVER_ALL);
-    testKey({layout:"German", keyCode:27, shift:1, chars:"?", unmodifiedChars:"?"},
+    testKey({layout:"German", keyCode:MAC_VK_ANSI_Minus, shift:1, chars:"?", unmodifiedChars:"?"},
             nsIDOMKeyEvent.DOM_VK_QUESTION_MARK, "?", SHOULD_DELIVER_ALL);
     // Note that Shift+SS is '?' but Cmd+Shift+SS is '/' on German layout.
     // Therefore, when Cmd key is pressed, the SS key's keycode is changed.
-    testKey({layout:"German", keyCode:27, command:1, chars:"\u00df", unmodifiedChars:"\u00df"},
+    testKey({layout:"German", keyCode:MAC_VK_ANSI_Minus, command:1, chars:"\u00df", unmodifiedChars:"\u00df"},
             nsIDOMKeyEvent.DOM_VK_SLASH, "\u00df", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"German", keyCode:27, command:1, shift:1, chars:"/", unmodifiedChars:"?"},
+    testKey({layout:"German", keyCode:MAC_VK_ANSI_Minus, command:1, shift:1, chars:"/", unmodifiedChars:"?"},
             nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
 
     // Caps Lock key event
     // XXX keyup event of Caps Lock key is not fired.
-    testKey({layout:"US", keyCode:57, capsLock:1, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_CapsLock, capsLock:1, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN);
-    testKey({layout:"US", keyCode:57, capsLock:0, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_CapsLock, capsLock:0, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN);
 
     // Shift/RightShift key event
-    testKey({layout:"US", keyCode:56, shift:1, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_Shift, shift:1, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYDOWN);
-    testKey({layout:"US", keyCode:56, shift:0, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_Shift, shift:0, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYUP);
-    testKey({layout:"US", keyCode:60, shiftRight:1, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_RightShift, shiftRight:1, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYDOWN);
-    testKey({layout:"US", keyCode:60, shiftRight:0, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_RightShift, shiftRight:0, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYUP);
 
     // Control/RightControl key event
-    testKey({layout:"US", keyCode:59, ctrl:1, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_Control, ctrl:1, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYDOWN);
-    testKey({layout:"US", keyCode:59, ctrl:0, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_Control, ctrl:0, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYUP);
-    testKey({layout:"US", keyCode:62, ctrlRight:1, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_RightControl, ctrlRight:1, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYDOWN);
-    testKey({layout:"US", keyCode:62, ctrlRight:0, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_RightControl, ctrlRight:0, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYUP);
 
     // Option/RightOption key event
-    testKey({layout:"US", keyCode:58, alt:1, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_Option, alt:1, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN);
-    testKey({layout:"US", keyCode:58, alt:0, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_Option, alt:0, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYUP);
-    testKey({layout:"US", keyCode:61, altRight:1, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_RightOption, altRight:1, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN);
-    testKey({layout:"US", keyCode:61, altRight:0, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_RightOption, altRight:0, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYUP);
 
     // Command/RightCommand key event
-    testKey({layout:"US", keyCode:55, command:1, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_Command, command:1, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYDOWN);
-    testKey({layout:"US", keyCode:55, command:0, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_Command, command:0, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYUP);
-    testKey({layout:"US", keyCode:54, commandRight:1, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_RightCommand, commandRight:1, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYDOWN);
-    testKey({layout:"US", keyCode:54, commandRight:0, chars:"", unmodifiedChars:""},
+    testKey({layout:"US", keyCode:MAC_VK_RightCommand, commandRight:0, chars:"", unmodifiedChars:""},
             nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYUP);
 
     // all keys on keyboard (keyCode test)
-    testKey({layout:"US", keyCode:0x30, chars:"\t", unmodifiedChars:"\t"},
+    testKey({layout:"US", keyCode:MAC_VK_Tab, chars:"\t", unmodifiedChars:"\t"},
             nsIDOMKeyEvent.DOM_VK_TAB, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x47, chars:"\uF739", unmodifiedChars:"\uF739"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadClear, chars:"\uF739", unmodifiedChars:"\uF739"},
             nsIDOMKeyEvent.DOM_VK_CLEAR, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x24, chars:"\u000D", unmodifiedChars:"\u000D"},
+    testKey({layout:"US", keyCode:MAC_VK_Return, chars:"\u000D", unmodifiedChars:"\u000D"},
             nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x71, chars:"\uF712", unmodifiedChars:"\uF712"},
+    testKey({layout:"US", keyCode:MAC_VK_F15, chars:"\uF712", unmodifiedChars:"\uF712"},
             nsIDOMKeyEvent.DOM_VK_PAUSE, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x35, chars:"\u001B", unmodifiedChars:"\u001B"},
+    testKey({layout:"US", keyCode:MAC_VK_Escape, chars:"\u001B", unmodifiedChars:"\u001B"},
             nsIDOMKeyEvent.DOM_VK_ESCAPE, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x31, chars:" ", unmodifiedChars:" "},
+    testKey({layout:"US", keyCode:MAC_VK_Space, chars:" ", unmodifiedChars:" "},
             nsIDOMKeyEvent.DOM_VK_SPACE, " ", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x74, chars:"\uF72C", unmodifiedChars:"\uF72C"},
+    testKey({layout:"US", keyCode:MAC_VK_PageUp, chars:"\uF72C", unmodifiedChars:"\uF72C"},
             nsIDOMKeyEvent.DOM_VK_PAGE_UP, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x79, chars:"\uF72D", unmodifiedChars:"\uF72D"},
+    testKey({layout:"US", keyCode:MAC_VK_PageDown, chars:"\uF72D", unmodifiedChars:"\uF72D"},
             nsIDOMKeyEvent.DOM_VK_PAGE_DOWN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x77, chars:"\uF72B", unmodifiedChars:"\uF72B"},
+    testKey({layout:"US", keyCode:MAC_VK_End, chars:"\uF72B", unmodifiedChars:"\uF72B"},
             nsIDOMKeyEvent.DOM_VK_END, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x73, chars:"\uF729", unmodifiedChars:"\uF729"},
+    testKey({layout:"US", keyCode:MAC_VK_Home, chars:"\uF729", unmodifiedChars:"\uF729"},
             nsIDOMKeyEvent.DOM_VK_HOME, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x7B, chars:"\uF702", unmodifiedChars:"\uF702"},
+    testKey({layout:"US", keyCode:MAC_VK_LeftArrow, chars:"\uF702", unmodifiedChars:"\uF702"},
             nsIDOMKeyEvent.DOM_VK_LEFT, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x7E, chars:"\uF700", unmodifiedChars:"\uF700"},
+    testKey({layout:"US", keyCode:MAC_VK_UpArrow, chars:"\uF700", unmodifiedChars:"\uF700"},
             nsIDOMKeyEvent.DOM_VK_UP, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x7C, chars:"\uF703", unmodifiedChars:"\uF703"},
+    testKey({layout:"US", keyCode:MAC_VK_RightArrow, chars:"\uF703", unmodifiedChars:"\uF703"},
             nsIDOMKeyEvent.DOM_VK_RIGHT, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x7D, chars:"\uF701", unmodifiedChars:"\uF701"},
+    testKey({layout:"US", keyCode:MAC_VK_DownArrow, chars:"\uF701", unmodifiedChars:"\uF701"},
             nsIDOMKeyEvent.DOM_VK_DOWN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x69, chars:"\uF710", unmodifiedChars:"\uF710"},
+    testKey({layout:"US", keyCode:MAC_VK_PC_PrintScreen, chars:"\uF710", unmodifiedChars:"\uF710"},
             nsIDOMKeyEvent.DOM_VK_PRINTSCREEN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x75, chars:"\uF728", unmodifiedChars:"\uF728"},
+    testKey({layout:"US", keyCode:MAC_VK_PC_Delete, chars:"\uF728", unmodifiedChars:"\uF728"},
             nsIDOMKeyEvent.DOM_VK_DELETE, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x6B, chars:"\uF711", unmodifiedChars:"\uF711"},
+    testKey({layout:"US", keyCode:MAC_VK_PC_Pause, chars:"\uF711", unmodifiedChars:"\uF711"},
             nsIDOMKeyEvent.DOM_VK_SCROLL_LOCK, "", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"US", keyCode:0x7A, function:1, chars:"\uF704", unmodifiedChars:"\uF704"},
+    testKey({layout:"US", keyCode:MAC_VK_F1, function:1, chars:"\uF704", unmodifiedChars:"\uF704"},
             nsIDOMKeyEvent.DOM_VK_F1, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x78, function:1, chars:"\uF705", unmodifiedChars:"\uF705"},
+    testKey({layout:"US", keyCode:MAC_VK_F2, function:1, chars:"\uF705", unmodifiedChars:"\uF705"},
             nsIDOMKeyEvent.DOM_VK_F2, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x63, function:1, chars:"\uF706", unmodifiedChars:"\uF706"},
+    testKey({layout:"US", keyCode:MAC_VK_F3, function:1, chars:"\uF706", unmodifiedChars:"\uF706"},
             nsIDOMKeyEvent.DOM_VK_F3, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x76, function:1, chars:"\uF707", unmodifiedChars:"\uF707"},
+    testKey({layout:"US", keyCode:MAC_VK_F4, function:1, chars:"\uF707", unmodifiedChars:"\uF707"},
             nsIDOMKeyEvent.DOM_VK_F4, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x60, function:1, chars:"\uF708", unmodifiedChars:"\uF708"},
+    testKey({layout:"US", keyCode:MAC_VK_F5, function:1, chars:"\uF708", unmodifiedChars:"\uF708"},
             nsIDOMKeyEvent.DOM_VK_F5, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x61, function:1, chars:"\uF709", unmodifiedChars:"\uF709"},
+    testKey({layout:"US", keyCode:MAC_VK_F6, function:1, chars:"\uF709", unmodifiedChars:"\uF709"},
             nsIDOMKeyEvent.DOM_VK_F6, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x62, function:1, chars:"\uF70A", unmodifiedChars:"\uF70A"},
+    testKey({layout:"US", keyCode:MAC_VK_F7, function:1, chars:"\uF70A", unmodifiedChars:"\uF70A"},
             nsIDOMKeyEvent.DOM_VK_F7, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x64, function:1, chars:"\uF70B", unmodifiedChars:"\uF70B"},
+    testKey({layout:"US", keyCode:MAC_VK_F8, function:1, chars:"\uF70B", unmodifiedChars:"\uF70B"},
             nsIDOMKeyEvent.DOM_VK_F8, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x65, function:1, chars:"\uF70C", unmodifiedChars:"\uF70C"},
+    testKey({layout:"US", keyCode:MAC_VK_F9, function:1, chars:"\uF70C", unmodifiedChars:"\uF70C"},
             nsIDOMKeyEvent.DOM_VK_F9, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x6D, function:1, chars:"\uF70D", unmodifiedChars:"\uF70D"},
+    testKey({layout:"US", keyCode:MAC_VK_F10, function:1, chars:"\uF70D", unmodifiedChars:"\uF70D"},
             nsIDOMKeyEvent.DOM_VK_F10, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x67, function:1, chars:"\uF70E", unmodifiedChars:"\uF70E"},
+    testKey({layout:"US", keyCode:MAC_VK_F11, function:1, chars:"\uF70E", unmodifiedChars:"\uF70E"},
             nsIDOMKeyEvent.DOM_VK_F11, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x6F, function:1, chars:"\uF70F", unmodifiedChars:"\uF70F"},
+    testKey({layout:"US", keyCode:MAC_VK_F12, function:1, chars:"\uF70F", unmodifiedChars:"\uF70F"},
             nsIDOMKeyEvent.DOM_VK_F12, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x6A, function:1, chars:"\uF713", unmodifiedChars:"\uF713"},
+    testKey({layout:"US", keyCode:MAC_VK_F16, function:1, chars:"\uF713", unmodifiedChars:"\uF713"},
             nsIDOMKeyEvent.DOM_VK_F16, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x40, function:1, chars:"\uF714", unmodifiedChars:"\uF714"},
+    testKey({layout:"US", keyCode:MAC_VK_F17, function:1, chars:"\uF714", unmodifiedChars:"\uF714"},
             nsIDOMKeyEvent.DOM_VK_F17, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4F, function:1, chars:"\uF715", unmodifiedChars:"\uF715"},
+    testKey({layout:"US", keyCode:MAC_VK_F18, function:1, chars:"\uF715", unmodifiedChars:"\uF715"},
             nsIDOMKeyEvent.DOM_VK_F18, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x50, function:1, chars:"\uF716", unmodifiedChars:"\uF716"},
+    testKey({layout:"US", keyCode:MAC_VK_F19, function:1, chars:"\uF716", unmodifiedChars:"\uF716"},
             nsIDOMKeyEvent.DOM_VK_F19, "", SHOULD_DELIVER_ALL);
 
     // US
     // Alphabet
-    testKey({layout:"US", keyCode:0x00, chars:"a", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, chars:"a", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x00, shift:1, chars:"A", unmodifiedChars:"A"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, shift:1, chars:"A", unmodifiedChars:"A"},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x00, ctrl:1, chars:"\u0001", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, ctrl:1, chars:"\u0001", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x00, alt:1, chars:"\u00E5", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, alt:1, chars:"\u00E5", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00E5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x00, command:1, chars:"a", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, command:1, chars:"a", unmodifiedChars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x0B, chars:"b", unmodifiedChars:"b"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_B, chars:"b", unmodifiedChars:"b"},
             nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0B, shift:1, chars:"B", unmodifiedChars:"B"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_B, shift:1, chars:"B", unmodifiedChars:"B"},
             nsIDOMKeyEvent.DOM_VK_B, "B", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0B, ctrl:1, chars:"\u0002", unmodifiedChars:"b"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_B, ctrl:1, chars:"\u0002", unmodifiedChars:"b"},
             nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0B, alt:1, chars:"\u222B", unmodifiedChars:"b"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_B, alt:1, chars:"\u222B", unmodifiedChars:"b"},
             nsIDOMKeyEvent.DOM_VK_B, "\u222B", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0B, command:1, chars:"b", unmodifiedChars:"b"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_B, command:1, chars:"b", unmodifiedChars:"b"},
             nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x08, chars:"c", unmodifiedChars:"c"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_C, chars:"c", unmodifiedChars:"c"},
             nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x08, shift:1, chars:"C", unmodifiedChars:"C"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_C, shift:1, chars:"C", unmodifiedChars:"C"},
             nsIDOMKeyEvent.DOM_VK_C, "C", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x08, ctrl:1, chars:"\u0003", unmodifiedChars:"c"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_C, ctrl:1, chars:"\u0003", unmodifiedChars:"c"},
             nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x08, alt:1, chars:"\u00E7", unmodifiedChars:"c"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_C, alt:1, chars:"\u00E7", unmodifiedChars:"c"},
             nsIDOMKeyEvent.DOM_VK_C, "\u00E7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x08, command:1, chars:"c", unmodifiedChars:"c"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_C, command:1, chars:"c", unmodifiedChars:"c"},
             nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x02, chars:"d", unmodifiedChars:"d"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_D, chars:"d", unmodifiedChars:"d"},
             nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x02, shift:1, chars:"D", unmodifiedChars:"D"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_D, shift:1, chars:"D", unmodifiedChars:"D"},
             nsIDOMKeyEvent.DOM_VK_D, "D", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x02, ctrl:1, chars:"\u0004", unmodifiedChars:"d"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_D, ctrl:1, chars:"\u0004", unmodifiedChars:"d"},
             nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x02, alt:1, chars:"\u2202", unmodifiedChars:"d"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_D, alt:1, chars:"\u2202", unmodifiedChars:"d"},
             nsIDOMKeyEvent.DOM_VK_D, "\u2202", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x02, command:1, chars:"d", unmodifiedChars:"d"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_D, command:1, chars:"d", unmodifiedChars:"d"},
             nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x0E, chars:"e", unmodifiedChars:"e"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_E, chars:"e", unmodifiedChars:"e"},
             nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0E, shift:1, chars:"E", unmodifiedChars:"E"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_E, shift:1, chars:"E", unmodifiedChars:"E"},
             nsIDOMKeyEvent.DOM_VK_E, "E", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0E, ctrl:1, chars:"\u0005", unmodifiedChars:"e"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_E, ctrl:1, chars:"\u0005", unmodifiedChars:"e"},
             nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0E, alt:1, chars:"", unmodifiedChars:"e"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_E, alt:1, chars:"", unmodifiedChars:"e"},
             nsIDOMKeyEvent.DOM_VK_E, "", SHOULD_DELIVER_NONE); // dead key
-    testKey({layout:"US", keyCode:0x0E, command:1, chars:"e", unmodifiedChars:"e"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_E, command:1, chars:"e", unmodifiedChars:"e"},
             nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x03, chars:"f", unmodifiedChars:"f"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_F, chars:"f", unmodifiedChars:"f"},
             nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x03, shift:1, chars:"F", unmodifiedChars:"F"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_F, shift:1, chars:"F", unmodifiedChars:"F"},
             nsIDOMKeyEvent.DOM_VK_F, "F", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x03, ctrl:1, chars:"\u0006", unmodifiedChars:"f"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_F, ctrl:1, chars:"\u0006", unmodifiedChars:"f"},
             nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x03, alt:1, chars:"\u0192", unmodifiedChars:"f"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_F, alt:1, chars:"\u0192", unmodifiedChars:"f"},
             nsIDOMKeyEvent.DOM_VK_F, "\u0192", SHOULD_DELIVER_ALL);
     // XXX This test starts fullscreen mode.
-    // testKey({layout:"US", keyCode:0x03, command:1, chars:"f", unmodifiedChars:"f"},
+    // testKey({layout:"US", keyCode:MAC_VK_ANSI_F, command:1, chars:"f", unmodifiedChars:"f"},
     //         nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x05, chars:"g", unmodifiedChars:"g"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_G, chars:"g", unmodifiedChars:"g"},
             nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x05, shift:1, chars:"G", unmodifiedChars:"G"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_G, shift:1, chars:"G", unmodifiedChars:"G"},
             nsIDOMKeyEvent.DOM_VK_G, "G", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x05, ctrl:1, chars:"\u0007", unmodifiedChars:"g"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_G, ctrl:1, chars:"\u0007", unmodifiedChars:"g"},
             nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x05, alt:1, chars:"\u00A9", unmodifiedChars:"g"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_G, alt:1, chars:"\u00A9", unmodifiedChars:"g"},
             nsIDOMKeyEvent.DOM_VK_G, "\u00A9", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x05, command:1, chars:"g", unmodifiedChars:"g"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_G, command:1, chars:"g", unmodifiedChars:"g"},
             nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x04, chars:"h", unmodifiedChars:"h"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_H, chars:"h", unmodifiedChars:"h"},
             nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x04, shift:1, chars:"H", unmodifiedChars:"H"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_H, shift:1, chars:"H", unmodifiedChars:"H"},
             nsIDOMKeyEvent.DOM_VK_H, "H", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x04, ctrl:1, chars:"\u0008", unmodifiedChars:"h"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_H, ctrl:1, chars:"\u0008", unmodifiedChars:"h"},
             nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x04, alt:1, chars:"\u02D9", unmodifiedChars:"h"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_H, alt:1, chars:"\u02D9", unmodifiedChars:"h"},
             nsIDOMKeyEvent.DOM_VK_H, "\u02D9", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x04, command:1, chars:"h", unmodifiedChars:"h"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_H, command:1, chars:"h", unmodifiedChars:"h"},
             nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x22, chars:"i", unmodifiedChars:"i"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_I, chars:"i", unmodifiedChars:"i"},
             nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x22, shift:1, chars:"I", unmodifiedChars:"I"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_I, shift:1, chars:"I", unmodifiedChars:"I"},
             nsIDOMKeyEvent.DOM_VK_I, "I", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x22, ctrl:1, chars:"\u0009", unmodifiedChars:"i"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_I, ctrl:1, chars:"\u0009", unmodifiedChars:"i"},
             nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x22, alt:1, chars:"", unmodifiedChars:"i"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_I, alt:1, chars:"", unmodifiedChars:"i"},
             nsIDOMKeyEvent.DOM_VK_I, "", SHOULD_DELIVER_NONE); // dead key
     // XXX This test causes memory leak.
-    // testKey({layout:"US", keyCode:0x22, command:1, chars:"i", unmodifiedChars:"i"},
+    // testKey({layout:"US", keyCode:MAC_VK_ANSI_I, command:1, chars:"i", unmodifiedChars:"i"},
     //         nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x26, chars:"j", unmodifiedChars:"j"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_J, chars:"j", unmodifiedChars:"j"},
             nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x26, shift:1, chars:"J", unmodifiedChars:"J"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_J, shift:1, chars:"J", unmodifiedChars:"J"},
             nsIDOMKeyEvent.DOM_VK_J, "J", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x26, ctrl:1, chars:"\u000A", unmodifiedChars:"j"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_J, ctrl:1, chars:"\u000A", unmodifiedChars:"j"},
             nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x26, alt:1, chars:"\u2206", unmodifiedChars:"j"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_J, alt:1, chars:"\u2206", unmodifiedChars:"j"},
             nsIDOMKeyEvent.DOM_VK_J, "\u2206", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x26, command:1, chars:"j", unmodifiedChars:"j"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_J, command:1, chars:"j", unmodifiedChars:"j"},
             nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x28, chars:"k", unmodifiedChars:"k"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_K, chars:"k", unmodifiedChars:"k"},
             nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x28, shift:1, chars:"K", unmodifiedChars:"K"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_K, shift:1, chars:"K", unmodifiedChars:"K"},
             nsIDOMKeyEvent.DOM_VK_K, "K", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x28, ctrl:1, chars:"\u000B", unmodifiedChars:"k"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_K, ctrl:1, chars:"\u000B", unmodifiedChars:"k"},
             nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x28, alt:1, chars:"\u02DA", unmodifiedChars:"k"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_K, alt:1, chars:"\u02DA", unmodifiedChars:"k"},
             nsIDOMKeyEvent.DOM_VK_K, "\u02DA", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x28, command:1, chars:"k", unmodifiedChars:"k"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_K, command:1, chars:"k", unmodifiedChars:"k"},
             nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x25, chars:"l", unmodifiedChars:"l"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_L, chars:"l", unmodifiedChars:"l"},
             nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x25, shift:1, chars:"L", unmodifiedChars:"L"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_L, shift:1, chars:"L", unmodifiedChars:"L"},
             nsIDOMKeyEvent.DOM_VK_L, "L", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x25, ctrl:1, chars:"\u000C", unmodifiedChars:"l"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_L, ctrl:1, chars:"\u000C", unmodifiedChars:"l"},
             nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x25, alt:1, chars:"\u00AC", unmodifiedChars:"l"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_L, alt:1, chars:"\u00AC", unmodifiedChars:"l"},
             nsIDOMKeyEvent.DOM_VK_L, "\u00AC", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x25, command:1, chars:"l", unmodifiedChars:"l"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_L, command:1, chars:"l", unmodifiedChars:"l"},
             nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x2E, chars:"m", unmodifiedChars:"m"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_M, chars:"m", unmodifiedChars:"m"},
             nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2E, shift:1, chars:"M", unmodifiedChars:"M"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_M, shift:1, chars:"M", unmodifiedChars:"M"},
             nsIDOMKeyEvent.DOM_VK_M, "M", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2E, ctrl:1, chars:"\u000D", unmodifiedChars:"m"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_M, ctrl:1, chars:"\u000D", unmodifiedChars:"m"},
             nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2E, alt:1, chars:"\u00B5", unmodifiedChars:"m"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_M, alt:1, chars:"\u00B5", unmodifiedChars:"m"},
             nsIDOMKeyEvent.DOM_VK_M, "\u00B5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2E, command:1, chars:"m", unmodifiedChars:"m"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_M, command:1, chars:"m", unmodifiedChars:"m"},
             nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x2D, chars:"n", unmodifiedChars:"n"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_N, chars:"n", unmodifiedChars:"n"},
             nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2D, shift:1, chars:"N", unmodifiedChars:"N"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_N, shift:1, chars:"N", unmodifiedChars:"N"},
             nsIDOMKeyEvent.DOM_VK_N, "N", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2D, ctrl:1, chars:"\u000E", unmodifiedChars:"n"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_N, ctrl:1, chars:"\u000E", unmodifiedChars:"n"},
             nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2D, alt:1, chars:"", unmodifiedChars:"n"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_N, alt:1, chars:"", unmodifiedChars:"n"},
             nsIDOMKeyEvent.DOM_VK_N, "", SHOULD_DELIVER_NONE); // dead key
-    testKey({layout:"US", keyCode:0x2D, command:1, chars:"n", unmodifiedChars:"n"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_N, command:1, chars:"n", unmodifiedChars:"n"},
             nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x1F, chars:"o", unmodifiedChars:"o"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_O, chars:"o", unmodifiedChars:"o"},
             nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1F, shift:1, chars:"O", unmodifiedChars:"O"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_O, shift:1, chars:"O", unmodifiedChars:"O"},
             nsIDOMKeyEvent.DOM_VK_O, "O", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1F, ctrl:1, chars:"\u000F", unmodifiedChars:"o"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_O, ctrl:1, chars:"\u000F", unmodifiedChars:"o"},
             nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1F, alt:1, chars:"\u00F8", unmodifiedChars:"o"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_O, alt:1, chars:"\u00F8", unmodifiedChars:"o"},
             nsIDOMKeyEvent.DOM_VK_O, "\u00F8", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1F, command:1, chars:"o", unmodifiedChars:"o"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_O, command:1, chars:"o", unmodifiedChars:"o"},
             nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x23, chars:"p", unmodifiedChars:"p"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_P, chars:"p", unmodifiedChars:"p"},
             nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x23, shift:1, chars:"P", unmodifiedChars:"P"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_P, shift:1, chars:"P", unmodifiedChars:"P"},
             nsIDOMKeyEvent.DOM_VK_P, "P", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x23, ctrl:1, chars:"\u0010", unmodifiedChars:"p"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_P, ctrl:1, chars:"\u0010", unmodifiedChars:"p"},
             nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x23, alt:1, chars:"\u03C0", unmodifiedChars:"p"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_P, alt:1, chars:"\u03C0", unmodifiedChars:"p"},
             nsIDOMKeyEvent.DOM_VK_P, "\u03C0", SHOULD_DELIVER_ALL);
     // XXX This test starts private browsing mode (stopped at the confirmation dialog)
-    // testKey({layout:"US", keyCode:0x23, command:1, chars:"p", unmodifiedChars:"p"},
+    // testKey({layout:"US", keyCode:MAC_VK_ANSI_P, command:1, chars:"p", unmodifiedChars:"p"},
     //         nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x0C, chars:"q", unmodifiedChars:"q"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Q, chars:"q", unmodifiedChars:"q"},
             nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0C, shift:1, chars:"Q", unmodifiedChars:"Q"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Q, shift:1, chars:"Q", unmodifiedChars:"Q"},
             nsIDOMKeyEvent.DOM_VK_Q, "Q", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0C, ctrl:1, chars:"\u0011", unmodifiedChars:"q"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Q, ctrl:1, chars:"\u0011", unmodifiedChars:"q"},
             nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0C, alt:1, chars:"\u0153", unmodifiedChars:"q"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Q, alt:1, chars:"\u0153", unmodifiedChars:"q"},
             nsIDOMKeyEvent.DOM_VK_Q, "\u0153", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0C, command:1, chars:"q", unmodifiedChars:"q"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Q, command:1, chars:"q", unmodifiedChars:"q"},
             nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x0F, chars:"r", unmodifiedChars:"r"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_R, chars:"r", unmodifiedChars:"r"},
             nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0F, shift:1, chars:"R", unmodifiedChars:"R"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_R, shift:1, chars:"R", unmodifiedChars:"R"},
             nsIDOMKeyEvent.DOM_VK_R, "R", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0F, ctrl:1, chars:"\u0012", unmodifiedChars:"r"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_R, ctrl:1, chars:"\u0012", unmodifiedChars:"r"},
             nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0F, alt:1, chars:"\u00AE", unmodifiedChars:"r"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_R, alt:1, chars:"\u00AE", unmodifiedChars:"r"},
             nsIDOMKeyEvent.DOM_VK_R, "\u00AE", SHOULD_DELIVER_ALL);
     // XXX This test makes some tabs and dialogs.
-    // testKey({layout:"US", keyCode:0x0F, command:1, chars:"r", unmodifiedChars:"r"},
+    // testKey({layout:"US", keyCode:MAC_VK_ANSI_R, command:1, chars:"r", unmodifiedChars:"r"},
     //         nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x01, chars:"s", unmodifiedChars:"s"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_S, chars:"s", unmodifiedChars:"s"},
             nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x01, shift:1, chars:"S", unmodifiedChars:"S"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_S, shift:1, chars:"S", unmodifiedChars:"S"},
             nsIDOMKeyEvent.DOM_VK_S, "S", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x01, ctrl:1, chars:"\u0013", unmodifiedChars:"s"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_S, ctrl:1, chars:"\u0013", unmodifiedChars:"s"},
             nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x01, alt:1, chars:"\u00DF", unmodifiedChars:"s"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_S, alt:1, chars:"\u00DF", unmodifiedChars:"s"},
             nsIDOMKeyEvent.DOM_VK_S, "\u00DF", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x01, command:1, chars:"s", unmodifiedChars:"s"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_S, command:1, chars:"s", unmodifiedChars:"s"},
             nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x11, chars:"t", unmodifiedChars:"t"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_T, chars:"t", unmodifiedChars:"t"},
             nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x11, shift:1, chars:"T", unmodifiedChars:"T"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_T, shift:1, chars:"T", unmodifiedChars:"T"},
             nsIDOMKeyEvent.DOM_VK_T, "T", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x11, ctrl:1, chars:"\u0014", unmodifiedChars:"t"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_T, ctrl:1, chars:"\u0014", unmodifiedChars:"t"},
             nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x11, alt:1, chars:"\u2020", unmodifiedChars:"t"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_T, alt:1, chars:"\u2020", unmodifiedChars:"t"},
             nsIDOMKeyEvent.DOM_VK_T, "\u2020", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x11, command:1, chars:"t", unmodifiedChars:"t"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_T, command:1, chars:"t", unmodifiedChars:"t"},
             nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x20, chars:"u", unmodifiedChars:"u"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_U, chars:"u", unmodifiedChars:"u"},
             nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x20, shift:1, chars:"U", unmodifiedChars:"U"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_U, shift:1, chars:"U", unmodifiedChars:"U"},
             nsIDOMKeyEvent.DOM_VK_U, "U", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x20, ctrl:1, chars:"\u0015", unmodifiedChars:"u"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_U, ctrl:1, chars:"\u0015", unmodifiedChars:"u"},
             nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x20, alt:1, chars:"", unmodifiedChars:"u"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_U, alt:1, chars:"", unmodifiedChars:"u"},
             nsIDOMKeyEvent.DOM_VK_U, "", SHOULD_DELIVER_NONE); // dead key
-    testKey({layout:"US", keyCode:0x20, command:1, chars:"u", unmodifiedChars:"u"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_U, command:1, chars:"u", unmodifiedChars:"u"},
             nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x09, chars:"v", unmodifiedChars:"v"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_V, chars:"v", unmodifiedChars:"v"},
             nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x09, shift:1, chars:"V", unmodifiedChars:"V"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_V, shift:1, chars:"V", unmodifiedChars:"V"},
             nsIDOMKeyEvent.DOM_VK_V, "V", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x09, ctrl:1, chars:"\u0016", unmodifiedChars:"v"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_V, ctrl:1, chars:"\u0016", unmodifiedChars:"v"},
             nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x09, alt:1, chars:"\u221A", unmodifiedChars:"v"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_V, alt:1, chars:"\u221A", unmodifiedChars:"v"},
             nsIDOMKeyEvent.DOM_VK_V, "\u221A", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x09, command:1, chars:"v", unmodifiedChars:"v"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_V, command:1, chars:"v", unmodifiedChars:"v"},
             nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x0D, chars:"w", unmodifiedChars:"w"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_W, chars:"w", unmodifiedChars:"w"},
             nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0D, shift:1, chars:"W", unmodifiedChars:"W"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_W, shift:1, chars:"W", unmodifiedChars:"W"},
             nsIDOMKeyEvent.DOM_VK_W, "W", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0D, ctrl:1, chars:"\u0017", unmodifiedChars:"w"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_W, ctrl:1, chars:"\u0017", unmodifiedChars:"w"},
             nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0D, alt:1, chars:"\u2211", unmodifiedChars:"w"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_W, alt:1, chars:"\u2211", unmodifiedChars:"w"},
             nsIDOMKeyEvent.DOM_VK_W, "\u2211", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x0D, command:1, chars:"w", unmodifiedChars:"w"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_W, command:1, chars:"w", unmodifiedChars:"w"},
             nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x07, chars:"x", unmodifiedChars:"x"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_X, chars:"x", unmodifiedChars:"x"},
             nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x07, shift:1, chars:"X", unmodifiedChars:"X"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_X, shift:1, chars:"X", unmodifiedChars:"X"},
             nsIDOMKeyEvent.DOM_VK_X, "X", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x07, ctrl:1, chars:"\u0018", unmodifiedChars:"x"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_X, ctrl:1, chars:"\u0018", unmodifiedChars:"x"},
             nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x07, alt:1, chars:"\u2248", unmodifiedChars:"x"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_X, alt:1, chars:"\u2248", unmodifiedChars:"x"},
             nsIDOMKeyEvent.DOM_VK_X, "\u2248", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x07, command:1, chars:"x", unmodifiedChars:"x"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_X, command:1, chars:"x", unmodifiedChars:"x"},
             nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x10, chars:"y", unmodifiedChars:"y"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Y, chars:"y", unmodifiedChars:"y"},
             nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x10, shift:1, chars:"Y", unmodifiedChars:"Y"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Y, shift:1, chars:"Y", unmodifiedChars:"Y"},
             nsIDOMKeyEvent.DOM_VK_Y, "Y", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x10, ctrl:1, chars:"\u0019", unmodifiedChars:"y"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Y, ctrl:1, chars:"\u0019", unmodifiedChars:"y"},
             nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x10, alt:1, chars:"\u00A5", unmodifiedChars:"y"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Y, alt:1, chars:"\u00A5", unmodifiedChars:"y"},
             nsIDOMKeyEvent.DOM_VK_Y, "\u00A5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x10, command:1, chars:"y", unmodifiedChars:"y"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Y, command:1, chars:"y", unmodifiedChars:"y"},
             nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x06, chars:"z", unmodifiedChars:"z"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Z, chars:"z", unmodifiedChars:"z"},
             nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x06, shift:1, chars:"Z", unmodifiedChars:"Z"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Z, shift:1, chars:"Z", unmodifiedChars:"Z"},
             nsIDOMKeyEvent.DOM_VK_Z, "Z", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x06, ctrl:1, chars:"\u001A", unmodifiedChars:"z"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Z, ctrl:1, chars:"\u001A", unmodifiedChars:"z"},
             nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x06, alt:1, chars:"\u03A9", unmodifiedChars:"z"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Z, alt:1, chars:"\u03A9", unmodifiedChars:"z"},
             nsIDOMKeyEvent.DOM_VK_Z, "\u03A9", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x06, command:1, chars:"z", unmodifiedChars:"z"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Z, command:1, chars:"z", unmodifiedChars:"z"},
             nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
 
     // numeric
-    testKey({layout:"US", keyCode:0x12, chars:"1", unmodifiedChars:"1"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_1, chars:"1", unmodifiedChars:"1"},
             nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x12, shift:1, chars:"!", unmodifiedChars:"!"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_1, shift:1, chars:"!", unmodifiedChars:"!"},
             nsIDOMKeyEvent.DOM_VK_1, "!", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x12, ctrl:1, chars:"1", unmodifiedChars:"1"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_1, ctrl:1, chars:"1", unmodifiedChars:"1"},
             nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x12, alt:1, chars:"\u00A1", unmodifiedChars:"1"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_1, alt:1, chars:"\u00A1", unmodifiedChars:"1"},
             nsIDOMKeyEvent.DOM_VK_1, "\u00A1", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x12, command:1, chars:"1", unmodifiedChars:"1"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_1, command:1, chars:"1", unmodifiedChars:"1"},
             nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x13, chars:"2", unmodifiedChars:"2"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_2, chars:"2", unmodifiedChars:"2"},
             nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x13, shift:1, chars:"@", unmodifiedChars:"@"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_2, shift:1, chars:"@", unmodifiedChars:"@"},
             nsIDOMKeyEvent.DOM_VK_2, "@", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x13, ctrl:1, chars:"2", unmodifiedChars:"2"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_2, ctrl:1, chars:"2", unmodifiedChars:"2"},
             nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x13, alt:1, chars:"\u00A1", unmodifiedChars:"2"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_2, alt:1, chars:"\u00A1", unmodifiedChars:"2"},
             nsIDOMKeyEvent.DOM_VK_2, "\u00A1", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x13, command:1, chars:"2", unmodifiedChars:"2"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_2, command:1, chars:"2", unmodifiedChars:"2"},
             nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x14, chars:"3", unmodifiedChars:"3"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_3, chars:"3", unmodifiedChars:"3"},
             nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x14, shift:1, chars:"#", unmodifiedChars:"#"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_3, shift:1, chars:"#", unmodifiedChars:"#"},
             nsIDOMKeyEvent.DOM_VK_3, "#", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x14, ctrl:1, chars:"3", unmodifiedChars:"3"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_3, ctrl:1, chars:"3", unmodifiedChars:"3"},
             nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x14, alt:1, chars:"\u00A3", unmodifiedChars:"3"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_3, alt:1, chars:"\u00A3", unmodifiedChars:"3"},
             nsIDOMKeyEvent.DOM_VK_3, "\u00A3", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x14, command:1, chars:"3", unmodifiedChars:"3"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_3, command:1, chars:"3", unmodifiedChars:"3"},
             nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x15, chars:"4", unmodifiedChars:"4"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_4, chars:"4", unmodifiedChars:"4"},
             nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x15, shift:1, chars:"$", unmodifiedChars:"$"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_4, shift:1, chars:"$", unmodifiedChars:"$"},
             nsIDOMKeyEvent.DOM_VK_4, "$", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x15, ctrl:1, chars:"4", unmodifiedChars:"4"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_4, ctrl:1, chars:"4", unmodifiedChars:"4"},
             nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x15, alt:1, chars:"\u00A2", unmodifiedChars:"4"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_4, alt:1, chars:"\u00A2", unmodifiedChars:"4"},
             nsIDOMKeyEvent.DOM_VK_4, "\u00A2", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x15, command:1, chars:"4", unmodifiedChars:"4"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_4, command:1, chars:"4", unmodifiedChars:"4"},
             nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x17, chars:"5", unmodifiedChars:"5"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_5, chars:"5", unmodifiedChars:"5"},
             nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x17, shift:1, chars:"%", unmodifiedChars:"%"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_5, shift:1, chars:"%", unmodifiedChars:"%"},
             nsIDOMKeyEvent.DOM_VK_5, "%", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x17, ctrl:1, chars:"5", unmodifiedChars:"5"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_5, ctrl:1, chars:"5", unmodifiedChars:"5"},
             nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x17, alt:1, chars:"\u221E", unmodifiedChars:"5"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_5, alt:1, chars:"\u221E", unmodifiedChars:"5"},
             nsIDOMKeyEvent.DOM_VK_5, "\u221E", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x17, command:1, chars:"5", unmodifiedChars:"5"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_5, command:1, chars:"5", unmodifiedChars:"5"},
             nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x16, chars:"6", unmodifiedChars:"6"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_6, chars:"6", unmodifiedChars:"6"},
             nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x16, shift:1, chars:"^", unmodifiedChars:"^"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_6, shift:1, chars:"^", unmodifiedChars:"^"},
             nsIDOMKeyEvent.DOM_VK_6, "^", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x16, ctrl:1, chars:"6", unmodifiedChars:"6"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_6, ctrl:1, chars:"6", unmodifiedChars:"6"},
             nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x16, alt:1, chars:"\u00A7", unmodifiedChars:"6"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_6, alt:1, chars:"\u00A7", unmodifiedChars:"6"},
             nsIDOMKeyEvent.DOM_VK_6, "\u00A7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x16, command:1, chars:"6", unmodifiedChars:"6"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_6, command:1, chars:"6", unmodifiedChars:"6"},
             nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x1A, chars:"7", unmodifiedChars:"7"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_7, chars:"7", unmodifiedChars:"7"},
             nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1A, shift:1, chars:"\u0026;", unmodifiedChars:"\u0026;"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_7, shift:1, chars:"\u0026;", unmodifiedChars:"\u0026;"},
             nsIDOMKeyEvent.DOM_VK_7, "\u0026", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1A, ctrl:1, chars:"7", unmodifiedChars:"7"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_7, ctrl:1, chars:"7", unmodifiedChars:"7"},
             nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1A, alt:1, chars:"\u00B6", unmodifiedChars:"7"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_7, alt:1, chars:"\u00B6", unmodifiedChars:"7"},
             nsIDOMKeyEvent.DOM_VK_7, "\u00B6", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1A, command:1, chars:"7", unmodifiedChars:"7"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_7, command:1, chars:"7", unmodifiedChars:"7"},
             nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x1C, chars:"8", unmodifiedChars:"8"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_8, chars:"8", unmodifiedChars:"8"},
             nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1C, shift:1, chars:"*", unmodifiedChars:"*"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_8, shift:1, chars:"*", unmodifiedChars:"*"},
             nsIDOMKeyEvent.DOM_VK_8, "*", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1C, ctrl:1, chars:"8", unmodifiedChars:"8"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_8, ctrl:1, chars:"8", unmodifiedChars:"8"},
             nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1C, alt:1, chars:"\u2022", unmodifiedChars:"8"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_8, alt:1, chars:"\u2022", unmodifiedChars:"8"},
             nsIDOMKeyEvent.DOM_VK_8, "\u2022", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1C, command:1, chars:"8", unmodifiedChars:"8"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_8, command:1, chars:"8", unmodifiedChars:"8"},
             nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x19, chars:"9", unmodifiedChars:"9"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_9, chars:"9", unmodifiedChars:"9"},
             nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x19, shift:1, chars:"(", unmodifiedChars:"("},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_9, shift:1, chars:"(", unmodifiedChars:"("},
             nsIDOMKeyEvent.DOM_VK_9, "(", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x19, ctrl:1, chars:"9", unmodifiedChars:"9"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_9, ctrl:1, chars:"9", unmodifiedChars:"9"},
             nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x19, alt:1, chars:"\u00AA", unmodifiedChars:"9"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_9, alt:1, chars:"\u00AA", unmodifiedChars:"9"},
             nsIDOMKeyEvent.DOM_VK_9, "\u00AA", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x19, command:1, chars:"9", unmodifiedChars:"9"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_9, command:1, chars:"9", unmodifiedChars:"9"},
             nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x1D, chars:"0", unmodifiedChars:"0"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_0, chars:"0", unmodifiedChars:"0"},
             nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1D, shift:1, chars:")", unmodifiedChars:")"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_0, shift:1, chars:")", unmodifiedChars:")"},
             nsIDOMKeyEvent.DOM_VK_0, ")", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1D, ctrl:1, chars:"0", unmodifiedChars:"0"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_0, ctrl:1, chars:"0", unmodifiedChars:"0"},
             nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1D, alt:1, chars:"\u00BA", unmodifiedChars:"0"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_0, alt:1, chars:"\u00BA", unmodifiedChars:"0"},
             nsIDOMKeyEvent.DOM_VK_0, "\u00BA", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1D, command:1, chars:"0", unmodifiedChars:"0"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_0, command:1, chars:"0", unmodifiedChars:"0"},
             nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
 
     // other chracters
-    testKey({layout:"US", keyCode:0x32, chars:"`", unmodifiedChars:"`"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Grave, chars:"`", unmodifiedChars:"`"},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x32, shift:1, chars:"~", unmodifiedChars:"~"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Grave, shift:1, chars:"~", unmodifiedChars:"~"},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "~", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x32, ctrl:1, chars:"`", unmodifiedChars:"`"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Grave, ctrl:1, chars:"`", unmodifiedChars:"`"},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x32, alt:1, chars:"", unmodifiedChars:"`"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Grave, alt:1, chars:"", unmodifiedChars:"`"},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_NONE); // dead key
-    testKey({layout:"US", keyCode:0x32, command:1, chars:"`", unmodifiedChars:"`"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Grave, command:1, chars:"`", unmodifiedChars:"`"},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x1B, chars:"-", unmodifiedChars:"-"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Minus, chars:"-", unmodifiedChars:"-"},
             nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1B, shift:1, chars:"_", unmodifiedChars:"_"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Minus, shift:1, chars:"_", unmodifiedChars:"_"},
             nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "_", SHOULD_DELIVER_ALL);
     // TODO:
-    // testKey({layout:"US", keyCode:0x1B, ctrl:1, chars:"\u001F", unmodifiedChars:"-"},
+    // testKey({layout:"US", keyCode:MAC_VK_ANSI_Minus, ctrl:1, chars:"\u001F", unmodifiedChars:"-"},
     //         nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1B, alt:1, chars:"\u2013", unmodifiedChars:"-"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Minus, alt:1, chars:"\u2013", unmodifiedChars:"-"},
             nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "\u2013", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1B, command:1, chars:"-", unmodifiedChars:"-"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Minus, command:1, chars:"-", unmodifiedChars:"-"},
             nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x18, chars:"=", unmodifiedChars:"="},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Equal, chars:"=", unmodifiedChars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x18, shift:1, chars:"+", unmodifiedChars:"+"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Equal, shift:1, chars:"+", unmodifiedChars:"+"},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x18, ctrl:1, chars:"=", unmodifiedChars:"="},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Equal, ctrl:1, chars:"=", unmodifiedChars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x18, alt:1, chars:"\u2260", unmodifiedChars:"="},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Equal, alt:1, chars:"\u2260", unmodifiedChars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "\u2260", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x18, command:1, chars:"=", unmodifiedChars:"="},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Equal, command:1, chars:"=", unmodifiedChars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x21, chars:"[", unmodifiedChars:"["},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_LeftBracket, chars:"[", unmodifiedChars:"["},
             nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x21, shift:1, chars:"{", unmodifiedChars:"{"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_LeftBracket, shift:1, chars:"{", unmodifiedChars:"{"},
             nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "{", SHOULD_DELIVER_ALL);
     // TODO:
-    // testKey({layout:"US", keyCode:0x21, ctrl:1, chars:"\u001B", unmodifiedChars:"["},
+    // testKey({layout:"US", keyCode:MAC_VK_ANSI_LeftBracket, ctrl:1, chars:"\u001B", unmodifiedChars:"["},
     //         nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x21, alt:1, chars:"\u201C", unmodifiedChars:"["},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_LeftBracket, alt:1, chars:"\u201C", unmodifiedChars:"["},
             nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "\u201C", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x21, command:1, chars:"[", unmodifiedChars:"["},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_LeftBracket, command:1, chars:"[", unmodifiedChars:"["},
             nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x1E, chars:"]", unmodifiedChars:"]"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_RightBracket, chars:"]", unmodifiedChars:"]"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1E, shift:1, chars:"}", unmodifiedChars:"}"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_RightBracket, shift:1, chars:"}", unmodifiedChars:"}"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "}", SHOULD_DELIVER_ALL);
     // TODO:
-    // testKey({layout:"US", keyCode:0x1E, ctrl:1, chars:"\u001D", unmodifiedChars:"]"},
+    // testKey({layout:"US", keyCode:MAC_VK_ANSI_RightBracket, ctrl:1, chars:"\u001D", unmodifiedChars:"]"},
     //         nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1E, alt:1, chars:"\u2018", unmodifiedChars:"]"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_RightBracket, alt:1, chars:"\u2018", unmodifiedChars:"]"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "\u2018", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x1E, command:1, chars:"]", unmodifiedChars:"]"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_RightBracket, command:1, chars:"]", unmodifiedChars:"]"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x2A, chars:"\\", unmodifiedChars:"\\"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Backslash, chars:"\\", unmodifiedChars:"\\"},
             nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2A, shift:1, chars:"|", unmodifiedChars:"|"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Backslash, shift:1, chars:"|", unmodifiedChars:"|"},
             nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "|", SHOULD_DELIVER_ALL);
     // TODO:
-    // testKey({layout:"US", keyCode:0x2A, ctrl:1, chars:"\u001C", unmodifiedChars:"\\"},
+    // testKey({layout:"US", keyCode:MAC_VK_ANSI_Backslash, ctrl:1, chars:"\u001C", unmodifiedChars:"\\"},
     //         nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2A, alt:1, chars:"\u00AB", unmodifiedChars:"\\"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Backslash, alt:1, chars:"\u00AB", unmodifiedChars:"\\"},
             nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\u00AB", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2A, command:1, chars:"\\", unmodifiedChars:"\\"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Backslash, command:1, chars:"\\", unmodifiedChars:"\\"},
             nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x29, chars:";", unmodifiedChars:";"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Semicolon, chars:";", unmodifiedChars:";"},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x29, shift:1, chars:":", unmodifiedChars:":"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Semicolon, shift:1, chars:":", unmodifiedChars:":"},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, ":", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x29, ctrl:1, chars:";", unmodifiedChars:";"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Semicolon, ctrl:1, chars:";", unmodifiedChars:";"},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x29, alt:1, chars:"\u2026", unmodifiedChars:";"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Semicolon, alt:1, chars:"\u2026", unmodifiedChars:";"},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, "\u2026", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x29, command:1, chars:";", unmodifiedChars:";"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Semicolon, command:1, chars:";", unmodifiedChars:";"},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x27, chars:"'", unmodifiedChars:"'"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Quote, chars:"'", unmodifiedChars:"'"},
             nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x27, shift:1, chars:"\"", unmodifiedChars:"\""},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Quote, shift:1, chars:"\"", unmodifiedChars:"\""},
             nsIDOMKeyEvent.DOM_VK_QUOTE, "\"", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x27, ctrl:1, chars:"'", unmodifiedChars:"'"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Quote, ctrl:1, chars:"'", unmodifiedChars:"'"},
             nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x27, alt:1, chars:"\u00E6", unmodifiedChars:"'"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Quote, alt:1, chars:"\u00E6", unmodifiedChars:"'"},
             nsIDOMKeyEvent.DOM_VK_QUOTE, "\u00E6", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x27, command:1, chars:"'", unmodifiedChars:"'"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Quote, command:1, chars:"'", unmodifiedChars:"'"},
             nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x2B, chars:",", unmodifiedChars:","},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Comma, chars:",", unmodifiedChars:","},
             nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2B, shift:1, chars:"\u003C", unmodifiedChars:"\u003C"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Comma, shift:1, chars:"\u003C", unmodifiedChars:"\u003C"},
             nsIDOMKeyEvent.DOM_VK_COMMA, "\u003C", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2B, ctrl:1, chars:",", unmodifiedChars:","},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Comma, ctrl:1, chars:",", unmodifiedChars:","},
             nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2B, alt:1, chars:"\u2264", unmodifiedChars:","},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Comma, alt:1, chars:"\u2264", unmodifiedChars:","},
             nsIDOMKeyEvent.DOM_VK_COMMA, "\u2264", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2B, command:1, chars:",", unmodifiedChars:","},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Comma, command:1, chars:",", unmodifiedChars:","},
             nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x2F, chars:".", unmodifiedChars:"."},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Period, chars:".", unmodifiedChars:"."},
             nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2F, shift:1, chars:"\u003E", unmodifiedChars:"\u003E"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Period, shift:1, chars:"\u003E", unmodifiedChars:"\u003E"},
             nsIDOMKeyEvent.DOM_VK_PERIOD, "\u003E", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2F, ctrl:1, chars:".", unmodifiedChars:"."},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Period, ctrl:1, chars:".", unmodifiedChars:"."},
             nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2F, alt:1, chars:"\u2265", unmodifiedChars:"."},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Period, alt:1, chars:"\u2265", unmodifiedChars:"."},
             nsIDOMKeyEvent.DOM_VK_PERIOD, "\u2265", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2F, command:1, chars:".", unmodifiedChars:"."},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Period, command:1, chars:".", unmodifiedChars:"."},
             nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x2C, chars:"/", unmodifiedChars:"/"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Slash, chars:"/", unmodifiedChars:"/"},
             nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2C, shift:1, chars:"?", unmodifiedChars:"?"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Slash, shift:1, chars:"?", unmodifiedChars:"?"},
             nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2C, ctrl:1, chars:"/", unmodifiedChars:"/"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Slash, ctrl:1, chars:"/", unmodifiedChars:"/"},
             nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2C, alt:1, chars:"\u00F7", unmodifiedChars:"/"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Slash, alt:1, chars:"\u00F7", unmodifiedChars:"/"},
             nsIDOMKeyEvent.DOM_VK_SLASH, "\u00F7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x2C, command:1, chars:"/", unmodifiedChars:"/"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Slash, command:1, chars:"/", unmodifiedChars:"/"},
             nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
 
     // numpad
-    testKey({layout:"US", keyCode:0x53, numLock:1, chars:"1", unmodifiedChars:"1"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad1, numLock:1, chars:"1", unmodifiedChars:"1"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x53, numLock:1, shift:1, chars:"1", unmodifiedChars:"1"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad1, numLock:1, shift:1, chars:"1", unmodifiedChars:"1"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x53, numLock:1, ctrl:1, chars:"1", unmodifiedChars:"1"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad1, numLock:1, ctrl:1, chars:"1", unmodifiedChars:"1"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x53, numLock:1, alt:1, chars:"1", unmodifiedChars:"1"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad1, numLock:1, alt:1, chars:"1", unmodifiedChars:"1"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x53, numLock:1, command:1, chars:"1", unmodifiedChars:"1"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad1, numLock:1, command:1, chars:"1", unmodifiedChars:"1"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x54, numLock:1, chars:"2", unmodifiedChars:"2"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad2, numLock:1, chars:"2", unmodifiedChars:"2"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x54, numLock:1, shift:1, chars:"2", unmodifiedChars:"2"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad2, numLock:1, shift:1, chars:"2", unmodifiedChars:"2"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x54, numLock:1, ctrl:1, chars:"2", unmodifiedChars:"2"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad2, numLock:1, ctrl:1, chars:"2", unmodifiedChars:"2"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x54, numLock:1, alt:1, chars:"2", unmodifiedChars:"2"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad2, numLock:1, alt:1, chars:"2", unmodifiedChars:"2"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x54, numLock:1, command:1, chars:"2", unmodifiedChars:"2"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad2, numLock:1, command:1, chars:"2", unmodifiedChars:"2"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x55, numLock:1, chars:"3", unmodifiedChars:"3"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad3, numLock:1, chars:"3", unmodifiedChars:"3"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x55, numLock:1, shift:1, chars:"3", unmodifiedChars:"3"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad3, numLock:1, shift:1, chars:"3", unmodifiedChars:"3"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x55, numLock:1, ctrl:1, chars:"3", unmodifiedChars:"3"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad3, numLock:1, ctrl:1, chars:"3", unmodifiedChars:"3"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x55, numLock:1, alt:1, chars:"3", unmodifiedChars:"3"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad3, numLock:1, alt:1, chars:"3", unmodifiedChars:"3"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x55, numLock:1, command:1, chars:"3", unmodifiedChars:"3"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad3, numLock:1, command:1, chars:"3", unmodifiedChars:"3"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x56, numLock:1, chars:"4", unmodifiedChars:"4"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad4, numLock:1, chars:"4", unmodifiedChars:"4"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x56, numLock:1, shift:1, chars:"4", unmodifiedChars:"4"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad4, numLock:1, shift:1, chars:"4", unmodifiedChars:"4"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x56, numLock:1, ctrl:1, chars:"4", unmodifiedChars:"4"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad4, numLock:1, ctrl:1, chars:"4", unmodifiedChars:"4"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x56, numLock:1, alt:1, chars:"4", unmodifiedChars:"4"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad4, numLock:1, alt:1, chars:"4", unmodifiedChars:"4"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x56, numLock:1, command:1, chars:"4", unmodifiedChars:"4"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad4, numLock:1, command:1, chars:"4", unmodifiedChars:"4"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x57, numLock:1, chars:"5", unmodifiedChars:"5"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad5, numLock:1, chars:"5", unmodifiedChars:"5"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x57, numLock:1, shift:1, chars:"5", unmodifiedChars:"5"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad5, numLock:1, shift:1, chars:"5", unmodifiedChars:"5"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x57, numLock:1, ctrl:1, chars:"5", unmodifiedChars:"5"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad5, numLock:1, ctrl:1, chars:"5", unmodifiedChars:"5"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x57, numLock:1, alt:1, chars:"5", unmodifiedChars:"5"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad5, numLock:1, alt:1, chars:"5", unmodifiedChars:"5"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x57, numLock:1, command:1, chars:"5", unmodifiedChars:"5"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad5, numLock:1, command:1, chars:"5", unmodifiedChars:"5"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x58, numLock:1, chars:"6", unmodifiedChars:"6"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad6, numLock:1, chars:"6", unmodifiedChars:"6"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x58, numLock:1, shift:1, chars:"6", unmodifiedChars:"6"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad6, numLock:1, shift:1, chars:"6", unmodifiedChars:"6"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x58, numLock:1, ctrl:1, chars:"6", unmodifiedChars:"6"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad6, numLock:1, ctrl:1, chars:"6", unmodifiedChars:"6"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x58, numLock:1, alt:1, chars:"6", unmodifiedChars:"6"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad6, numLock:1, alt:1, chars:"6", unmodifiedChars:"6"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x58, numLock:1, command:1, chars:"6", unmodifiedChars:"6"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad6, numLock:1, command:1, chars:"6", unmodifiedChars:"6"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x59, numLock:1, chars:"7", unmodifiedChars:"7"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad7, numLock:1, chars:"7", unmodifiedChars:"7"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x59, numLock:1, shift:1, chars:"7", unmodifiedChars:"7"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad7, numLock:1, shift:1, chars:"7", unmodifiedChars:"7"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x59, numLock:1, ctrl:1, chars:"7", unmodifiedChars:"7"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad7, numLock:1, ctrl:1, chars:"7", unmodifiedChars:"7"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x59, numLock:1, alt:1, chars:"7", unmodifiedChars:"7"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad7, numLock:1, alt:1, chars:"7", unmodifiedChars:"7"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x59, numLock:1, command:1, chars:"7", unmodifiedChars:"7"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad7, numLock:1, command:1, chars:"7", unmodifiedChars:"7"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x5B, numLock:1, chars:"8", unmodifiedChars:"8"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad8, numLock:1, chars:"8", unmodifiedChars:"8"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x5B, numLock:1, shift:1, chars:"8", unmodifiedChars:"8"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad8, numLock:1, shift:1, chars:"8", unmodifiedChars:"8"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x5B, numLock:1, ctrl:1, chars:"8", unmodifiedChars:"8"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad8, numLock:1, ctrl:1, chars:"8", unmodifiedChars:"8"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x5B, numLock:1, alt:1, chars:"8", unmodifiedChars:"8"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad8, numLock:1, alt:1, chars:"8", unmodifiedChars:"8"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x5B, numLock:1, command:1, chars:"8", unmodifiedChars:"8"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad8, numLock:1, command:1, chars:"8", unmodifiedChars:"8"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x5C, numLock:1, chars:"9", unmodifiedChars:"9"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad9, numLock:1, chars:"9", unmodifiedChars:"9"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x5C, numLock:1, shift:1, chars:"9", unmodifiedChars:"9"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad9, numLock:1, shift:1, chars:"9", unmodifiedChars:"9"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x5C, numLock:1, ctrl:1, chars:"9", unmodifiedChars:"9"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad9, numLock:1, ctrl:1, chars:"9", unmodifiedChars:"9"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x5C, numLock:1, alt:1, chars:"9", unmodifiedChars:"9"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad9, numLock:1, alt:1, chars:"9", unmodifiedChars:"9"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x5C, numLock:1, command:1, chars:"9", unmodifiedChars:"9"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad9, numLock:1, command:1, chars:"9", unmodifiedChars:"9"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x52, numLock:1, chars:"0", unmodifiedChars:"0"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad0, numLock:1, chars:"0", unmodifiedChars:"0"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x52, numLock:1, shift:1, chars:"0", unmodifiedChars:"0"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad0, numLock:1, shift:1, chars:"0", unmodifiedChars:"0"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x52, numLock:1, ctrl:1, chars:"0", unmodifiedChars:"0"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad0, numLock:1, ctrl:1, chars:"0", unmodifiedChars:"0"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x52, numLock:1, alt:1, chars:"0", unmodifiedChars:"0"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad0, numLock:1, alt:1, chars:"0", unmodifiedChars:"0"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x52, numLock:1, command:1, chars:"0", unmodifiedChars:"0"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Keypad0, numLock:1, command:1, chars:"0", unmodifiedChars:"0"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x51, numLock:1, chars:"=", unmodifiedChars:"="},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadEquals, numLock:1, chars:"=", unmodifiedChars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x51, numLock:1, shift:1, chars:"=", unmodifiedChars:"="},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadEquals, numLock:1, shift:1, chars:"=", unmodifiedChars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x51, numLock:1, ctrl:1, chars:"=", unmodifiedChars:"="},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadEquals, numLock:1, ctrl:1, chars:"=", unmodifiedChars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x51, numLock:1, alt:1, chars:"=", unmodifiedChars:"="},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadEquals, numLock:1, alt:1, chars:"=", unmodifiedChars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x51, numLock:1, command:1, chars:"=", unmodifiedChars:"="},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadEquals, numLock:1, command:1, chars:"=", unmodifiedChars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x4B, numLock:1, chars:"/", unmodifiedChars:"/"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadDivide, numLock:1, chars:"/", unmodifiedChars:"/"},
             nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4B, numLock:1, shift:1, chars:"/", unmodifiedChars:"/"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadDivide, numLock:1, shift:1, chars:"/", unmodifiedChars:"/"},
             nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4B, numLock:1, ctrl:1, chars:"/", unmodifiedChars:"/"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadDivide, numLock:1, ctrl:1, chars:"/", unmodifiedChars:"/"},
             nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4B, numLock:1, alt:1, chars:"/", unmodifiedChars:"/"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadDivide, numLock:1, alt:1, chars:"/", unmodifiedChars:"/"},
             nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4B, numLock:1, command:1, chars:"/", unmodifiedChars:"/"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadDivide, numLock:1, command:1, chars:"/", unmodifiedChars:"/"},
             nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x43, numLock:1, chars:"*", unmodifiedChars:"*"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadMultiply, numLock:1, chars:"*", unmodifiedChars:"*"},
             nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x43, numLock:1, shift:1, chars:"*", unmodifiedChars:"*"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadMultiply, numLock:1, shift:1, chars:"*", unmodifiedChars:"*"},
             nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x43, numLock:1, ctrl:1, chars:"*", unmodifiedChars:"*"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadMultiply, numLock:1, ctrl:1, chars:"*", unmodifiedChars:"*"},
             nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x43, numLock:1, alt:1, chars:"*", unmodifiedChars:"*"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadMultiply, numLock:1, alt:1, chars:"*", unmodifiedChars:"*"},
             nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x43, numLock:1, command:1, chars:"*", unmodifiedChars:"*"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadMultiply, numLock:1, command:1, chars:"*", unmodifiedChars:"*"},
             nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x4E, numLock:1, chars:"-", unmodifiedChars:"-"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadMinus, numLock:1, chars:"-", unmodifiedChars:"-"},
             nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4E, numLock:1, shift:1, chars:"-", unmodifiedChars:"-"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadMinus, numLock:1, shift:1, chars:"-", unmodifiedChars:"-"},
             nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4E, numLock:1, ctrl:1, chars:"-", unmodifiedChars:"-"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadMinus, numLock:1, ctrl:1, chars:"-", unmodifiedChars:"-"},
             nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4E, numLock:1, alt:1, chars:"-", unmodifiedChars:"-"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadMinus, numLock:1, alt:1, chars:"-", unmodifiedChars:"-"},
             nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4E, numLock:1, command:1, chars:"-", unmodifiedChars:"-"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadMinus, numLock:1, command:1, chars:"-", unmodifiedChars:"-"},
             nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x45, numLock:1, chars:"+", unmodifiedChars:"+"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadPlus, numLock:1, chars:"+", unmodifiedChars:"+"},
             nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x45, numLock:1, shift:1, chars:"+", unmodifiedChars:"+"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadPlus, numLock:1, shift:1, chars:"+", unmodifiedChars:"+"},
             nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x45, numLock:1, ctrl:1, chars:"+", unmodifiedChars:"+"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadPlus, numLock:1, ctrl:1, chars:"+", unmodifiedChars:"+"},
             nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x45, numLock:1, alt:1, chars:"+", unmodifiedChars:"+"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadPlus, numLock:1, alt:1, chars:"+", unmodifiedChars:"+"},
             nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x45, numLock:1, command:1, chars:"+", unmodifiedChars:"+"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadPlus, numLock:1, command:1, chars:"+", unmodifiedChars:"+"},
             nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"US", keyCode:0x4C, numLock:1, chars:"\u0003", unmodifiedChars:"\u0003"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadEnter, numLock:1, chars:"\u0003", unmodifiedChars:"\u0003"},
             nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4C, numLock:1, shift:1, chars:"\u0003", unmodifiedChars:"\u0003"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadEnter, numLock:1, shift:1, chars:"\u0003", unmodifiedChars:"\u0003"},
             nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4C, numLock:1, ctrl:1, chars:"\u0003", unmodifiedChars:"\u0003"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadEnter, numLock:1, ctrl:1, chars:"\u0003", unmodifiedChars:"\u0003"},
             nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4C, numLock:1, alt:1, chars:"\u0003", unmodifiedChars:"\u0003"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadEnter, numLock:1, alt:1, chars:"\u0003", unmodifiedChars:"\u0003"},
             nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:0x4C, numLock:1, command:1, chars:"\u0003", unmodifiedChars:"\u0003"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_KeypadEnter, numLock:1, command:1, chars:"\u0003", unmodifiedChars:"\u0003"},
             nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
 
     // French, numeric
-    testKey({layout:"French", keyCode:0x12, chars:"\u0026", unmodifiedChars:"\u0026"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_1, chars:"\u0026", unmodifiedChars:"\u0026"},
             nsIDOMKeyEvent.DOM_VK_1, "\u0026", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x12, shift:1, chars:"1", unmodifiedChars:"1"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_1, shift:1, chars:"1", unmodifiedChars:"1"},
             nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x12, ctrl:1, chars:"1", unmodifiedChars:"\u0026"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_1, ctrl:1, chars:"1", unmodifiedChars:"\u0026"},
             nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x12, command:1, chars:"\u0026", unmodifiedChars:"\u0026"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_1, command:1, chars:"\u0026", unmodifiedChars:"\u0026"},
             nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"French", keyCode:0x13, chars:"\u00E9", unmodifiedChars:"\u00E9"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_2, chars:"\u00E9", unmodifiedChars:"\u00E9"},
             nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x13, shift:1, chars:"2", unmodifiedChars:"2"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_2, shift:1, chars:"2", unmodifiedChars:"2"},
             nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x13, ctrl:1, chars:"2", unmodifiedChars:"\u00E9"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_2, ctrl:1, chars:"2", unmodifiedChars:"\u00E9"},
             nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x13, command:1, chars:"\u00E9", unmodifiedChars:"\u00E9"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_2, command:1, chars:"\u00E9", unmodifiedChars:"\u00E9"},
             nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"French", keyCode:0x14, chars:"\"", unmodifiedChars:"\""},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_3, chars:"\"", unmodifiedChars:"\""},
             nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x14, shift:1, chars:"3", unmodifiedChars:"3"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_3, shift:1, chars:"3", unmodifiedChars:"3"},
             nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x14, ctrl:1, chars:"3", unmodifiedChars:"\""},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_3, ctrl:1, chars:"3", unmodifiedChars:"\""},
             nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x14, command:1, chars:"\"", unmodifiedChars:"\""},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_3, command:1, chars:"\"", unmodifiedChars:"\""},
             nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"French", keyCode:0x15, chars:"'", unmodifiedChars:"'"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_4, chars:"'", unmodifiedChars:"'"},
             nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x15, shift:1, chars:"4", unmodifiedChars:"4"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_4, shift:1, chars:"4", unmodifiedChars:"4"},
             nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x15, ctrl:1, chars:"4", unmodifiedChars:"'"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_4, ctrl:1, chars:"4", unmodifiedChars:"'"},
             nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x15, command:1, chars:"'", unmodifiedChars:"'"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_4, command:1, chars:"'", unmodifiedChars:"'"},
             nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"French", keyCode:0x17, chars:"(", unmodifiedChars:"("},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_5, chars:"(", unmodifiedChars:"("},
             nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x17, shift:1, chars:"5", unmodifiedChars:"5"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_5, shift:1, chars:"5", unmodifiedChars:"5"},
             nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x17, ctrl:1, chars:"5", unmodifiedChars:"("},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_5, ctrl:1, chars:"5", unmodifiedChars:"("},
             nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x17, command:1, chars:"(", unmodifiedChars:"("},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_5, command:1, chars:"(", unmodifiedChars:"("},
             nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"French", keyCode:0x16, chars:"\u00A7", unmodifiedChars:"\u00A7"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_6, chars:"\u00A7", unmodifiedChars:"\u00A7"},
             nsIDOMKeyEvent.DOM_VK_6, "\u00A7", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x16, shift:1, chars:"6", unmodifiedChars:"6"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_6, shift:1, chars:"6", unmodifiedChars:"6"},
             nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL);
     // TODO:
-    // testKey({layout:"French", keyCode:0x16, ctrl:1, chars:"\u001D", unmodifiedChars:"\u00A7"},
+    // testKey({layout:"French", keyCode:MAC_VK_ANSI_6, ctrl:1, chars:"\u001D", unmodifiedChars:"\u00A7"},
     //         nsIDOMKeyEvent.DOM_VK_6, "", SHOULD_DELIVER_ALL); // Ctrl+6 sets strange char
-    testKey({layout:"French", keyCode:0x16, command:1, chars:"\u00A7", unmodifiedChars:"\u00A7"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_6, command:1, chars:"\u00A7", unmodifiedChars:"\u00A7"},
             nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"French", keyCode:0x1A, chars:"\u00E8", unmodifiedChars:"\u00E8"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_7, chars:"\u00E8", unmodifiedChars:"\u00E8"},
             nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x1A, shift:1, chars:"7", unmodifiedChars:"7"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_7, shift:1, chars:"7", unmodifiedChars:"7"},
             nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x1A, ctrl:1, chars:"7", unmodifiedChars:"\u00E8"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_7, ctrl:1, chars:"7", unmodifiedChars:"\u00E8"},
             nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x1A, command:1, chars:"\u00E8", unmodifiedChars:"\u00E8"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_7, command:1, chars:"\u00E8", unmodifiedChars:"\u00E8"},
             nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"French", keyCode:0x1C, chars:"!", unmodifiedChars:"!"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_8, chars:"!", unmodifiedChars:"!"},
             nsIDOMKeyEvent.DOM_VK_8, "!", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x1C, shift:1, chars:"8", unmodifiedChars:"8"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_8, shift:1, chars:"8", unmodifiedChars:"8"},
             nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x1C, ctrl:1, chars:"8", unmodifiedChars:"!"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_8, ctrl:1, chars:"8", unmodifiedChars:"!"},
             nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x1C, command:1, chars:"!", unmodifiedChars:"!"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_8, command:1, chars:"!", unmodifiedChars:"!"},
             nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"French", keyCode:0x19, chars:"\u00E7", unmodifiedChars:"\u00E7"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_9, chars:"\u00E7", unmodifiedChars:"\u00E7"},
             nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x19, shift:1, chars:"9", unmodifiedChars:"9"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_9, shift:1, chars:"9", unmodifiedChars:"9"},
             nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL);
     // TODO:
-    // testKey({layout:"French", keyCode:0x19, ctrl:1, chars:"\u001C", unmodifiedChars:"\u00E7"},
+    // testKey({layout:"French", keyCode:MAC_VK_ANSI_9, ctrl:1, chars:"\u001C", unmodifiedChars:"\u00E7"},
     //         nsIDOMKeyEvent.DOM_VK_9, "", SHOULD_DELIVER_ALL); // Ctrl+9 sets strange char
-    testKey({layout:"French", keyCode:0x19, command:1, chars:"\u00E7", unmodifiedChars:"\u00E7"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_9, command:1, chars:"\u00E7", unmodifiedChars:"\u00E7"},
             nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"French", keyCode:0x1D, chars:"\u00E0", unmodifiedChars:"\u00E0"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_0, chars:"\u00E0", unmodifiedChars:"\u00E0"},
             nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x1D, shift:1, chars:"0", unmodifiedChars:"0"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_0, shift:1, chars:"0", unmodifiedChars:"0"},
             nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL);
     // XXX No events fired, not sure the reason.
-    // testKey({layout:"French", keyCode:0x1D, ctrl:1, chars:"", unmodifiedChars:"\u00E0"},
+    // testKey({layout:"French", keyCode:MAC_VK_ANSI_0, ctrl:1, chars:"", unmodifiedChars:"\u00E0"},
     //         nsIDOMKeyEvent.DOM_VK_0, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:0x1D, command:1, chars:"\u00E0", unmodifiedChars:"\u00E0"},
+    testKey({layout:"French", keyCode:MAC_VK_ANSI_0, command:1, chars:"\u00E0", unmodifiedChars:"\u00E0"},
             nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
 
     // Thai
     // keycode should be DOM_VK_[A-Z] of the key on the latest ASCII capable keyboard layout is for alphabet
-    testKey({layout:"Thai", keyCode:0x00, chars:"\u0E1F", unmodifiedChars:"\u0E1F"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_A, chars:"\u0E1F", unmodifiedChars:"\u0E1F"},
             nsIDOMKeyEvent.DOM_VK_A, "\u0E1F", SHOULD_DELIVER_ALL);
     // keycode should be shifted character if unshifted character isn't an ASCII character
-    testKey({layout:"Thai", keyCode:0x27, chars:"\u0E07", unmodifiedChars:"\u0E07"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_Quote, chars:"\u0E07", unmodifiedChars:"\u0E07"},
             nsIDOMKeyEvent.DOM_VK_PERIOD, "\u0E07", SHOULD_DELIVER_ALL);
     // keycode should be zero if the character of the key on the latest ASCII capable keyboard layout isn't for alphabet
-    testKey({layout:"Thai", keyCode:0x2F, chars:"\u0E43", unmodifiedChars:"\u0E43"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_Period, chars:"\u0E43", unmodifiedChars:"\u0E43"},
             0, "\u0E43", SHOULD_DELIVER_ALL);
     // keycode should be DOM_VK_[0-9] if the key on the latest ASCII capable keyboard layout is for numeric
-    testKey({layout:"Thai", keyCode:0x12, chars:"\u0E45", unmodifiedChars:"\u0E45"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_1, chars:"\u0E45", unmodifiedChars:"\u0E45"},
             nsIDOMKeyEvent.DOM_VK_1, "\u0E45", SHOULD_DELIVER_ALL);
-    testKey({layout:"Thai", keyCode:0x13, chars:"/", unmodifiedChars:"/"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_2, chars:"/", unmodifiedChars:"/"},
             nsIDOMKeyEvent.DOM_VK_2, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"Thai", keyCode:0x14, chars:"_", unmodifiedChars:"_"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_3, chars:"_", unmodifiedChars:"_"},
             nsIDOMKeyEvent.DOM_VK_3, "_", SHOULD_DELIVER_ALL);
-    testKey({layout:"Thai", keyCode:0x15, chars:"\u0E20", unmodifiedChars:"\u0E20"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_4, chars:"\u0E20", unmodifiedChars:"\u0E20"},
             nsIDOMKeyEvent.DOM_VK_4, "\u0E20", SHOULD_DELIVER_ALL);
-    testKey({layout:"Thai", keyCode:0x17, chars:"\u0E16", unmodifiedChars:"\u0E16"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_5, chars:"\u0E16", unmodifiedChars:"\u0E16"},
             nsIDOMKeyEvent.DOM_VK_5, "\u0E16", SHOULD_DELIVER_ALL);
-    testKey({layout:"Thai", keyCode:0x16, chars:"\u0E38", unmodifiedChars:"\u0E38"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_6, chars:"\u0E38", unmodifiedChars:"\u0E38"},
             nsIDOMKeyEvent.DOM_VK_6, "\u0E38", SHOULD_DELIVER_ALL);
-    testKey({layout:"Thai", keyCode:0x1A, chars:"\u0E36", unmodifiedChars:"\u0E36"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_7, chars:"\u0E36", unmodifiedChars:"\u0E36"},
             nsIDOMKeyEvent.DOM_VK_7, "\u0E36", SHOULD_DELIVER_ALL);
-    testKey({layout:"Thai", keyCode:0x1C, chars:"\u0E04", unmodifiedChars:"\u0E04"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_8, chars:"\u0E04", unmodifiedChars:"\u0E04"},
             nsIDOMKeyEvent.DOM_VK_8, "\u0E04", SHOULD_DELIVER_ALL);
-    testKey({layout:"Thai", keyCode:0x19, chars:"\u0E15", unmodifiedChars:"\u0E15"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_9, chars:"\u0E15", unmodifiedChars:"\u0E15"},
             nsIDOMKeyEvent.DOM_VK_9, "\u0E15", SHOULD_DELIVER_ALL);
-    testKey({layout:"Thai", keyCode:0x1D, chars:"\u0E08", unmodifiedChars:"\u0E08"},
+    testKey({layout:"Thai", keyCode:MAC_VK_ANSI_0, chars:"\u0E08", unmodifiedChars:"\u0E08"},
             nsIDOMKeyEvent.DOM_VK_0, "\u0E08", SHOULD_DELIVER_ALL);
 
     // Dvorak-Qwerty, layout should be changed when Command key is pressed.
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x01, chars:"o", unmodifiedChars:"o"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_S, chars:"o", unmodifiedChars:"o"},
             nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL);
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x01, shift:1, chars:"O", unmodifiedChars:"O"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_S, shift:1, chars:"O", unmodifiedChars:"O"},
             nsIDOMKeyEvent.DOM_VK_O, "O", SHOULD_DELIVER_ALL);
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x01, ctrl:1, chars:"\u000F", unmodifiedChars:"o"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_S, ctrl:1, chars:"\u000F", unmodifiedChars:"o"},
             nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL);
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x01, alt:1, chars:"\u00F8", unmodifiedChars:"o"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_S, alt:1, chars:"\u00F8", unmodifiedChars:"o"},
             nsIDOMKeyEvent.DOM_VK_O, "\u00F8", SHOULD_DELIVER_ALL);
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x01, command:1, chars:"s", unmodifiedChars:"o"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_S, command:1, chars:"s", unmodifiedChars:"o"},
             nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x02, chars:"e", unmodifiedChars:"e"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_D, chars:"e", unmodifiedChars:"e"},
             nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL);
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x02, shift:1, chars:"E", unmodifiedChars:"E"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_D, shift:1, chars:"E", unmodifiedChars:"E"},
             nsIDOMKeyEvent.DOM_VK_E, "E", SHOULD_DELIVER_ALL);
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x02, ctrl:1, chars:"\u0005", unmodifiedChars:"e"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_D, ctrl:1, chars:"\u0005", unmodifiedChars:"e"},
             nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL);
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x02, alt:1, chars:"", unmodifiedChars:"e"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_D, alt:1, chars:"", unmodifiedChars:"e"},
             nsIDOMKeyEvent.DOM_VK_E, "", SHOULD_DELIVER_NONE); // dead key
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x02, command:1, chars:"d", unmodifiedChars:"e"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_D, command:1, chars:"d", unmodifiedChars:"e"},
             nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x22, command:1, alt:1, chars:"^", unmodifiedChars:"c"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_I, command:1, alt:1, chars:"^", unmodifiedChars:"c"},
             nsIDOMKeyEvent.DOM_VK_I, "^", SHOULD_DELIVER_KEYDOWN_KEYPRESS);
-    testKey({layout:"Dvorak-Qwerty", keyCode:0x22, command:1, alt:1, shift:1, chars:"\u02C6", unmodifiedChars:"C"},
+    testKey({layout:"Dvorak-Qwerty", keyCode:MAC_VK_ANSI_I, command:1, alt:1, shift:1, chars:"\u02C6", unmodifiedChars:"C"},
             nsIDOMKeyEvent.DOM_VK_I, "\u02C6", SHOULD_DELIVER_KEYDOWN_KEYPRESS);  }
   else if (IS_WIN) {
     // On Windows, you can use Spy++ or Winspector (free) to watch window messages.
     // The keyCode is given by the wParam of the last WM_KEYDOWN message. The
     // chars string is given by the wParam of the WM_CHAR message. unmodifiedChars
     // is not needed on Windows.
 
     // Plain text input
-    testKey({layout:"US", keyCode:65, chars:"a"},
+    testKey({layout:"US", keyCode:WIN_VK_A, chars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:66, chars:"b"},
+    testKey({layout:"US", keyCode:WIN_VK_B, chars:"b"},
             nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:65, shift:1, chars:"A"},
+    testKey({layout:"US", keyCode:WIN_VK_A, shift:1, chars:"A"},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL);
 
     // Ctrl keys
-    testKey({layout:"US", keyCode:65, ctrl:1, chars:"\u0001"},
+    testKey({layout:"US", keyCode:WIN_VK_A, ctrl:1, chars:"\u0001"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:65, ctrl:1, shift:1, chars:"\u0001"},
+    testKey({layout:"US", keyCode:WIN_VK_A, ctrl:1, shift:1, chars:"\u0001"},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL);
 
     // Alt keys
-    testKey({layout:"US", keyCode:65, alt:1, chars:"a"},
+    testKey({layout:"US", keyCode:WIN_VK_A, alt:1, chars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:65, alt:1, shift:1, chars:"A"},
+    testKey({layout:"US", keyCode:WIN_VK_A, alt:1, shift:1, chars:"A"},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL);
 
     // Shift-ctrl-alt generates no WM_CHAR, but we still get a keypress
-    testKey({layout:"US", keyCode:65, alt:1, ctrl:1, shift:1, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_A, alt:1, ctrl:1, shift:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL);
 
     // Greek plain text
-    testKey({layout:"Greek", keyCode:65, chars:"\u03b1"},
+    testKey({layout:"Greek", keyCode:WIN_VK_A, chars:"\u03b1"},
             nsIDOMKeyEvent.DOM_VK_A, "\u03b1", SHOULD_DELIVER_ALL);
-    testKey({layout:"Greek", keyCode:65, shift:1, chars:"\u0391"},
+    testKey({layout:"Greek", keyCode:WIN_VK_A, shift:1, chars:"\u0391"},
             nsIDOMKeyEvent.DOM_VK_A, "\u0391", SHOULD_DELIVER_ALL);
 
     // Greek ctrl keys produce Latin charcodes
-    testKey({layout:"Greek", keyCode:65, ctrl:1, chars:"\u0001"},
+    testKey({layout:"Greek", keyCode:WIN_VK_A, ctrl:1, chars:"\u0001"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL);
-    testKey({layout:"Greek", keyCode:65, ctrl:1, shift:1, chars:"\u0001"},
+    testKey({layout:"Greek", keyCode:WIN_VK_A, ctrl:1, shift:1, chars:"\u0001"},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL);
 
     // Caps Lock key event
-    testKey({layout:"US", keyCode:20, capsLock:1, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_CAPITAL, capsLock:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"US", keyCode:20, capsLock:0, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_CAPITAL, capsLock:0, chars:""},
             nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
 
     // Win keys
-    testKey({layout:"US", keyCode:8, chars:"\u0008"},
+    testKey({layout:"US", keyCode:WIN_VK_BACK, chars:"\u0008"},
             nsIDOMKeyEvent.DOM_VK_BACK_SPACE, "", SHOULD_DELIVER_ALL);
 
     // all keys on keyboard (keyCode test)
-    testKey({layout:"US", keyCode:9, chars:"\t"},
+    testKey({layout:"US", keyCode:WIN_VK_TAB, chars:"\t"},
             nsIDOMKeyEvent.DOM_VK_TAB, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:12, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_CLEAR, chars:""},
             nsIDOMKeyEvent.DOM_VK_CLEAR, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:13, chars:"\r"},
+    testKey({layout:"US", keyCode:WIN_VK_RETURN, chars:"\r"},
             nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:19, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_PAUSE, chars:""},
             nsIDOMKeyEvent.DOM_VK_PAUSE, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:21, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_KANA, chars:""},
             nsIDOMKeyEvent.DOM_VK_KANA, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:23, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_JUNJA, chars:""},
             nsIDOMKeyEvent.DOM_VK_JUNJA, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:24, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_FINAL, chars:""},
             nsIDOMKeyEvent.DOM_VK_FINAL, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:25, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_KANJI, chars:""},
             nsIDOMKeyEvent.DOM_VK_KANJI, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:27, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_ESCAPE, chars:""},
             nsIDOMKeyEvent.DOM_VK_ESCAPE, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:28, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_CONVERT, chars:""},
             nsIDOMKeyEvent.DOM_VK_CONVERT, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:29, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_NONCONVERT, chars:""},
             nsIDOMKeyEvent.DOM_VK_NONCONVERT, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:30, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_ACCEPT, chars:""},
             nsIDOMKeyEvent.DOM_VK_ACCEPT, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:31, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_MODECHANGE, chars:""},
             nsIDOMKeyEvent.DOM_VK_MODECHANGE, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:32, chars:" "},
+    testKey({layout:"US", keyCode:WIN_VK_SPACE, chars:" "},
             nsIDOMKeyEvent.DOM_VK_SPACE, " ", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:33, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_PRIOR, chars:""},
             nsIDOMKeyEvent.DOM_VK_PAGE_UP, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:34, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_NEXT, chars:""},
             nsIDOMKeyEvent.DOM_VK_PAGE_DOWN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:35, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_END, chars:""},
             nsIDOMKeyEvent.DOM_VK_END, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:36, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_HOME, chars:""},
             nsIDOMKeyEvent.DOM_VK_HOME, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:37, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_LEFT, chars:""},
             nsIDOMKeyEvent.DOM_VK_LEFT, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:38, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_UP, chars:""},
             nsIDOMKeyEvent.DOM_VK_UP, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:39, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_RIGHT, chars:""},
             nsIDOMKeyEvent.DOM_VK_RIGHT, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:40, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_DOWN, chars:""},
             nsIDOMKeyEvent.DOM_VK_DOWN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:41, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_SELECT, chars:""},
             nsIDOMKeyEvent.DOM_VK_SELECT, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:42, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_PRINT, chars:""},
             nsIDOMKeyEvent.DOM_VK_PRINT, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:43, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_EXECUTE, chars:""},
             nsIDOMKeyEvent.DOM_VK_EXECUTE, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:44, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_SNAPSHOT, chars:""},
             nsIDOMKeyEvent.DOM_VK_PRINTSCREEN, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:45, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_INSERT, chars:""},
             nsIDOMKeyEvent.DOM_VK_INSERT, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:46, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_DELETE, chars:""},
             nsIDOMKeyEvent.DOM_VK_DELETE, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:47, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_HELP, chars:""},
             nsIDOMKeyEvent.DOM_VK_HELP, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:95, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_SLEEP, chars:""},
             nsIDOMKeyEvent.DOM_VK_SLEEP, "", SHOULD_DELIVER_ALL);
 
     // US
     // Alphabet
-    testKey({layout:"US", keyCode:65, chars:"a"},
+    testKey({layout:"US", keyCode:WIN_VK_A, chars:"a"},
             nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:65, shift:1, chars:"A"},
+    testKey({layout:"US", keyCode:WIN_VK_A, shift:1, chars:"A"},
             nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:66, chars:"b"},
+    testKey({layout:"US", keyCode:WIN_VK_B, chars:"b"},
             nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:66, shift:1, chars:"B"},
+    testKey({layout:"US", keyCode:WIN_VK_B, shift:1, chars:"B"},
             nsIDOMKeyEvent.DOM_VK_B, "B", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:67, chars:"c"},
+    testKey({layout:"US", keyCode:WIN_VK_C, chars:"c"},
             nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:67, shift:1, chars:"C"},
+    testKey({layout:"US", keyCode:WIN_VK_C, shift:1, chars:"C"},
             nsIDOMKeyEvent.DOM_VK_C, "C", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:68, chars:"d"},
+    testKey({layout:"US", keyCode:WIN_VK_D, chars:"d"},
             nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:68, shift:1, chars:"D"},
+    testKey({layout:"US", keyCode:WIN_VK_D, shift:1, chars:"D"},
             nsIDOMKeyEvent.DOM_VK_D, "D", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:69, chars:"e"},
+    testKey({layout:"US", keyCode:WIN_VK_E, chars:"e"},
             nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:69, shift:1, chars:"E"},
+    testKey({layout:"US", keyCode:WIN_VK_E, shift:1, chars:"E"},
             nsIDOMKeyEvent.DOM_VK_E, "E", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:70, chars:"f"},
+    testKey({layout:"US", keyCode:WIN_VK_F, chars:"f"},
             nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:70, shift:1, chars:"F"},
+    testKey({layout:"US", keyCode:WIN_VK_F, shift:1, chars:"F"},
             nsIDOMKeyEvent.DOM_VK_F, "F", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:71, chars:"g"},
+    testKey({layout:"US", keyCode:WIN_VK_G, chars:"g"},
             nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:71, shift:1, chars:"G"},
+    testKey({layout:"US", keyCode:WIN_VK_G, shift:1, chars:"G"},
             nsIDOMKeyEvent.DOM_VK_G, "G", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:72, chars:"h"},
+    testKey({layout:"US", keyCode:WIN_VK_H, chars:"h"},
             nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:72, shift:1, chars:"H"},
+    testKey({layout:"US", keyCode:WIN_VK_H, shift:1, chars:"H"},
             nsIDOMKeyEvent.DOM_VK_H, "H", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:73, chars:"i"},
+    testKey({layout:"US", keyCode:WIN_VK_I, chars:"i"},
             nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:73, shift:1, chars:"I"},
+    testKey({layout:"US", keyCode:WIN_VK_I, shift:1, chars:"I"},
             nsIDOMKeyEvent.DOM_VK_I, "I", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:74, chars:"j"},
+    testKey({layout:"US", keyCode:WIN_VK_J, chars:"j"},
             nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:74, shift:1, chars:"J"},
+    testKey({layout:"US", keyCode:WIN_VK_J, shift:1, chars:"J"},
             nsIDOMKeyEvent.DOM_VK_J, "J", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:75, chars:"k"},
+    testKey({layout:"US", keyCode:WIN_VK_K, chars:"k"},
             nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:75, shift:1, chars:"K"},
+    testKey({layout:"US", keyCode:WIN_VK_K, shift:1, chars:"K"},
             nsIDOMKeyEvent.DOM_VK_K, "K", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:76, chars:"l"},
+    testKey({layout:"US", keyCode:WIN_VK_L, chars:"l"},
             nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:76, shift:1, chars:"L"},
+    testKey({layout:"US", keyCode:WIN_VK_L, shift:1, chars:"L"},
             nsIDOMKeyEvent.DOM_VK_L, "L", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:77, chars:"m"},
+    testKey({layout:"US", keyCode:WIN_VK_M, chars:"m"},
             nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:77, shift:1, chars:"M"},
+    testKey({layout:"US", keyCode:WIN_VK_M, shift:1, chars:"M"},
             nsIDOMKeyEvent.DOM_VK_M, "M", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:78, chars:"n"},
+    testKey({layout:"US", keyCode:WIN_VK_N, chars:"n"},
             nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:78, shift:1, chars:"N"},
+    testKey({layout:"US", keyCode:WIN_VK_N, shift:1, chars:"N"},
             nsIDOMKeyEvent.DOM_VK_N, "N", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:79, chars:"o"},
+    testKey({layout:"US", keyCode:WIN_VK_O, chars:"o"},
             nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:79, shift:1, chars:"O"},
+    testKey({layout:"US", keyCode:WIN_VK_O, shift:1, chars:"O"},
             nsIDOMKeyEvent.DOM_VK_O, "O", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:80, chars:"p"},
+    testKey({layout:"US", keyCode:WIN_VK_P, chars:"p"},
             nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:80, shift:1, chars:"P"},
+    testKey({layout:"US", keyCode:WIN_VK_P, shift:1, chars:"P"},
             nsIDOMKeyEvent.DOM_VK_P, "P", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:81, chars:"q"},
+    testKey({layout:"US", keyCode:WIN_VK_Q, chars:"q"},
             nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:81, shift:1, chars:"Q"},
+    testKey({layout:"US", keyCode:WIN_VK_Q, shift:1, chars:"Q"},
             nsIDOMKeyEvent.DOM_VK_Q, "Q", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:82, chars:"r"},
+    testKey({layout:"US", keyCode:WIN_VK_R, chars:"r"},
             nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:82, shift:1, chars:"R"},
+    testKey({layout:"US", keyCode:WIN_VK_R, shift:1, chars:"R"},
             nsIDOMKeyEvent.DOM_VK_R, "R", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:83, chars:"s"},
+    testKey({layout:"US", keyCode:WIN_VK_S, chars:"s"},
             nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:83, shift:1, chars:"S"},
+    testKey({layout:"US", keyCode:WIN_VK_S, shift:1, chars:"S"},
             nsIDOMKeyEvent.DOM_VK_S, "S", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:84, chars:"t"},
+    testKey({layout:"US", keyCode:WIN_VK_T, chars:"t"},
             nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:84, shift:1, chars:"T"},
+    testKey({layout:"US", keyCode:WIN_VK_T, shift:1, chars:"T"},
             nsIDOMKeyEvent.DOM_VK_T, "T", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:85, chars:"u"},
+    testKey({layout:"US", keyCode:WIN_VK_U, chars:"u"},
             nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:85, shift:1, chars:"U"},
+    testKey({layout:"US", keyCode:WIN_VK_U, shift:1, chars:"U"},
             nsIDOMKeyEvent.DOM_VK_U, "U", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:86, chars:"v"},
+    testKey({layout:"US", keyCode:WIN_VK_V, chars:"v"},
             nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:86, shift:1, chars:"V"},
+    testKey({layout:"US", keyCode:WIN_VK_V, shift:1, chars:"V"},
             nsIDOMKeyEvent.DOM_VK_V, "V", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:87, chars:"w"},
+    testKey({layout:"US", keyCode:WIN_VK_W, chars:"w"},
             nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:87, shift:1, chars:"W"},
+    testKey({layout:"US", keyCode:WIN_VK_W, shift:1, chars:"W"},
             nsIDOMKeyEvent.DOM_VK_W, "W", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:88, chars:"x"},
+    testKey({layout:"US", keyCode:WIN_VK_X, chars:"x"},
             nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:88, shift:1, chars:"X"},
+    testKey({layout:"US", keyCode:WIN_VK_X, shift:1, chars:"X"},
             nsIDOMKeyEvent.DOM_VK_X, "X", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:89, chars:"y"},
+    testKey({layout:"US", keyCode:WIN_VK_Y, chars:"y"},
             nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:89, shift:1, chars:"Y"},
+    testKey({layout:"US", keyCode:WIN_VK_Y, shift:1, chars:"Y"},
             nsIDOMKeyEvent.DOM_VK_Y, "Y", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:90, chars:"z"},
+    testKey({layout:"US", keyCode:WIN_VK_Z, chars:"z"},
             nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:90, shift:1, chars:"Z"},
+    testKey({layout:"US", keyCode:WIN_VK_Z, shift:1, chars:"Z"},
             nsIDOMKeyEvent.DOM_VK_Z, "Z", SHOULD_DELIVER_ALL);
 
     // Numeric
-    testKey({layout:"US", keyCode:48, chars:"0"},
+    testKey({layout:"US", keyCode:WIN_VK_0, chars:"0"},
             nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:48, shift:1, chars:")"},
+    testKey({layout:"US", keyCode:WIN_VK_0, shift:1, chars:")"},
             nsIDOMKeyEvent.DOM_VK_0, ")", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:49, chars:"1"},
+    testKey({layout:"US", keyCode:WIN_VK_1, chars:"1"},
             nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:49, shift:1, chars:"!"},
+    testKey({layout:"US", keyCode:WIN_VK_1, shift:1, chars:"!"},
             nsIDOMKeyEvent.DOM_VK_1, "!", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:50, chars:"2"},
+    testKey({layout:"US", keyCode:WIN_VK_2, chars:"2"},
             nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:50, shift:1, chars:"@"},
+    testKey({layout:"US", keyCode:WIN_VK_2, shift:1, chars:"@"},
             nsIDOMKeyEvent.DOM_VK_2, "@", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:51, chars:"3"},
+    testKey({layout:"US", keyCode:WIN_VK_3, chars:"3"},
             nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:51, shift:1, chars:"#"},
+    testKey({layout:"US", keyCode:WIN_VK_3, shift:1, chars:"#"},
             nsIDOMKeyEvent.DOM_VK_3, "#", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:52, chars:"4"},
+    testKey({layout:"US", keyCode:WIN_VK_4, chars:"4"},
             nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:52, shift:1, chars:"$"},
+    testKey({layout:"US", keyCode:WIN_VK_4, shift:1, chars:"$"},
             nsIDOMKeyEvent.DOM_VK_4, "$", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:53, chars:"5"},
+    testKey({layout:"US", keyCode:WIN_VK_5, chars:"5"},
             nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:53, shift:1, chars:"%"},
+    testKey({layout:"US", keyCode:WIN_VK_5, shift:1, chars:"%"},
             nsIDOMKeyEvent.DOM_VK_5, "%", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:54, chars:"6"},
+    testKey({layout:"US", keyCode:WIN_VK_6, chars:"6"},
             nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:54, shift:1, chars:"^"},
+    testKey({layout:"US", keyCode:WIN_VK_6, shift:1, chars:"^"},
             nsIDOMKeyEvent.DOM_VK_6, "^", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:55, chars:"7"},
+    testKey({layout:"US", keyCode:WIN_VK_7, chars:"7"},
             nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:55, shift:1, chars:"&"},
+    testKey({layout:"US", keyCode:WIN_VK_7, shift:1, chars:"&"},
             nsIDOMKeyEvent.DOM_VK_7, "&", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:56, chars:"8"},
+    testKey({layout:"US", keyCode:WIN_VK_8, chars:"8"},
             nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:56, shift:1, chars:"*"},
+    testKey({layout:"US", keyCode:WIN_VK_8, shift:1, chars:"*"},
             nsIDOMKeyEvent.DOM_VK_8, "*", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:57, chars:"9"},
+    testKey({layout:"US", keyCode:WIN_VK_9, chars:"9"},
             nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:57, shift:1, chars:"("},
+    testKey({layout:"US", keyCode:WIN_VK_9, shift:1, chars:"("},
             nsIDOMKeyEvent.DOM_VK_9, "(", SHOULD_DELIVER_ALL);
 
     // OEM keys
-    testKey({layout:"US", keyCode:189, chars:"-"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_MINUS, chars:"-"},
             nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:189, shift:1, chars:"_"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_MINUS, shift:1, chars:"_"},
             nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "_", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:187, chars:"="},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_PLUS, chars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:187, shift:1, chars:"+"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_PLUS, shift:1, chars:"+"},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:219, chars:"["},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_4, chars:"["},
             nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:219, shift:1, chars:"{"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_4, shift:1, chars:"{"},
             nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "{", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:221, chars:"]"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_6, chars:"]"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:221, shift:1, chars:"}"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_6, shift:1, chars:"}"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "}", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:186, chars:";"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_1, chars:";"},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:186, shift:1, chars:":"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_1, shift:1, chars:":"},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, ":", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:222, chars:"'"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_7, chars:"'"},
             nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:222, shift:1, chars:"\""},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_7, shift:1, chars:"\""},
             nsIDOMKeyEvent.DOM_VK_QUOTE, "\"", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:220, chars:"\\"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_5, chars:"\\"},
             nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:220, shift:1, chars:"|"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_5, shift:1, chars:"|"},
             nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "|", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:188, chars:","},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_COMMA, chars:","},
             nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:188, shift:1, chars:"<"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_COMMA, shift:1, chars:"<"},
             nsIDOMKeyEvent.DOM_VK_COMMA, "<", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:190, chars:"."},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_PERIOD, chars:"."},
             nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:190, shift:1, chars:">"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_PERIOD, shift:1, chars:">"},
             nsIDOMKeyEvent.DOM_VK_PERIOD, ">", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:191, chars:"/"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_2, chars:"/"},
             nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:191, shift:1, chars:"?"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_2, shift:1, chars:"?"},
             nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:192, chars:"`"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_3, chars:"`"},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:192, shift:1, chars:"~"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_3, shift:1, chars:"~"},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "~", SHOULD_DELIVER_ALL);
 
     // Numpad
-    testKey({layout:"US", keyCode:96, numLock:1, chars:"0"},
+    testKey({layout:"US", keyCode:WIN_VK_NUMPAD0, numLock:1, chars:"0"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:97, numLock:1, chars:"1"},
+    testKey({layout:"US", keyCode:WIN_VK_NUMPAD1, numLock:1, chars:"1"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:98, numLock:1, chars:"2"},
+    testKey({layout:"US", keyCode:WIN_VK_NUMPAD2, numLock:1, chars:"2"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:99, numLock:1, chars:"3"},
+    testKey({layout:"US", keyCode:WIN_VK_NUMPAD3, numLock:1, chars:"3"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:100, numLock:1, chars:"4"},
+    testKey({layout:"US", keyCode:WIN_VK_NUMPAD4, numLock:1, chars:"4"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:101, numLock:1, chars:"5"},
+    testKey({layout:"US", keyCode:WIN_VK_NUMPAD5, numLock:1, chars:"5"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:102, numLock:1, chars:"6"},
+    testKey({layout:"US", keyCode:WIN_VK_NUMPAD6, numLock:1, chars:"6"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:103, numLock:1, chars:"7"},
+    testKey({layout:"US", keyCode:WIN_VK_NUMPAD7, numLock:1, chars:"7"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:104, numLock:1, chars:"8"},
+    testKey({layout:"US", keyCode:WIN_VK_NUMPAD8, numLock:1, chars:"8"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:105, numLock:1, chars:"9"},
+    testKey({layout:"US", keyCode:WIN_VK_NUMPAD9, numLock:1, chars:"9"},
             nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"US", keyCode:106, numLock:1, chars:"*"},
+    testKey({layout:"US", keyCode:WIN_VK_MULTIPLY, numLock:1, chars:"*"},
             nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:106, numLock:1, shift:1, chars:"*"},
+    testKey({layout:"US", keyCode:WIN_VK_MULTIPLY, numLock:1, shift:1, chars:"*"},
             nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:107, numLock:1, chars:"+"},
+    testKey({layout:"US", keyCode:WIN_VK_ADD, numLock:1, chars:"+"},
             nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:107, numLock:1, shift:1, chars:"+"},
+    testKey({layout:"US", keyCode:WIN_VK_ADD, numLock:1, shift:1, chars:"+"},
             nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL);
-    // XXX VK_SEPARATOR isn't used on Win7.  Even if we synthesize this,
-    //     keypress event isn't dispatched.
-    //testKey({layout:"US", keyCode:108, numLock:1, chars:""},
+    // VK_SEPARATOR is keycode for NEC's PC-98 series whose keyboard layout was
+    // different from current PC's keyboard layout and it cannot connect to
+    // current PC.  Note that even if we synthesize WM_KEYDOWN with
+    // VK_SEPARATOR, it doesn't work on Win7.
+    //testKey({layout:"US", keyCode:WIN_VK_SEPARATOR, numLock:1, chars:""},
     //        nsIDOMKeyEvent.DOM_VK_SEPARATOR, "", SHOULD_DELIVER_ALL);
-    //testKey({layout:"US", keyCode:108, numLock:1, shift:1, chars:""},
+    //testKey({layout:"US", keyCode:WIN_VK_SEPARATOR, numLock:1, shift:1, chars:""},
     //        nsIDOMKeyEvent.DOM_VK_SEPARATOR, "", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:109, numLock:1, chars:"-"},
+    testKey({layout:"US", keyCode:WIN_VK_SUBTRACT, numLock:1, chars:"-"},
             nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:109, numLock:1, shift:1, chars:"-"},
+    testKey({layout:"US", keyCode:WIN_VK_SUBTRACT, numLock:1, shift:1, chars:"-"},
             nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:110, numLock:1, chars:"."},
+    testKey({layout:"US", keyCode:WIN_VK_DECIMAL, numLock:1, chars:"."},
             nsIDOMKeyEvent.DOM_VK_DECIMAL, ".", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:110, numLock:1, shift:1, chars:"."},
+    testKey({layout:"US", keyCode:WIN_VK_DECIMAL, numLock:1, shift:1, chars:"."},
             nsIDOMKeyEvent.DOM_VK_DECIMAL, ".", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:111, numLock:1, chars:"/"},
+    testKey({layout:"US", keyCode:WIN_VK_DIVIDE, numLock:1, chars:"/"},
             nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"US", keyCode:111, numLock:1, shift:1, chars:"/"},
+    testKey({layout:"US", keyCode:WIN_VK_DIVIDE, numLock:1, shift:1, chars:"/"},
             nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL);
     // XXX we cannot test numpad keys without NumLock becasue Windows
     // uses same keycode for Home, Up, PageUp, Left, Clear(5), Right,
     // End, Down, PageDown, Ins, Del of Numpad.
 
     // Even if widget receives unknown keycode, it should dispatch key events
     // whose keycode is 0 rather than native keycode.
-    testKey({layout:"US", keyCode:58, numLock:1, chars:""},
+    testKey({layout:"US", keyCode:0x3A, numLock:1, chars:""},
             0, "", SHOULD_DELIVER_ALL);
 
     // French
     // Numeric
-    testKey({layout:"French", keyCode:48, chars:"\u00E0"},
+    testKey({layout:"French", keyCode:WIN_VK_0, chars:"\u00E0"},
             nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:48, shift:1, chars:"0"},
+    testKey({layout:"French", keyCode:WIN_VK_0, shift:1, chars:"0"},
             nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:49, chars:"&"},
+    testKey({layout:"French", keyCode:WIN_VK_1, chars:"&"},
             nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:49, shift:1, chars:"1"},
+    testKey({layout:"French", keyCode:WIN_VK_1, shift:1, chars:"1"},
             nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:50, chars:"\u00E9"},
+    testKey({layout:"French", keyCode:WIN_VK_2, chars:"\u00E9"},
             nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:50, shift:1, chars:"2"},
+    testKey({layout:"French", keyCode:WIN_VK_2, shift:1, chars:"2"},
             nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:51, chars:"\""},
+    testKey({layout:"French", keyCode:WIN_VK_3, chars:"\""},
             nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:51, shift:1, chars:"3"},
+    testKey({layout:"French", keyCode:WIN_VK_3, shift:1, chars:"3"},
             nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:52, chars:"'"},
+    testKey({layout:"French", keyCode:WIN_VK_4, chars:"'"},
             nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:52, shift:1, chars:"4"},
+    testKey({layout:"French", keyCode:WIN_VK_4, shift:1, chars:"4"},
             nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:53, chars:"("},
+    testKey({layout:"French", keyCode:WIN_VK_5, chars:"("},
             nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:53, shift:1, chars:"5"},
+    testKey({layout:"French", keyCode:WIN_VK_5, shift:1, chars:"5"},
             nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:54, chars:"-"},
+    testKey({layout:"French", keyCode:WIN_VK_6, chars:"-"},
             nsIDOMKeyEvent.DOM_VK_6, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:54, shift:1, chars:"6"},
+    testKey({layout:"French", keyCode:WIN_VK_6, shift:1, chars:"6"},
             nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:55, chars:"\u00E8"},
+    testKey({layout:"French", keyCode:WIN_VK_7, chars:"\u00E8"},
             nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:55, shift:1, chars:"7"},
+    testKey({layout:"French", keyCode:WIN_VK_7, shift:1, chars:"7"},
             nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:56, chars:"_"},
+    testKey({layout:"French", keyCode:WIN_VK_8, chars:"_"},
             nsIDOMKeyEvent.DOM_VK_8, "_", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:56, shift:1, chars:"8"},
+    testKey({layout:"French", keyCode:WIN_VK_8, shift:1, chars:"8"},
             nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:57, chars:"\u00E7"},
+    testKey({layout:"French", keyCode:WIN_VK_9, chars:"\u00E7"},
             nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:57, shift:1, chars:"9"},
+    testKey({layout:"French", keyCode:WIN_VK_9, shift:1, chars:"9"},
             nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL);
 
     // Numeric with ShiftLock
-    testKey({layout:"French", keyCode:48, capsLock:1, chars:"0"},
+    testKey({layout:"French", keyCode:WIN_VK_0, capsLock:1, chars:"0"},
             nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:48, capsLock:1, shift:1, chars:"\u00E0"},
+    testKey({layout:"French", keyCode:WIN_VK_0, capsLock:1, shift:1, chars:"\u00E0"},
             nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:49, capsLock:1, chars:"1"},
+    testKey({layout:"French", keyCode:WIN_VK_1, capsLock:1, chars:"1"},
             nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:49, capsLock:1, shift:1, chars:"&"},
+    testKey({layout:"French", keyCode:WIN_VK_1, capsLock:1, shift:1, chars:"&"},
             nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:50, capsLock:1, chars:"2"},
+    testKey({layout:"French", keyCode:WIN_VK_2, capsLock:1, chars:"2"},
             nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:50, capsLock:1, shift:1, chars:"\u00E9"},
+    testKey({layout:"French", keyCode:WIN_VK_2, capsLock:1, shift:1, chars:"\u00E9"},
             nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:51, capsLock:1, chars:"3"},
+    testKey({layout:"French", keyCode:WIN_VK_3, capsLock:1, chars:"3"},
             nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:51, capsLock:1, shift:1, chars:"\""},
+    testKey({layout:"French", keyCode:WIN_VK_3, capsLock:1, shift:1, chars:"\""},
             nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:52, capsLock:1, chars:"4"},
+    testKey({layout:"French", keyCode:WIN_VK_4, capsLock:1, chars:"4"},
             nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:52, capsLock:1, shift:1, chars:"'"},
+    testKey({layout:"French", keyCode:WIN_VK_4, capsLock:1, shift:1, chars:"'"},
             nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:53, capsLock:1, chars:"5"},
+    testKey({layout:"French", keyCode:WIN_VK_5, capsLock:1, chars:"5"},
             nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:53, capsLock:1, shift:1, chars:"("},
+    testKey({layout:"French", keyCode:WIN_VK_5, capsLock:1, shift:1, chars:"("},
             nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:54, capsLock:1, chars:"6"},
+    testKey({layout:"French", keyCode:WIN_VK_6, capsLock:1, chars:"6"},
             nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:54, capsLock:1, shift:1, chars:"-"},
+    testKey({layout:"French", keyCode:WIN_VK_6, capsLock:1, shift:1, chars:"-"},
             nsIDOMKeyEvent.DOM_VK_6, "-", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:55, capsLock:1, chars:"7"},
+    testKey({layout:"French", keyCode:WIN_VK_7, capsLock:1, chars:"7"},
             nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:55, capsLock:1, shift:1, chars:"\u00E8"},
+    testKey({layout:"French", keyCode:WIN_VK_7, capsLock:1, shift:1, chars:"\u00E8"},
             nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:56, capsLock:1, chars:"8"},
+    testKey({layout:"French", keyCode:WIN_VK_8, capsLock:1, chars:"8"},
             nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:56, capsLock:1, shift:1, chars:"_"},
+    testKey({layout:"French", keyCode:WIN_VK_8, capsLock:1, shift:1, chars:"_"},
             nsIDOMKeyEvent.DOM_VK_8, "_", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:57, capsLock:1, chars:"9"},
+    testKey({layout:"French", keyCode:WIN_VK_9, capsLock:1, chars:"9"},
             nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:57, capsLock:1, shift:1, chars:"\u00E7"},
+    testKey({layout:"French", keyCode:WIN_VK_9, capsLock:1, shift:1, chars:"\u00E7"},
             nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_ALL);
 
     // OEM keys
-    testKey({layout:"French", keyCode:222, chars:"\u00B2"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_7, chars:"\u00B2"},
             0, "\u00B2", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:222, shift:1, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_7, shift:1, chars:""},
             0, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"French", keyCode:219, chars:")"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_4, chars:")"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, ")", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:219, shift:1, chars:"\u00B0"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_4, shift:1, chars:"\u00B0"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, "\u00B0", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:187, chars:"="},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_PLUS, chars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:187, shift:1, chars:"+"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_PLUS, shift:1, chars:"+"},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL);
-    //testKey({layout:"French", keyCode:221, chars:""},
+    //testKey({layout:"French", keyCode:WIN_VK_OEM_6, chars:""},
     //        nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP); // Dead-key
-    //testKey({layout:"French", keyCode:221, shift:1, chars:""},
+    //testKey({layout:"French", keyCode:WIN_VK_OEM_6, shift:1, chars:""},
     //        nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_ALL); // Dead-key
-    testKey({layout:"French", keyCode:186, chars:"$"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_1, chars:"$"},
             nsIDOMKeyEvent.DOM_VK_DOLLAR, "$", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:186, shift:1, chars:"\u00A3"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_1, shift:1, chars:"\u00A3"},
             nsIDOMKeyEvent.DOM_VK_DOLLAR, "\u00A3", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:192, chars:"\u00F9"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_3, chars:"\u00F9"},
             nsIDOMKeyEvent.DOM_VK_PERCENT, "\u00F9", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:192, shift:1, chars:"%"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_3, shift:1, chars:"%"},
             nsIDOMKeyEvent.DOM_VK_PERCENT, "%", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:220, chars:"*"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_5, chars:"*"},
             nsIDOMKeyEvent.DOM_VK_ASTERISK, "*", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:220, shift:1, chars:"\u00B5"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_5, shift:1, chars:"\u00B5"},
             nsIDOMKeyEvent.DOM_VK_ASTERISK, "\u00B5", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:226, chars:"<"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_102, chars:"<"},
             nsIDOMKeyEvent.DOM_VK_LESS_THAN, "<", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:226, shift:1, chars:">"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_102, shift:1, chars:">"},
             nsIDOMKeyEvent.DOM_VK_LESS_THAN, ">", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:188, chars:","},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_COMMA, chars:","},
             nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:188, shift:1, chars:"?"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_COMMA, shift:1, chars:"?"},
             nsIDOMKeyEvent.DOM_VK_COMMA, "?", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:190, chars:";"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_PERIOD, chars:";"},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:190, shift:1, chars:"."},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_PERIOD, shift:1, chars:"."},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, ".", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:191, chars:":"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_2, chars:":"},
             nsIDOMKeyEvent.DOM_VK_COLON, ":", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:191, shift:1, chars:"/"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_2, shift:1, chars:"/"},
             nsIDOMKeyEvent.DOM_VK_COLON, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:223, chars:"!"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_8, chars:"!"},
             nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "!", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:223, shift:1, chars:"\u00A7"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_8, shift:1, chars:"\u00A7"},
             nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "\u00A7", SHOULD_DELIVER_ALL);
 
     // OEM keys with ShiftLock
-    testKey({layout:"French", keyCode:222, capsLock:1, chars:"\u00B2"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_7, capsLock:1, chars:"\u00B2"},
             0, "\u00B2", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:222, capsLock:1, shift:1, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_7, capsLock:1, shift:1, chars:""},
             0, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"French", keyCode:219, capsLock:1, chars:"\u00B0"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_4, capsLock:1, chars:"\u00B0"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, "\u00B0", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:219, capsLock:1, shift:1, chars:")"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_4, capsLock:1, shift:1, chars:")"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, ")", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:187, capsLock:1, chars:"+"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_PLUS, capsLock:1, chars:"+"},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:187, capsLock:1, shift:1, chars:"="},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_PLUS, capsLock:1, shift:1, chars:"="},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL);
-    //testKey({layout:"French", keyCode:221, capsLock:1, chars:""},
+    //testKey({layout:"French", keyCode:WIN_VK_OEM_6, capsLock:1, chars:""},
     //        0, "", SHOULD_DELIVER_KEYDOWN_KEYUP); // Dead-key
-    //testKey({layout:"French", keyCode:221, capsLock:1, shift:1, chars:""},
+    //testKey({layout:"French", keyCode:WIN_VK_OEM_6, capsLock:1, shift:1, chars:""},
     //        0, "", SHOULD_DELIVER_KEYDOWN_KEYUP); // Dead-key
-    testKey({layout:"French", keyCode:186, capsLock:1, chars:"\u00A3"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_1, capsLock:1, chars:"\u00A3"},
             nsIDOMKeyEvent.DOM_VK_DOLLAR, "\u00A3", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:186, capsLock:1, shift:1, chars:"$"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_1, capsLock:1, shift:1, chars:"$"},
             nsIDOMKeyEvent.DOM_VK_DOLLAR, "$", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:192, capsLock:1, chars:"%"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_3, capsLock:1, chars:"%"},
             nsIDOMKeyEvent.DOM_VK_PERCENT, "%", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:192, capsLock:1, shift:1, chars:"\u00F9"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_3, capsLock:1, shift:1, chars:"\u00F9"},
             nsIDOMKeyEvent.DOM_VK_PERCENT, "\u00F9", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:220, capsLock:1, chars:"\u00B5"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_5, capsLock:1, chars:"\u00B5"},
             nsIDOMKeyEvent.DOM_VK_ASTERISK, "\u00B5", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:220, capsLock:1, shift:1, chars:"*"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_5, capsLock:1, shift:1, chars:"*"},
             nsIDOMKeyEvent.DOM_VK_ASTERISK, "*", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:226, capsLock:1, chars:"<"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_102, capsLock:1, chars:"<"},
             nsIDOMKeyEvent.DOM_VK_LESS_THAN, "<", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:226, capsLock:1, shift:1, chars:">"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_102, capsLock:1, shift:1, chars:">"},
             nsIDOMKeyEvent.DOM_VK_LESS_THAN, ">", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:188, capsLock:1, chars:"?"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_COMMA, capsLock:1, chars:"?"},
             nsIDOMKeyEvent.DOM_VK_COMMA, "?", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:188, capsLock:1, shift:1, chars:","},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_COMMA, capsLock:1, shift:1, chars:","},
             nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:190, capsLock:1, chars:"."},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_PERIOD, capsLock:1, chars:"."},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, ".", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:190, capsLock:1, shift:1, chars:";"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_PERIOD, capsLock:1, shift:1, chars:";"},
             nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:191, capsLock:1, chars:"/"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_2, capsLock:1, chars:"/"},
             nsIDOMKeyEvent.DOM_VK_COLON, "/", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:191, capsLock:1, shift:1, chars:":"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_2, capsLock:1, shift:1, chars:":"},
             nsIDOMKeyEvent.DOM_VK_COLON, ":", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:223, capsLock:1, chars:"\u00A7"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_8, capsLock:1, chars:"\u00A7"},
             nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "\u00A7", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:223, capsLock:1, shift:1, chars:"!"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_8, capsLock:1, shift:1, chars:"!"},
             nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "!", SHOULD_DELIVER_ALL);
 
     // AltGr
-    testKey({layout:"French", keyCode:48, altGr:1, chars:"@"},
+    testKey({layout:"French", keyCode:WIN_VK_0, altGr:1, chars:"@"},
             nsIDOMKeyEvent.DOM_VK_0, "@", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:49, altGr:1, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_1, altGr:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL_BUT_NOT_CAUSE_INPUT);
-    //testKey({layout:"French", keyCode:50, altGr:1, chars:""},
+    //testKey({layout:"French", keyCode:WIN_VK_2, altGr:1, chars:""},
     //        nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL); // Dead-key
-    testKey({layout:"French", keyCode:51, altGr:1, chars:"#"},
+    testKey({layout:"French", keyCode:WIN_VK_3, altGr:1, chars:"#"},
             nsIDOMKeyEvent.DOM_VK_3, "#", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:52, altGr:1, chars:"{"},
+    testKey({layout:"French", keyCode:WIN_VK_4, altGr:1, chars:"{"},
             nsIDOMKeyEvent.DOM_VK_4, "{", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:53, altGr:1, chars:"["},
+    testKey({layout:"French", keyCode:WIN_VK_5, altGr:1, chars:"["},
             nsIDOMKeyEvent.DOM_VK_5, "[", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:54, altGr:1, chars:"|"},
+    testKey({layout:"French", keyCode:WIN_VK_6, altGr:1, chars:"|"},
             nsIDOMKeyEvent.DOM_VK_6, "|", SHOULD_DELIVER_ALL);
-    //testKey({layout:"French", keyCode:55, altGr:1, chars:""},
+    //testKey({layout:"French", keyCode:WIN_VK_7, altGr:1, chars:""},
     //        nsIDOMKeyEvent.DOM_VK_7, "", SHOULD_DELIVER_ALL); // Dead-key
-    testKey({layout:"French", keyCode:56, altGr:1, chars:"\\"},
+    testKey({layout:"French", keyCode:WIN_VK_8, altGr:1, chars:"\\"},
             nsIDOMKeyEvent.DOM_VK_8, "\\", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:57, altGr:1, chars:"^"},
+    testKey({layout:"French", keyCode:WIN_VK_9, altGr:1, chars:"^"},
             nsIDOMKeyEvent.DOM_VK_9, "^", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:219, altGr:1, chars:"]"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_4, altGr:1, chars:"]"},
             nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, "]", SHOULD_DELIVER_ALL);
-    testKey({layout:"French", keyCode:187, altGr:1, chars:"}"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_PLUS, altGr:1, chars:"}"},
             nsIDOMKeyEvent.DOM_VK_EQUALS, "}", SHOULD_DELIVER_ALL);
 
     // German
-    testKey({layout:"German", keyCode:191, chars:"#"},
+    testKey({layout:"German", keyCode:WIN_VK_OEM_2, chars:"#"},
             nsIDOMKeyEvent.DOM_VK_HASH, "#", SHOULD_DELIVER_ALL);
-    testKey({layout:"German", keyCode:191, shift:1, chars:"'"},
+    testKey({layout:"German", keyCode:WIN_VK_OEM_2, shift:1, chars:"'"},
             nsIDOMKeyEvent.DOM_VK_HASH, "'", SHOULD_DELIVER_ALL);
 
     // Norwegian
-    testKey({layout:"Norwegian", keyCode:220, chars:"|"},
+    testKey({layout:"Norwegian", keyCode:WIN_VK_OEM_5, chars:"|"},
             nsIDOMKeyEvent.DOM_VK_PIPE, "|", SHOULD_DELIVER_ALL);
-    testKey({layout:"Norwegian", keyCode:220, shift:1, chars:"\u00A7"},
+    testKey({layout:"Norwegian", keyCode:WIN_VK_OEM_5, shift:1, chars:"\u00A7"},
             nsIDOMKeyEvent.DOM_VK_PIPE, "\u00A7", SHOULD_DELIVER_ALL);
 
     // Dead keys on any layouts
-    testKey({layout:"French", keyCode:221, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_6, chars:""},
             nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"French", keyCode:221, chars:"^^"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_6, chars:"^^"},
             nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "^^", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"French", keyCode:221, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_6, chars:""},
             nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"French", keyCode:65, chars:"\u00E2"},
+    testKey({layout:"French", keyCode:WIN_VK_A, chars:"\u00E2"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00E2", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"French", keyCode:221, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_6, chars:""},
             nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"French", keyCode:65, shift:1, chars:"\u00C2"},
+    testKey({layout:"French", keyCode:WIN_VK_A, shift:1, chars:"\u00C2"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00C2", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"French", keyCode:221, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_6, chars:""},
             nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"French", keyCode:81, chars:"^q"},
+    testKey({layout:"French", keyCode:WIN_VK_Q, chars:"^q"},
             nsIDOMKeyEvent.DOM_VK_Q, "^q", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"French", keyCode:221, shift:1, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_6, shift:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"French", keyCode:221, shift:1, chars:"\u00A8\u00A8"},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_6, shift:1, chars:"\u00A8\u00A8"},
             nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "\u00A8\u00A8", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"French", keyCode:221, shift:1, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_6, shift:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"French", keyCode:65, shift:1, chars:"\u00C4"},
+    testKey({layout:"French", keyCode:WIN_VK_A, shift:1, chars:"\u00C4"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00C4", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"French", keyCode:221, shift:1, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_6, shift:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"French", keyCode:65, chars:"\u00E4"},
+    testKey({layout:"French", keyCode:WIN_VK_A, chars:"\u00E4"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00E4", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"French", keyCode:221, shift:1, chars:""},
+    testKey({layout:"French", keyCode:WIN_VK_OEM_6, shift:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"French", keyCode:81, shift:1, chars:"\u00A8Q"},
+    testKey({layout:"French", keyCode:WIN_VK_Q, shift:1, chars:"\u00A8Q"},
             nsIDOMKeyEvent.DOM_VK_Q, "\u00A8Q", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:186, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_1, chars:""},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:186, chars:"``"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_1, chars:"``"},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "``", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:186, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_1, chars:""},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:65, chars:"\u00E0"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_A, chars:"\u00E0"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00E0", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:186, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_1, chars:""},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:65, shift:1, chars:"\u00C0"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_A, shift:1, chars:"\u00C0"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00C0", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:186, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_1, chars:""},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:81, chars:"`q"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_Q, chars:"`q"},
             nsIDOMKeyEvent.DOM_VK_Q, "`q", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:186, shift:1, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_1, shift:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:186, shift:1, chars:"^^"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_1, shift:1, chars:"^^"},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "^^", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:186, shift:1, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_1, shift:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:65, shift:1, chars:"\u00C2"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_A, shift:1, chars:"\u00C2"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00C2", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:186, shift:1, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_1, shift:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:65, chars:"\u00E2"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_A, chars:"\u00E2"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00E2", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:186, shift:1, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_1, shift:1, chars:""},
             nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:81, shift:1, chars:"^Q"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_Q, shift:1, chars:"^Q"},
             nsIDOMKeyEvent.DOM_VK_Q, "^Q", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:222, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_7, chars:""},
             0, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:222, chars:"\u00B4\u00B4"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_7, chars:"\u00B4\u00B4"},
             0, "\u00B4\u00B4", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:222, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_7, chars:""},
             0, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:65, chars:"\u00E1"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_A, chars:"\u00E1"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00E1", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:222, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_7, chars:""},
             0, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:65, shift:1, chars:"\u00C1"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_A, shift:1, chars:"\u00C1"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00C1", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:222, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_7, chars:""},
             0, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:81, chars:"\u00B4q"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_Q, chars:"\u00B4q"},
             nsIDOMKeyEvent.DOM_VK_Q, "\u00B4q", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:222, shift:1, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_7, shift:1, chars:""},
             0, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:222, shift:1, chars:"\u00A8\u00A8"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_7, shift:1, chars:"\u00A8\u00A8"},
             0, "\u00A8\u00A8", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:222, shift:1, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_7, shift:1, chars:""},
             0, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:65, shift:1, chars:"\u00C4"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_A, shift:1, chars:"\u00C4"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00C4", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:222, shift:1, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_7, shift:1, chars:""},
             0, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:65, chars:"\u00E4"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_A, chars:"\u00E4"},
             nsIDOMKeyEvent.DOM_VK_A, "\u00E4", SHOULD_DELIVER_ALL);
 
-    testKey({layout:"Spanish", keyCode:222, shift:1, chars:""},
+    testKey({layout:"Spanish", keyCode:WIN_VK_OEM_7, shift:1, chars:""},
             0, "", SHOULD_DELIVER_KEYDOWN_KEYUP);
-    testKey({layout:"Spanish", keyCode:81, shift:1, chars:"\u00A8Q"},
+    testKey({layout:"Spanish", keyCode:WIN_VK_Q, shift:1, chars:"\u00A8Q"},
             nsIDOMKeyEvent.DOM_VK_Q, "\u00A8Q", SHOULD_DELIVER_ALL);
   }
 
   document.removeEventListener("keydown",  onKeyEvent, false);
   document.removeEventListener("keypress", onKeyEvent, false);
   document.removeEventListener("keyup",    onKeyEvent, false);
 }
 
@@ -2072,87 +2076,87 @@ function runAccessKeyTests()
     is(activationCount, aShouldActivate ? 1 : 0, name + ", activating '" + aAccessKey + "'");
   }
 
   button.addEventListener("click", onClick, false);
   
   // These tests have to be per-plaform.
   if (IS_MAC) {
     // Basic sanity checks
-    testKey({layout:"US", keyCode:0, chars:"a", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, chars:"a", unmodifiedChars:"a"},
             "a", false);
-    testKey({layout:"US", keyCode:0, ctrl:1, chars:"\u0001", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, ctrl:1, chars:"\u0001", unmodifiedChars:"a"},
             "a", false);
-    testKey({layout:"US", keyCode:0, ctrl:1, chars:"\u0001", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, ctrl:1, chars:"\u0001", unmodifiedChars:"a"},
             "A", false);
 
     // Shift-ctrl does not activate accesskeys
-    testKey({layout:"US", keyCode:0, ctrl:1, shift:1, chars:"\u0001", unmodifiedChars:"A"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, ctrl:1, shift:1, chars:"\u0001", unmodifiedChars:"A"},
             "a", false);
-    testKey({layout:"US", keyCode:0, ctrl:1, shift:1, chars:"\u0001", unmodifiedChars:"A"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, ctrl:1, shift:1, chars:"\u0001", unmodifiedChars:"A"},
             "A", false);
     // Alt-ctrl activate accesskeys
-    testKey({layout:"US", keyCode:0, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"a"},
             "a", true);
-    testKey({layout:"US", keyCode:0, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"a"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_A, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"a"},
             "A", true);
             
     // Greek layout can activate a Latin accesskey
-    testKey({layout:"Greek", keyCode:0, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
             "a", true);
-    testKey({layout:"Greek", keyCode:0, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
             "A", true);
     // ... and a Greek accesskey!
-    testKey({layout:"Greek", keyCode:0, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
             "\u03b1", true);
-    testKey({layout:"Greek", keyCode:0, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
+    testKey({layout:"Greek", keyCode:MAC_VK_ANSI_A, ctrl:1, alt:1, chars:"\u0001", unmodifiedChars:"\u03b1"},
             "\u0391", true);
 
     // bug 359638
-    testKey({layout:"US", keyCode:47, ctrl:1, alt:1, chars:".", unmodifiedChars:"."},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Period, ctrl:1, alt:1, chars:".", unmodifiedChars:"."},
             ".", true);
 
     // German (KCHR/KeyTranslate case)
-    testKey({layout:"German", keyCode:0, ctrl:1, alt:1, chars:"a", unmodifiedChars:"a"},
+    testKey({layout:"German", keyCode:MAC_VK_ANSI_A, ctrl:1, alt:1, chars:"a", unmodifiedChars:"a"},
             "a", true);
-    testKey({layout:"German", keyCode:0, ctrl:1, alt:1, chars:"a", unmodifiedChars:"a"},
+    testKey({layout:"German", keyCode:MAC_VK_ANSI_A, ctrl:1, alt:1, chars:"a", unmodifiedChars:"a"},
             "A", true);
-    testKey({layout:"German", keyCode:33, ctrl:1, alt:1, chars:"\u00fc", unmodifiedChars:"\u00fc"},
+    testKey({layout:"German", keyCode:MAC_VK_ANSI_LeftBracket, ctrl:1, alt:1, chars:"\u00fc", unmodifiedChars:"\u00fc"},
             "\u00fc", true);
-    testKey({layout:"German", keyCode:33, ctrl:1, alt:1, chars:"\u00fc", unmodifiedChars:"\u00fc"},
+    testKey({layout:"German", keyCode:MAC_VK_ANSI_LeftBracket, ctrl:1, alt:1, chars:"\u00fc", unmodifiedChars:"\u00fc"},
             "\u00dc", true);
   }
   else if (IS_WIN) {
     // Basic sanity checks
-    testKey({layout:"US", keyCode:65, chars:"a"},
+    testKey({layout:"US", keyCode:WIN_VK_A, chars:"a"},
             "a", false);
-    testKey({layout:"US", keyCode:65, shift:1, alt:1, chars:"A"},
+    testKey({layout:"US", keyCode:WIN_VK_A, shift:1, alt:1, chars:"A"},
             "a", true);
-    testKey({layout:"US", keyCode:65, shift:1, alt:1, chars:"A"},
+    testKey({layout:"US", keyCode:WIN_VK_A, shift:1, alt:1, chars:"A"},
             "A", true);
 
     // shift-alt-ctrl does not activate accesskeys
-    testKey({layout:"US", keyCode:65, ctrl:1, shift:1, alt:1, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_A, ctrl:1, shift:1, alt:1, chars:""},
             "a", false);
-    testKey({layout:"US", keyCode:65, ctrl:1, shift:1, alt:1, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_A, ctrl:1, shift:1, alt:1, chars:""},
             "A", false);
 
     // Greek layout can activate a Latin accesskey
-    testKey({layout:"Greek", keyCode:65, shift:1, alt:1, chars:"A"},
+    testKey({layout:"Greek", keyCode:WIN_VK_A, shift:1, alt:1, chars:"A"},
             "a", true);
-    testKey({layout:"Greek", keyCode:65, shift:1, alt:1, chars:"A"},
+    testKey({layout:"Greek", keyCode:WIN_VK_A, shift:1, alt:1, chars:"A"},
             "A", true);
     // ... and a Greek accesskey!
-    testKey({layout:"Greek", keyCode:65, shift:1, alt:1, chars:"A"},
+    testKey({layout:"Greek", keyCode:WIN_VK_A, shift:1, alt:1, chars:"A"},
             "\u03b1", true);
-    testKey({layout:"Greek", keyCode:65, shift:1, alt:1, chars:"A"},
+    testKey({layout:"Greek", keyCode:WIN_VK_A, shift:1, alt:1, chars:"A"},
             "\u0391", true);
 
     // bug 359638
-    testKey({layout:"US", keyCode:190, shift:1, alt:1, chars:".", unmodifiedChars:"."},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_PERIOD, shift:1, alt:1, chars:".", unmodifiedChars:"."},
             ".", true);
   }
   
   button.removeEventListener("click", onClick, false);
 }
 
 function runXULKeyTests()
 {
@@ -2165,101 +2169,101 @@ function runXULKeyTests()
 
     var name = eventToString(aEvent);
 
     is(elem.activeCount, aShouldActivate ? 1 : 0,
        name + " activating " + aElem);
   }
 
   if (IS_MAC) {
-    testKey({layout:"US", keyCode:41, command:1, chars:";", unmodifiedChars:";"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Semicolon, command:1, chars:";", unmodifiedChars:";"},
             "unshiftedKey", true);
-    testKey({layout:"US", keyCode:41, command:1, chars:";", unmodifiedChars:";"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Semicolon, command:1, chars:";", unmodifiedChars:";"},
             "shiftedKey", false);
-    testKey({layout:"US", keyCode:41, command:1, shift:1, chars:";", unmodifiedChars:":"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Semicolon, command:1, shift:1, chars:";", unmodifiedChars:":"},
             "shiftedKey", true);
-    testKey({layout:"US", keyCode:41, command:1, shift:1, chars:";", unmodifiedChars:":"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_Semicolon, command:1, shift:1, chars:";", unmodifiedChars:":"},
             "unshiftedKey", false);
   }
   else if (IS_WIN) {
-    testKey({layout:"US", keyCode:186, ctrl:1, chars:";"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_1, ctrl:1, chars:";"},
             "unshiftedKey", true);
-    testKey({layout:"US", keyCode:186, ctrl:1, chars:";"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_1, ctrl:1, chars:";"},
             "shiftedKey", false);
-    testKey({layout:"US", keyCode:186, ctrl:1, shift:1, chars:";"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_1, ctrl:1, shift:1, chars:";"},
             "shiftedKey", true);
-    testKey({layout:"US", keyCode:186, ctrl:1, shift:1, chars:";"},
+    testKey({layout:"US", keyCode:WIN_VK_OEM_1, ctrl:1, shift:1, chars:";"},
             "unshiftedKey", false);
   }
 
   keyElems = ["commandOptionF"];
 
   // 429160
   if (IS_MAC) {
-    testKey({layout:"US", keyCode:3, command:1, alt:1, chars:"\u0192", unmodifiedChars:"f"},
+    testKey({layout:"US", keyCode:MAC_VK_ANSI_F, command:1, alt:1, chars:"\u0192", unmodifiedChars:"f"},
             "commandOptionF", true);
   }
   else if (IS_WIN) {
-    testKey({layout:"US", keyCode:70, ctrl:1, alt:1, chars:"\u0006"},
+    testKey({layout:"US", keyCode:WIN_VK_F, ctrl:1, alt:1, chars:"\u0006"},
             "commandOptionF", true);
   }
   
   // 432112
   if (IS_MAC) {
-    testKey({layout:"Swedish", keyCode:27, command:1, shift:1, chars:"+", unmodifiedChars:"?"},
+    testKey({layout:"Swedish", keyCode:MAC_VK_ANSI_Minus, command:1, shift:1, chars:"+", unmodifiedChars:"?"},
             "question", true);
   }
   else if (IS_WIN) {
-    testKey({layout:"Swedish", keyCode:187, ctrl:1, shift:1, chars:""},
+    testKey({layout:"Swedish", keyCode:WIN_VK_OEM_PLUS, ctrl:1, shift:1, chars:""},
             "question", true);
-    testKey({layout:"Swedish", keyCode:187, ctrl:1, chars:""},
+    testKey({layout:"Swedish", keyCode:WIN_VK_OEM_PLUS, ctrl:1, chars:""},
             "question", false);
   }
 
   // bug 433192
   if (IS_WIN) {
-    testKey({layout:"US", keyCode:88, ctrl:1, chars:"\u0018"},
+    testKey({layout:"US", keyCode:WIN_VK_X, ctrl:1, chars:"\u0018"},
             "unshiftedX", true);
-    testKey({layout:"US", keyCode:88, ctrl:1, chars:"\u0018"},
+    testKey({layout:"US", keyCode:WIN_VK_X, ctrl:1, chars:"\u0018"},
             "shiftedX", false);
-    testKey({layout:"US", keyCode:88, ctrl:1, shift:1, chars:"\u0018"},
+    testKey({layout:"US", keyCode:WIN_VK_X, ctrl:1, shift:1, chars:"\u0018"},
             "unshiftedX", false);
-    testKey({layout:"US", keyCode:88, ctrl:1, shift:1, chars:"\u0018"},
+    testKey({layout:"US", keyCode:WIN_VK_X, ctrl:1, shift:1, chars:"\u0018"},
             "shiftedX", true);
-    testKey({layout:"Arabic", keyCode:88, ctrl:1, chars:"\u0018"},
+    testKey({layout:"Arabic", keyCode:WIN_VK_X, ctrl:1, chars:"\u0018"},
             "unshiftedX", true);
-    testKey({layout:"Arabic", keyCode:88, ctrl:1, chars:"\u0018"},
+    testKey({layout:"Arabic", keyCode:WIN_VK_X, ctrl:1, chars:"\u0018"},
             "shiftedX", false);
-    testKey({layout:"Arabic", keyCode:88, ctrl:1, shift:1, chars:"\u0018"},
+    testKey({layout:"Arabic", keyCode:WIN_VK_X, ctrl:1, shift:1, chars:"\u0018"},
             "unshiftedX", false);
-    testKey({layout:"Arabic", keyCode:88, ctrl:1, shift:1, chars:"\u0018"},
+    testKey({layout:"Arabic", keyCode:WIN_VK_X, ctrl:1, shift:1, chars:"\u0018"},
             "shiftedX", true);
-    testKey({layout:"Hebrew", keyCode:88, ctrl:1, chars:"\u0018"},
+    testKey({layout:"Hebrew", keyCode:WIN_VK_X, ctrl:1, chars:"\u0018"},
             "unshiftedX", true);
-    testKey({layout:"Hebrew", keyCode:88, ctrl:1, chars:"\u0018"},
+    testKey({layout:"Hebrew", keyCode:WIN_VK_X, ctrl:1, chars:"\u0018"},
             "shiftedX", false);
-    testKey({layout:"Hebrew", keyCode:88, ctrl:1, shift:1, chars:"\u0018"},
+    testKey({layout:"Hebrew", keyCode:WIN_VK_X, ctrl:1, shift:1, chars:"\u0018"},
             "unshiftedX", false);
-    testKey({layout:"Hebrew", keyCode:88, ctrl:1, shift:1, chars:"\u0018"},
+    testKey({layout:"Hebrew", keyCode:WIN_VK_X, ctrl:1, shift:1, chars:"\u0018"},
             "shiftedX", true);
-    testKey({layout:"Japanese", keyCode:187, ctrl:1, chars:""},
+    testKey({layout:"Japanese", keyCode:WIN_VK_OEM_PLUS, ctrl:1, chars:""},
             "unshiftedPlus", false);
-    testKey({layout:"Japanese", keyCode:187, ctrl:1, shift:1, chars:""},
+    testKey({layout:"Japanese", keyCode:WIN_VK_OEM_PLUS, ctrl:1, shift:1, chars:""},
             "unshiftedPlus", true);
   }
 
   // bug 759346
   if (IS_WIN) {
-    testKey({layout:"Thai", keyCode:49, ctrl:1, chars:""},
+    testKey({layout:"Thai", keyCode:WIN_VK_1, ctrl:1, chars:""},
             "unshiftedPlus", false);
-    testKey({layout:"Thai", keyCode:49, ctrl:1, shift:1, chars:""},
+    testKey({layout:"Thai", keyCode:WIN_VK_1, ctrl:1, shift:1, chars:""},
             "unshiftedPlus", true);
-    testKey({layout:"Thai", keyCode:187, ctrl:1, chars:""},
+    testKey({layout:"Thai", keyCode:WIN_VK_OEM_PLUS, ctrl:1, chars:""},
             "unshiftedPlus", true);
-    testKey({layout:"Thai", keyCode:187, ctrl:1, shift:1, chars:""},
+    testKey({layout:"Thai", keyCode:WIN_VK_OEM_PLUS, ctrl:1, shift:1, chars:""},
             "unshiftedPlus", false);
   }
 }
 
 function runTextInputTests()
 {
   var textbox = document.getElementById("textbox");
 
@@ -2271,36 +2275,36 @@ function runTextInputTests()
 
     var name = eventToString(aEvent);
 
     is(textbox.value, aExpectText, name + " does not input correct text.");
   }
 
   if (IS_WIN) {
     // Basic sanity checks
-    testKey({layout:"US", keyCode:65, chars:"a"},
+    testKey({layout:"US", keyCode:WIN_VK_A, chars:"a"},
             "a");
-    testKey({layout:"US", keyCode:65, shift:1, chars:"A"},
+    testKey({layout:"US", keyCode:WIN_VK_A, shift:1, chars:"A"},
             "A");
     // When Ctrl+Alt are pressed, any text should not be inputted.
-    testKey({layout:"US", keyCode:65, ctrl:1, alt:1, chars:""},
+    testKey({layout:"US", keyCode:WIN_VK_A, ctrl:1, alt:1, chars:""},
             "");
 
     // Lithuanian AltGr should be consumed at 9/0 keys pressed
-    testKey({layout:"Lithuanian", keyCode:56, chars:"\u016B"},
+    testKey({layout:"Lithuanian", keyCode:WIN_VK_8, chars:"\u016B"},
             "\u016B");
-    testKey({layout:"Lithuanian", keyCode:57, chars:"9"},
+    testKey({layout:"Lithuanian", keyCode:WIN_VK_9, chars:"9"},
             "9");
-    testKey({layout:"Lithuanian", keyCode:48, chars:"0"},
+    testKey({layout:"Lithuanian", keyCode:WIN_VK_0, chars:"0"},
             "0");
-    testKey({layout:"Lithuanian", keyCode:56, ctrl:1, alt:1, chars:"8"},
+    testKey({layout:"Lithuanian", keyCode:WIN_VK_8, ctrl:1, alt:1, chars:"8"},
             "8");
-    testKey({layout:"Lithuanian", keyCode:57, ctrl:1, alt:1, chars:"9"},
+    testKey({layout:"Lithuanian", keyCode:WIN_VK_9, ctrl:1, alt:1, chars:"9"},
             "9");
-    testKey({layout:"Lithuanian", keyCode:48, ctrl:1, alt:1, chars:"0"},
+    testKey({layout:"Lithuanian", keyCode:WIN_VK_0, ctrl:1, alt:1, chars:"0"},
             "0");
   }
   else
     todo(false, "runTextInputTests() checks Windows only");
 
   // XXX We need to move focus for canceling to search the autocomplete
   // result. If we don't do here, Fx will crash at end of this tests.
   document.getElementById("button").focus();
--- a/widget/tests/test_plugin_input_event.html
+++ b/widget/tests/test_plugin_input_event.html
@@ -1,16 +1,18 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Test for plugin input event</title>
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+  <script type="text/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/NativeKeyCodes.js"></script>
   <link rel="stylesheet" type="text/css"
           href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 </head>
 <body>
 <p id="display">
   <embed id="plugin" type="application/x-test" wmode="opaque">
 </p>
 <div id="content" style="display: none">
@@ -32,27 +34,27 @@ function doTest() {
   gPlugin.focus();
 
   is(gUtils.IMEStatus, gUtils.IME_STATUS_PLUGIN,
      "Plugin failed to get focus");
 
   is(gPlugin.getLastKeyText(), "", "Must be empty before first key test");
 
   gUtils.sendNativeKeyEvent(0x409 /* US */,
-                            0x41, 0,
+                            WIN_VK_A, 0,
                             "a", "a");
   is(gPlugin.getLastKeyText(), "a", "Invalid character was inputted");
 
   gUtils.sendNativeKeyEvent(0x407 /* German */,
-                            0xBB, 0,
+                            WIN_VK_OEM_PLUS, 0,
                             "+", "+");
   is(gPlugin.getLastKeyText(), "+", "Invalid character was inputted");
 
   gUtils.sendNativeKeyEvent(0x407 /* German */,
-                            0xBB, 0x1400 /* Ctrl + Alt (AltGr) */,
+                            WIN_VK_OEM_PLUS, 0x1400 /* Ctrl + Alt (AltGr) */,
                             "~", "+");
   is(gPlugin.getLastKeyText(), "~", "Invalid character was inputted");
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForFocus(doTest);
 
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -2600,17 +2600,17 @@ nsCycleCollector::GCIfNeeded(bool aForce
             mResults->mForcedGC = true;
     }
 
     TimeLog timeLog;
 
     // mJSRuntime->Collect() must be called from the main thread,
     // because it invokes XPCJSRuntime::GCCallback(cx, JSGC_BEGIN)
     // which returns false if not in the main thread.
-    mJSRuntime->Collect(js::gcreason::CC_FORCED, nsGCNormal);
+    mJSRuntime->Collect(aForceGC ? js::gcreason::SHUTDOWN_CC : js::gcreason::CC_FORCED, nsGCNormal);
     timeLog.Checkpoint("GC()");
 }
 
 bool
 nsCycleCollector::PrepareForCollection(nsCycleCollectorResults *aResults,
                                        nsTArray<PtrInfo*> *aWhiteNodes)
 {
     // This can legitimately happen in a few cases. See bug 383651.
--- a/xpcom/stub/dependentlibs.py
+++ b/xpcom/stub/dependentlibs.py
@@ -4,16 +4,17 @@
 
 '''Given a library, dependentlibs.py prints the list of libraries it depends
 upon that are in the same directory.
 '''
 
 from optparse import OptionParser
 import os
 import re
+import fnmatch
 import subprocess
 import sys
 
 TOOLCHAIN_PREFIX = ''
 
 def dependentlibs_dumpbin(lib):
     '''Returns the list of dependencies declared in the given DLL'''
     proc = subprocess.Popen(['dumpbin', '-imports', lib], stdout = subprocess.PIPE)
@@ -90,17 +91,17 @@ def main():
     (options, args) = parser.parse_args()
     if options.toolchain_prefix:
         global TOOLCHAIN_PREFIX
         TOOLCHAIN_PREFIX = options.toolchain_prefix
     lib = args[0]
     ext = os.path.splitext(lib)[1]
     if ext == '.dll':
         func = dependentlibs_dumpbin
-    elif ext == '.so':
+    elif ext == '.so' or fnmatch.fnmatch(lib, '*.so.*'):
         func = dependentlibs_readelf
     elif ext == '.dylib':
         func = dependentlibs_otool
     if not options.libpaths:
         options.libpaths = [os.path.dirname(lib)]
 
     print '\n'.join(dependentlibs(lib, options.libpaths, func))
 
--- a/xulrunner/tools/redit/redit.cpp
+++ b/xulrunner/tools/redit/redit.cpp
@@ -88,17 +88,17 @@ namespace {
     static type empty() { return NULL; }
     static void release(type handle) {
       if(NULL != handle) {
         EndUpdateResourceW(handle, TRUE); // Discard changes
       }
     }
   };
 
-  typedef Scoped<ScopedResourceUpdateTraits> ScopedResourceUpdate;
+  typedef mozilla::Scoped<ScopedResourceUpdateTraits> ScopedResourceUpdate;
 };
 
 #ifdef __MINGW32__
 extern "C"
 #endif
 int
 wmain(int argc, wchar_t** argv)
 {