diff --git a/.eslintignore b/.eslintignore index db3ebf0f518d..727765d6c4c8 100644 --- a/.eslintignore +++ b/.eslintignore @@ -70,6 +70,8 @@ browser/components/sessionstore/** browser/components/tabview/** browser/components/translation/** browser/extensions/pdfjs/** +# generated or library files in pocket +browser/extensions/pocket/content/panels/js/tmpl.js browser/extensions/pocket/content/panels/js/vendor/** browser/locales/** diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 9cb26206071f..0ed0a67a603c 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -8,7 +8,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index e7319942e2d0..0419408a3e85 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -8,7 +8,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 0a7d747cc1ca..bf31eb16450b 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -377,12 +377,6 @@ pref("browser.search.context.loadInBackground", false); // comma seperated list of of engines to hide in the search panel. pref("browser.search.hiddenOneOffs", ""); -#ifdef XP_WIN -pref("browser.search.redirectWindowsSearch", true); -#else -pref("browser.search.redirectWindowsSearch", false); -#endif - pref("browser.search.reset.enabled", true); pref("browser.usedOnWindows10", false); diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 5feea7b35b32..6fdca43b31ed 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -2417,12 +2417,12 @@ // processes the event queue and may lead to another removeTab() // call before permitUnload() returns. aTab._pendingPermitUnload = true; - let {permitUnload} = browser.permitUnload(); + let {permitUnload, timedOut} = browser.permitUnload(); delete aTab._pendingPermitUnload; // If we were closed during onbeforeunload, we return false now // so we don't (try to) close the same tab again. Of course, we // also stop if the unload was cancelled by the user: - if (aTab.closing || !permitUnload) { + if (aTab.closing || (!timedOut && !permitUnload)) { // NB: deliberately keep the _closedDuringPermitUnload set to // true so we keep exiting early in case of multiple calls. return false; diff --git a/browser/base/content/test/general/browser_misused_characters_in_strings.js b/browser/base/content/test/general/browser_misused_characters_in_strings.js index 9b3c598ffaf9..d4ca1c85694e 100644 --- a/browser/base/content/test/general/browser_misused_characters_in_strings.js +++ b/browser/base/content/test/general/browser_misused_characters_in_strings.js @@ -100,6 +100,14 @@ let gWhitelist = [{ file: "netErrorApp.dtd", key: "securityOverride.warningContent", type: "single-quote" + }, { + file: "pocket.properties", + key: "tos", + type: "double-quote" + }, { + file: "pocket.properties", + key: "tos", + type: "apostrophe" } ]; diff --git a/browser/base/content/test/urlbar/browser_autocomplete_autoselect.js b/browser/base/content/test/urlbar/browser_autocomplete_autoselect.js index 9852e8395cea..e96f54351369 100644 --- a/browser/base/content/test/urlbar/browser_autocomplete_autoselect.js +++ b/browser/base/content/test/urlbar/browser_autocomplete_autoselect.js @@ -1,3 +1,5 @@ +const ONEOFF_URLBAR_PREF = "browser.urlbar.oneOffSearches"; + function repeat(limit, func) { for (let i = 0; i < limit; i++) { func(i); @@ -26,8 +28,10 @@ function is_selected_one_off(index) { add_task(function*() { let maxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults"); + Services.prefs.setBoolPref(ONEOFF_URLBAR_PREF, true); registerCleanupFunction(function* () { yield PlacesTestUtils.clearHistory(); + Services.prefs.clearUserPref(ONEOFF_URLBAR_PREF); }); let visits = []; diff --git a/browser/components/nsBrowserContentHandler.js b/browser/components/nsBrowserContentHandler.js index a456f9c407a3..3ed2ac99ed79 100644 --- a/browser/components/nsBrowserContentHandler.js +++ b/browser/components/nsBrowserContentHandler.js @@ -2,8 +2,6 @@ * 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/. */ -Components.utils.importGlobalProperties(["URLSearchParams"]); - Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/Services.jsm"); Components.utils.import("resource://gre/modules/AppConstants.jsm"); @@ -744,60 +742,10 @@ nsDefaultCommandLineHandler.prototype = { } } - let redirectWinSearch = false; - if (AppConstants.isPlatformAndVersionAtLeast("win", "10")) { - redirectWinSearch = Services.prefs.getBoolPref("browser.search.redirectWindowsSearch"); - } - try { var ar; while ((ar = cmdLine.handleFlagWithParam("url", false))) { var uri = resolveURIInternal(cmdLine, ar); - - // Searches in the Windows 10 task bar searchbox simply open the default browser - // with a URL for a search on Bing. Here we extract the search term and use the - // user's default search engine instead. - var uriScheme = "", uriHost = "", uriPath = ""; - try { - uriScheme = uri.scheme; - uriHost = uri.host; - uriPath = uri.path; - } catch (e) { - } - - // Most Windows searches are "https://www.bing.com/search...", but bug - // 1182308 reports a Chinese edition of Windows 10 using - // "http://cn.bing.com/search...", so be a bit flexible in what we match. - if (redirectWinSearch && - (uriScheme == "http" || uriScheme == "https") && - uriHost.endsWith(".bing.com") && uriPath.startsWith("/search")) { - try { - var url = uri.QueryInterface(Components.interfaces.nsIURL); - var params = new URLSearchParams(url.query); - // We don't want to rewrite all Bing URLs coming from external apps. Look - // for the magic URL parm that's present in searches from the task bar. - // * Typed searches use "form=WNSGPH" - // * Cortana voice searches use "FORM=WNSBOX" or direct results, or "FORM=WNSFC2" - // for "see more results on Bing.com") - // * Cortana voice searches started from "Hey, Cortana" use "form=WNSHCO" - // or "form=WNSSSV" or "form=WNSSCX" - var allowedParams = ["WNSGPH", "WNSBOX", "WNSFC2", "WNSHCO", "WNSSCX", "WNSSSV"]; - var formParam = params.get("form"); - if (!formParam) { - formParam = params.get("FORM"); - } - if (allowedParams.indexOf(formParam) != -1) { - var term = params.get("q"); - var engine = Services.search.defaultEngine; - logSystemBasedSearch(engine); - var submission = engine.getSubmission(term, null, "system"); - uri = submission.uri; - } - } catch (e) { - Components.utils.reportError("Couldn't redirect Windows search: " + e); - } - } - urilist.push(uri); } } diff --git a/browser/components/preferences/in-content/search.js b/browser/components/preferences/in-content/search.js index be34eb8595e6..eb840081fd65 100644 --- a/browser/components/preferences/in-content/search.js +++ b/browser/components/preferences/in-content/search.js @@ -3,8 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "AppConstants", - "resource://gre/modules/AppConstants.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Task", @@ -12,12 +10,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task", const ENGINE_FLAVOR = "text/x-moz-search-engine"; -document.addEventListener("Initialized", () => { - if (!AppConstants.isPlatformAndVersionAtLeast("win", "10")) { - document.getElementById("redirectSearchCheckbox").hidden = true; - } -}); - var gEngineView = null; var gSearchPane = { diff --git a/browser/components/preferences/in-content/search.xul b/browser/components/preferences/in-content/search.xul index c01717de8d39..95c7acd85deb 100644 --- a/browser/components/preferences/in-content/search.xul +++ b/browser/components/preferences/in-content/search.xul @@ -12,10 +12,6 @@ name="browser.search.hiddenOneOffs" type="unichar"/> - - + + + +
+
+
+
+ + diff --git a/devtools/client/shared/components/test/mochitest/test_tree_04.html b/devtools/client/shared/components/test/mochitest/test_tree_04.html index be35cb2e5a19..8e4c125c9b37 100644 --- a/devtools/client/shared/components/test/mochitest/test_tree_04.html +++ b/devtools/client/shared/components/test/mochitest/test_tree_04.html @@ -15,15 +15,28 @@ Test that we only render visible tree items. + + diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js index 98d55ef56ba6..c6f698f10540 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js @@ -7,7 +7,7 @@ * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. */ -const { ConsoleMessage } = require("devtools/client/webconsole/new-console-output/types"); +const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webconsole/new-console-output/types"); let stubPreparedMessages = new Map(); let stubPackets = new Map(); @@ -25,10 +25,10 @@ stubPreparedMessages.set("console.log('foobar', 'test')", new ConsoleMessage({ "test" ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foobar\",\"test\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foobar\",\"test\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27foobar%27%2C%20%27test%27)\",\"line\":1,\"column\":27}}", "stacktrace": null, "frame": { - "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27foobar%27%2C%20%27test%27)", "line": 1, "column": 27 } @@ -47,10 +47,10 @@ stubPreparedMessages.set("console.log(undefined)", new ConsoleMessage({ } ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"undefined\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"undefined\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)\",\"line\":1,\"column\":27}}", "stacktrace": null, "frame": { - "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)", "line": 1, "column": 27 } @@ -67,10 +67,10 @@ stubPreparedMessages.set("console.warn('danger, will robinson!')", new ConsoleMe "danger, will robinson!" ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"warn\",\"level\":\"warn\",\"messageText\":null,\"parameters\":[\"danger, will robinson!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"warn\",\"level\":\"warn\",\"messageText\":null,\"parameters\":[\"danger, will robinson!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)\",\"line\":1,\"column\":27}}", "stacktrace": null, "frame": { - "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)", "line": 1, "column": 27 } @@ -89,10 +89,10 @@ stubPreparedMessages.set("console.log(NaN)", new ConsoleMessage({ } ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"NaN\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"NaN\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)\",\"line\":1,\"column\":27}}", "stacktrace": null, "frame": { - "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)", "line": 1, "column": 27 } @@ -111,10 +111,30 @@ stubPreparedMessages.set("console.log(null)", new ConsoleMessage({ } ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"null\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"null\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)\",\"line\":1,\"column\":27}}", "stacktrace": null, "frame": { - "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)", + "line": 1, + "column": 27 + } +})); + +stubPreparedMessages.set("console.log('鼬')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + "鼬" + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"鼬\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)\",\"line\":1,\"column\":27}}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)", "line": 1, "column": 27 } @@ -131,10 +151,10 @@ stubPreparedMessages.set("console.clear()", new ConsoleMessage({ "Console was cleared." ], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"clear\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"clear\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()\",\"line\":1,\"column\":27}}", "stacktrace": null, "frame": { - "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()", "line": 1, "column": 27 } @@ -149,10 +169,99 @@ stubPreparedMessages.set("console.count('bar')", new ConsoleMessage({ "messageText": "bar: 1", "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"debug\",\"messageText\":\"bar: 1\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":1,\"column\":27}}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"debug\",\"messageText\":\"bar: 1\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)\",\"line\":1,\"column\":27}}", "stacktrace": null, "frame": { - "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)", + "line": 1, + "column": 27 + } +})); + +stubPreparedMessages.set("console.assert(false, {message: 'foobar'})", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "assert", + "level": "error", + "messageText": null, + "parameters": [ + { + "type": "object", + "actor": "server1.conn8.child1/obj31", + "class": "Object", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 1, + "preview": { + "kind": "Object", + "ownProperties": { + "message": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "foobar" + } + }, + "ownPropertiesLength": 1, + "safeGetterValues": {} + } + } + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"assert\",\"level\":\"error\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn8.child1/obj31\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"message\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"foobar\"}},\"ownPropertiesLength\":1,\"safeGetterValues\":{}}}],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":27,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":1}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"line\":1,\"column\":27}}", + "stacktrace": [ + { + "columnNumber": 27, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)", + "functionName": "triggerPacket", + "language": 2, + "lineNumber": 1 + } + ], + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)", + "line": 1, + "column": 27 + } +})); + +stubPreparedMessages.set("console.log('hello \nfrom \rthe \"string world!')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + "hello \nfrom \rthe \"string world!" + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"hello \\nfrom \\rthe \\\"string world!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)\",\"line\":1,\"column\":27}}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)", + "line": 1, + "column": 27 + } +})); + +stubPreparedMessages.set("console.log('úṇĩçödê țĕșť')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + "úṇĩçödê țĕșť" + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"úṇĩçödê țĕșť\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)\",\"line\":1,\"column\":27}}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)", "line": 1, "column": 27 } @@ -167,32 +276,32 @@ stubPreparedMessages.set("console.trace()", new ConsoleMessage({ "messageText": null, "parameters": [], "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"trace\",\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"functionName\":\"bar\",\"language\":2,\"lineNumber\":3},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"functionName\":\"foo\",\"language\":2,\"lineNumber\":6},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":9}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":3,\"column\":3}}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"trace\",\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"testStacktraceFiltering\",\"language\":2,\"lineNumber\":3},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"foo\",\"language\":2,\"lineNumber\":6},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":9}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"line\":3,\"column\":3}}", "stacktrace": [ { "columnNumber": 3, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", - "functionName": "bar", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "functionName": "testStacktraceFiltering", "language": 2, "lineNumber": 3 }, { "columnNumber": 3, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", "functionName": "foo", "language": 2, "lineNumber": 6 }, { "columnNumber": 1, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", "functionName": "triggerPacket", "language": 2, "lineNumber": 9 } ], "frame": { - "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", "line": 3, "column": 3 } @@ -207,10 +316,10 @@ stubPreparedMessages.set("console.time('bar')", new ConsoleMessage({ "messageText": null, "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"nullMessage\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":2,\"column\":1}}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"nullMessage\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":2,\"column\":1}}", "stacktrace": null, "frame": { - "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", "line": 2, "column": 1 } @@ -222,13 +331,13 @@ stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({ "source": "console-api", "type": "timeEnd", "level": "log", - "messageText": "bar: 2.01ms", + "messageText": "bar: 1.63ms", "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"timeEnd\",\"level\":\"log\",\"messageText\":\"bar: 2.01ms\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":3,\"column\":1}}", + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"timeEnd\",\"level\":\"log\",\"messageText\":\"bar: 1.63ms\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)\",\"line\":3,\"column\":1}}", "stacktrace": null, "frame": { - "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", "line": 3, "column": 1 } @@ -245,7 +354,7 @@ stubPackets.set("console.log('foobar', 'test')", { ], "columnNumber": 27, "counter": null, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27foobar%27%2C%20%27test%27)", "functionName": "triggerPacket", "groupName": "", "level": "log", @@ -253,6 +362,7 @@ stubPackets.set("console.log('foobar', 'test')", { "originAttributes": { "addonId": "", "appId": 0, + "firstPartyDomain": "", "inIsolatedMozBrowser": false, "privateBrowsingId": 0, "signedPkg": "", @@ -260,7 +370,7 @@ stubPackets.set("console.log('foobar', 'test')", { }, "private": false, "styles": [], - "timeStamp": 1471885545204, + "timeStamp": 1474329261562, "timer": null, "workerType": "none", "category": "webdev" @@ -278,7 +388,7 @@ stubPackets.set("console.log(undefined)", { ], "columnNumber": 27, "counter": null, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)", "functionName": "triggerPacket", "groupName": "", "level": "log", @@ -286,6 +396,7 @@ stubPackets.set("console.log(undefined)", { "originAttributes": { "addonId": "", "appId": 0, + "firstPartyDomain": "", "inIsolatedMozBrowser": false, "privateBrowsingId": 0, "signedPkg": "", @@ -293,7 +404,7 @@ stubPackets.set("console.log(undefined)", { }, "private": false, "styles": [], - "timeStamp": 1471885546075, + "timeStamp": 1474329262588, "timer": null, "workerType": "none", "category": "webdev" @@ -309,7 +420,7 @@ stubPackets.set("console.warn('danger, will robinson!')", { ], "columnNumber": 27, "counter": null, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)", "functionName": "triggerPacket", "groupName": "", "level": "warn", @@ -317,6 +428,7 @@ stubPackets.set("console.warn('danger, will robinson!')", { "originAttributes": { "addonId": "", "appId": 0, + "firstPartyDomain": "", "inIsolatedMozBrowser": false, "privateBrowsingId": 0, "signedPkg": "", @@ -324,7 +436,7 @@ stubPackets.set("console.warn('danger, will robinson!')", { }, "private": false, "styles": [], - "timeStamp": 1471885546795, + "timeStamp": 1474329263650, "timer": null, "workerType": "none", "category": "webdev" @@ -342,7 +454,7 @@ stubPackets.set("console.log(NaN)", { ], "columnNumber": 27, "counter": null, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)", "functionName": "triggerPacket", "groupName": "", "level": "log", @@ -350,6 +462,7 @@ stubPackets.set("console.log(NaN)", { "originAttributes": { "addonId": "", "appId": 0, + "firstPartyDomain": "", "inIsolatedMozBrowser": false, "privateBrowsingId": 0, "signedPkg": "", @@ -357,7 +470,7 @@ stubPackets.set("console.log(NaN)", { }, "private": false, "styles": [], - "timeStamp": 1471885547605, + "timeStamp": 1474329264822, "timer": null, "workerType": "none", "category": "webdev" @@ -375,7 +488,7 @@ stubPackets.set("console.log(null)", { ], "columnNumber": 27, "counter": null, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)", "functionName": "triggerPacket", "groupName": "", "level": "log", @@ -383,6 +496,7 @@ stubPackets.set("console.log(null)", { "originAttributes": { "addonId": "", "appId": 0, + "firstPartyDomain": "", "inIsolatedMozBrowser": false, "privateBrowsingId": 0, "signedPkg": "", @@ -390,7 +504,39 @@ stubPackets.set("console.log(null)", { }, "private": false, "styles": [], - "timeStamp": 1471885548414, + "timeStamp": 1474329265855, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.log('鼬')", { + "from": "server1.conn5.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "鼬" + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "signedPkg": "", + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1474329266922, "timer": null, "workerType": "none", "category": "webdev" @@ -398,13 +544,13 @@ stubPackets.set("console.log(null)", { }); stubPackets.set("console.clear()", { - "from": "server1.conn5.child1/consoleActor2", + "from": "server1.conn6.child1/consoleActor2", "type": "consoleAPICall", "message": { "arguments": [], "columnNumber": 27, "counter": null, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()", "functionName": "triggerPacket", "groupName": "", "level": "clear", @@ -412,13 +558,14 @@ stubPackets.set("console.clear()", { "originAttributes": { "addonId": "", "appId": 0, + "firstPartyDomain": "", "inIsolatedMozBrowser": false, "privateBrowsingId": 0, "signedPkg": "", "userContextId": 0 }, "private": false, - "timeStamp": 1471885549077, + "timeStamp": 1474329267971, "timer": null, "workerType": "none", "styles": [], @@ -427,7 +574,7 @@ stubPackets.set("console.clear()", { }); stubPackets.set("console.count('bar')", { - "from": "server1.conn6.child1/consoleActor2", + "from": "server1.conn7.child1/consoleActor2", "type": "consoleAPICall", "message": { "arguments": [ @@ -438,7 +585,7 @@ stubPackets.set("console.count('bar')", { "count": 1, "label": "bar" }, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)", "functionName": "triggerPacket", "groupName": "", "level": "count", @@ -446,13 +593,14 @@ stubPackets.set("console.count('bar')", { "originAttributes": { "addonId": "", "appId": 0, + "firstPartyDomain": "", "inIsolatedMozBrowser": false, "privateBrowsingId": 0, "signedPkg": "", "userContextId": 0 }, "private": false, - "timeStamp": 1471885549791, + "timeStamp": 1474329269084, "timer": null, "workerType": "none", "styles": [], @@ -460,47 +608,174 @@ stubPackets.set("console.count('bar')", { } }); -stubPackets.set("console.trace()", { - "from": "server1.conn7.child1/consoleActor2", +stubPackets.set("console.assert(false, {message: 'foobar'})", { + "from": "server1.conn8.child1/consoleActor2", "type": "consoleAPICall", "message": { - "arguments": [], - "columnNumber": 3, + "arguments": [ + { + "type": "object", + "actor": "server1.conn8.child1/obj31", + "class": "Object", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 1, + "preview": { + "kind": "Object", + "ownProperties": { + "message": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "foobar" + } + }, + "ownPropertiesLength": 1, + "safeGetterValues": {} + } + } + ], + "columnNumber": 27, "counter": null, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", - "functionName": "bar", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)", + "functionName": "triggerPacket", "groupName": "", - "level": "trace", - "lineNumber": 3, + "level": "assert", + "lineNumber": 1, "originAttributes": { "addonId": "", "appId": 0, + "firstPartyDomain": "", "inIsolatedMozBrowser": false, "privateBrowsingId": 0, "signedPkg": "", "userContextId": 0 }, "private": false, - "timeStamp": 1471885551114, + "styles": [], + "timeStamp": 1474329270125, + "timer": null, + "stacktrace": [ + { + "columnNumber": 27, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)", + "functionName": "triggerPacket", + "language": 2, + "lineNumber": 1 + } + ], + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.log('hello \nfrom \rthe \"string world!')", { + "from": "server1.conn9.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "hello \nfrom \rthe \"string world!" + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "signedPkg": "", + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1474329271256, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.log('úṇĩçödê țĕșť')", { + "from": "server1.conn10.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "úṇĩçödê țĕșť" + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "signedPkg": "", + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1474329272298, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.trace()", { + "from": "server1.conn11.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [], + "columnNumber": 3, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "functionName": "testStacktraceFiltering", + "groupName": "", + "level": "trace", + "lineNumber": 3, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "signedPkg": "", + "userContextId": 0 + }, + "private": false, + "timeStamp": 1474329273375, "timer": null, "stacktrace": [ { "columnNumber": 3, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", - "functionName": "bar", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "functionName": "testStacktraceFiltering", "language": 2, "lineNumber": 3 }, { "columnNumber": 3, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", "functionName": "foo", "language": 2, "lineNumber": 6 }, { "columnNumber": 1, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", "functionName": "triggerPacket", "language": 2, "lineNumber": 9 @@ -513,7 +788,7 @@ stubPackets.set("console.trace()", { }); stubPackets.set("console.time('bar')", { - "from": "server1.conn8.child1/consoleActor2", + "from": "server1.conn12.child1/consoleActor2", "type": "consoleAPICall", "message": { "arguments": [ @@ -521,7 +796,7 @@ stubPackets.set("console.time('bar')", { ], "columnNumber": 1, "counter": null, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", "functionName": "triggerPacket", "groupName": "", "level": "time", @@ -529,16 +804,17 @@ stubPackets.set("console.time('bar')", { "originAttributes": { "addonId": "", "appId": 0, + "firstPartyDomain": "", "inIsolatedMozBrowser": false, "privateBrowsingId": 0, "signedPkg": "", "userContextId": 0 }, "private": false, - "timeStamp": 1471885552201, + "timeStamp": 1474329274410, "timer": { "name": "bar", - "started": 970.09 + "started": 618.57 }, "workerType": "none", "styles": [], @@ -547,7 +823,7 @@ stubPackets.set("console.time('bar')", { }); stubPackets.set("console.timeEnd('bar')", { - "from": "server1.conn8.child1/consoleActor2", + "from": "server1.conn12.child1/consoleActor2", "type": "consoleAPICall", "message": { "arguments": [ @@ -555,7 +831,7 @@ stubPackets.set("console.timeEnd('bar')", { ], "columnNumber": 1, "counter": null, - "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", "functionName": "triggerPacket", "groupName": "", "level": "timeEnd", @@ -563,15 +839,16 @@ stubPackets.set("console.timeEnd('bar')", { "originAttributes": { "addonId": "", "appId": 0, + "firstPartyDomain": "", "inIsolatedMozBrowser": false, "privateBrowsingId": 0, "signedPkg": "", "userContextId": 0 }, "private": false, - "timeStamp": 1471885552203, + "timeStamp": 1474329274411, "timer": { - "duration": 2.0149999999999864, + "duration": 1.3249999999999318, "name": "bar" }, "workerType": "none", diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js index 461b0a454d5e..b839e0060097 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js @@ -7,7 +7,7 @@ * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. */ -const { ConsoleMessage } = require("devtools/client/webconsole/new-console-output/types"); +const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webconsole/new-console-output/types"); let stubPreparedMessages = new Map(); let stubPackets = new Map(); diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js index dfca970d5dec..59b42018042c 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js @@ -8,6 +8,7 @@ let maps = []; [ "consoleApi", "evaluationResult", + "networkEvent", "pageError", ].forEach((filename) => { maps[filename] = require(`./${filename}`); @@ -18,9 +19,11 @@ module.exports = { stubPreparedMessages: new Map([ ...maps.consoleApi.stubPreparedMessages, ...maps.evaluationResult.stubPreparedMessages, + ...maps.networkEvent.stubPreparedMessages, ...maps.pageError.stubPreparedMessages, ]), stubPackets: new Map([ ...maps.consoleApi.stubPackets, ...maps.evaluationResult.stubPackets, + ...maps.networkEvent.stubPackets, ...maps.pageError.stubPackets, ]), }; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/networkEvent.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/networkEvent.js new file mode 100644 index 000000000000..a3e763093b8e --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/networkEvent.js @@ -0,0 +1,186 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* + * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. + */ + +const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webconsole/new-console-output/types"); + +let stubPreparedMessages = new Map(); +let stubPackets = new Map(); + + +stubPreparedMessages.set("GET request", new NetworkEventMessage({ + "id": "1", + "actor": "server1.conn0.child1/netEvent29", + "level": "log", + "isXHR": false, + "request": { + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "GET" + }, + "response": {}, + "source": "network", + "type": "log" +})); + +stubPreparedMessages.set("XHR GET request", new NetworkEventMessage({ + "id": "1", + "actor": "server1.conn1.child1/netEvent29", + "level": "log", + "isXHR": true, + "request": { + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "GET" + }, + "response": {}, + "source": "network", + "type": "log" +})); + +stubPreparedMessages.set("XHR POST request", new NetworkEventMessage({ + "id": "1", + "actor": "server1.conn2.child1/netEvent29", + "level": "log", + "isXHR": true, + "request": { + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "POST" + }, + "response": {}, + "source": "network", + "type": "log" +})); + + +stubPackets.set("GET request", { + "from": "server1.conn0.child1/consoleActor2", + "type": "networkEvent", + "eventActor": { + "actor": "server1.conn0.child1/netEvent29", + "startedDateTime": "2016-09-14T02:38:18.046Z", + "timeStamp": 1473820698046, + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "GET", + "isXHR": false, + "cause": { + "type": 3, + "loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-network-event.html", + "stacktrace": [ + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "lineNumber": 3, + "columnNumber": 1, + "functionName": "triggerPacket", + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval", + "lineNumber": 4, + "columnNumber": 7, + "functionName": null, + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js", + "lineNumber": 53, + "columnNumber": 20, + "functionName": null, + "asyncCause": null + } + ] + }, + "private": false + } +}); + +stubPackets.set("XHR GET request", { + "from": "server1.conn1.child1/consoleActor2", + "type": "networkEvent", + "eventActor": { + "actor": "server1.conn1.child1/netEvent29", + "startedDateTime": "2016-09-14T02:38:18.812Z", + "timeStamp": 1473820698812, + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "GET", + "isXHR": true, + "cause": { + "type": 11, + "loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-network-event.html", + "stacktrace": [ + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "lineNumber": 4, + "columnNumber": 1, + "functionName": "triggerPacket", + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval", + "lineNumber": 4, + "columnNumber": 7, + "functionName": null, + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js", + "lineNumber": 53, + "columnNumber": 20, + "functionName": null, + "asyncCause": null + } + ] + }, + "private": false + } +}); + +stubPackets.set("XHR POST request", { + "from": "server1.conn2.child1/consoleActor2", + "type": "networkEvent", + "eventActor": { + "actor": "server1.conn2.child1/netEvent29", + "startedDateTime": "2016-09-14T02:38:19.483Z", + "timeStamp": 1473820699483, + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "POST", + "isXHR": true, + "cause": { + "type": 11, + "loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-network-event.html", + "stacktrace": [ + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "lineNumber": 4, + "columnNumber": 1, + "functionName": "triggerPacket", + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval", + "lineNumber": 4, + "columnNumber": 7, + "functionName": null, + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js", + "lineNumber": 53, + "columnNumber": 20, + "functionName": null, + "asyncCause": null + } + ] + }, + "private": false + } +}); + + +module.exports = { + stubPreparedMessages, + stubPackets, +} \ No newline at end of file diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js index 9c17a7ef9988..f8eb7e869a35 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js @@ -7,7 +7,7 @@ * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. */ -const { ConsoleMessage } = require("devtools/client/webconsole/new-console-output/types"); +const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webconsole/new-console-output/types"); let stubPreparedMessages = new Map(); let stubPackets = new Map(); @@ -22,9 +22,32 @@ stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessa "messageText": "ReferenceError: asdf is not defined", "parameters": null, "repeat": 1, - "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"log\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":null}", - "stacktrace": null, - "frame": null + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"log\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"line\":3,\"column\":5}}", + "stacktrace": [ + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 3, + "columnNumber": 5, + "functionName": "bar" + }, + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 6, + "columnNumber": 5, + "functionName": "foo" + }, + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 9, + "columnNumber": 3, + "functionName": null + } + ], + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "line": 3, + "column": 5 + } })); @@ -35,12 +58,12 @@ stubPackets.set("ReferenceError: asdf is not defined", { "errorMessage": "ReferenceError: asdf is not defined", "errorMessageName": "JSMSG_NOT_DEFINED", "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default", - "sourceName": "data:text/html;charset=utf-8,stub%20generation", + "sourceName": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", "lineText": "", - "lineNumber": 1, - "columnNumber": 1, + "lineNumber": 3, + "columnNumber": 5, "category": "content javascript", - "timeStamp": 1471886066466, + "timeStamp": 1473960366996, "warning": false, "error": false, "exception": true, @@ -49,21 +72,21 @@ stubPackets.set("ReferenceError: asdf is not defined", { "private": false, "stacktrace": [ { - "filename": "data:text/html;charset=utf-8,stub%20generation", - "lineNumber": 1, - "columnNumber": 1, - "functionName": null + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 3, + "columnNumber": 5, + "functionName": "bar" }, { - "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval", + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", "lineNumber": 6, - "columnNumber": 7, - "functionName": null + "columnNumber": 5, + "functionName": "foo" }, { - "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js", - "lineNumber": 53, - "columnNumber": 20, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 9, + "columnNumber": 3, "functionName": null } ] diff --git a/devtools/client/webconsole/new-console-output/test/store/filters.test.js b/devtools/client/webconsole/new-console-output/test/store/filters.test.js index 7ff5ed29b8d1..2a219f28e976 100644 --- a/devtools/client/webconsole/new-console-output/test/store/filters.test.js +++ b/devtools/client/webconsole/new-console-output/test/store/filters.test.js @@ -12,25 +12,19 @@ const { getAllMessages } = require("devtools/client/webconsole/new-console-outpu const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters"); const { setupStore } = require("devtools/client/webconsole/new-console-output/test/helpers"); const { MESSAGE_LEVEL } = require("devtools/client/webconsole/new-console-output/constants"); +const { stubPackets } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); describe("Filtering", () => { - const numMessages = 7; - const store = setupStore([ - // Console API - "console.log('foobar', 'test')", - "console.warn('danger, will robinson!')", - "console.log(undefined)", - "console.count('bar')", - // Evaluation Result - "new Date(0)", - // PageError - "ReferenceError: asdf is not defined" - ]); - // Console Command - store.dispatch(messageAdd(new ConsoleCommand({ messageText: `console.warn("x")` }))); + let store; + let numMessages; + // Number of messages in prepareBaseStore which are not filtered out, i.e. Evaluation + // Results and console commands . + const numUnfilterableMessages = 2; beforeEach(() => { + store = prepareBaseStore(); store.dispatch(actions.filtersClear()); + numMessages = getAllMessages(store.getState()).size; }); describe("Level filter", () => { @@ -38,7 +32,7 @@ describe("Filtering", () => { store.dispatch(actions.filterToggle(MESSAGE_LEVEL.LOG)); let messages = getAllMessages(store.getState()); - expect(messages.size).toEqual(numMessages - 2); + expect(messages.size).toEqual(numMessages - 3); }); it("filters debug messages", () => { @@ -71,9 +65,63 @@ describe("Filtering", () => { store.dispatch(actions.filterTextSet("danger")); let messages = getAllMessages(store.getState()); - // @TODO figure out what this should filter - // This does not filter out PageErrors, Evaluation Results or console commands - expect(messages.size).toEqual(5); + expect(messages.size - numUnfilterableMessages).toEqual(1); + }); + + it("matches unicode values", () => { + store.dispatch(actions.filterTextSet("鼬")); + + let messages = getAllMessages(store.getState()); + expect(messages.size - numUnfilterableMessages).toEqual(1); + }); + + it("matches locations", () => { + // Add a message with a different filename. + let locationMsg = + Object.assign({}, stubPackets.get("console.log('foobar', 'test')")); + locationMsg.message = + Object.assign({}, locationMsg.message, { filename: "search-location-test.js" }); + store.dispatch(messageAdd(locationMsg)); + + store.dispatch(actions.filterTextSet("search-location-test.js")); + + let messages = getAllMessages(store.getState()); + expect(messages.size - numUnfilterableMessages).toEqual(1); + }); + + it("matches stacktrace functionName", () => { + let traceMessage = stubPackets.get("console.trace()"); + store.dispatch(messageAdd(traceMessage)); + + store.dispatch(actions.filterTextSet("testStacktraceFiltering")); + + let messages = getAllMessages(store.getState()); + expect(messages.size - numUnfilterableMessages).toEqual(1); + }); + + it("matches stacktrace location", () => { + let traceMessage = stubPackets.get("console.trace()"); + traceMessage.message = + Object.assign({}, traceMessage.message, { + filename: "search-location-test.js", + lineNumber: 85, + columnNumber: 13 + }); + + store.dispatch(messageAdd(traceMessage)); + + store.dispatch(actions.filterTextSet("search-location-test.js:85:13")); + + let messages = getAllMessages(store.getState()); + expect(messages.size - numUnfilterableMessages).toEqual(1); + }); + + it("restores all messages once text is cleared", () => { + store.dispatch(actions.filterTextSet("danger")); + store.dispatch(actions.filterTextSet("")); + + let messages = getAllMessages(store.getState()); + expect(messages.size).toEqual(numMessages); }); }); @@ -113,3 +161,23 @@ describe("Clear filters", () => { }); }); }); + +function prepareBaseStore() { + const store = setupStore([ + // Console API + "console.log('foobar', 'test')", + "console.warn('danger, will robinson!')", + "console.log(undefined)", + "console.count('bar')", + "console.log('鼬')", + // Evaluation Result - never filtered + "new Date(0)", + // PageError + "ReferenceError: asdf is not defined" + ]); + + // Console Command - never filtered + store.dispatch(messageAdd(new ConsoleCommand({ messageText: `console.warn("x")` }))); + + return store; +} diff --git a/devtools/client/webconsole/new-console-output/test/store/messages.test.js b/devtools/client/webconsole/new-console-output/test/store/messages.test.js index caf83b630181..d2f353620b1f 100644 --- a/devtools/client/webconsole/new-console-output/test/store/messages.test.js +++ b/devtools/client/webconsole/new-console-output/test/store/messages.test.js @@ -2,8 +2,10 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; -const { getAllMessages } = require("devtools/client/webconsole/new-console-output/selectors/messages"); -const { getRepeatId } = require("devtools/client/webconsole/new-console-output/utils/messages"); +const { + getAllMessages, + getAllMessagesUiById, +} = require("devtools/client/webconsole/new-console-output/selectors/messages"); const { setupActions, setupStore @@ -19,90 +21,130 @@ describe("Message reducer:", () => { actions = setupActions(); }); - it("adds a message to an empty store", () => { - const { dispatch, getState } = setupStore([]); + describe("messagesById", () => { + it("adds a message to an empty store", () => { + const { dispatch, getState } = setupStore([]); - const packet = stubPackets.get("console.log('foobar', 'test')"); - const message = stubPreparedMessages.get("console.log('foobar', 'test')"); - dispatch(actions.messageAdd(packet)); - - const messages = getAllMessages(getState()); - - expect(messages.first()).toEqual(message); - }); - - it("increments repeat on a repeating message", () => { - const { dispatch, getState } = setupStore([ - "console.log('foobar', 'test')", - "console.log('foobar', 'test')" - ]); - - const packet = stubPackets.get("console.log('foobar', 'test')"); - dispatch(actions.messageAdd(packet)); - dispatch(actions.messageAdd(packet)); - - const messages = getAllMessages(getState()); - - expect(messages.size).toBe(1); - expect(messages.first().repeat).toBe(4); - }); - - it("does not clobber a unique message", () => { - const { dispatch, getState } = setupStore([ - "console.log('foobar', 'test')", - "console.log('foobar', 'test')" - ]); - - const packet = stubPackets.get("console.log('foobar', 'test')"); - dispatch(actions.messageAdd(packet)); - - const packet2 = stubPackets.get("console.log(undefined)"); - dispatch(actions.messageAdd(packet2)); - - const messages = getAllMessages(getState()); - - expect(messages.size).toBe(2); - expect(messages.first().repeat).toBe(3); - expect(messages.last().repeat).toBe(1); - }); - - it("clears the store in response to console.clear()", () => { - const { dispatch, getState } = setupStore([ - "console.log('foobar', 'test')", - "console.log(undefined)" - ]); - - dispatch(actions.messageAdd(stubPackets.get("console.clear()"))); - - const messages = getAllMessages(getState()); - - expect(messages.size).toBe(1); - expect(messages.first().parameters[0]).toBe("Console was cleared."); - }); - - it("limits the number of messages displayed", () => { - const { dispatch, getState } = setupStore([]); - - const logLimit = 1000; - const packet = stubPackets.get("console.log(undefined)"); - for (let i = 1; i <= logLimit + 1; i++) { - packet.message.arguments = [`message num ${i}`]; + const packet = stubPackets.get("console.log('foobar', 'test')"); + const message = stubPreparedMessages.get("console.log('foobar', 'test')"); dispatch(actions.messageAdd(packet)); - } - const messages = getAllMessages(getState()); - expect(messages.count()).toBe(logLimit); - expect(messages.first().parameters[0]).toBe(`message num 2`); - expect(messages.last().parameters[0]).toBe(`message num ${logLimit + 1}`); + const messages = getAllMessages(getState()); + + expect(messages.first()).toEqual(message); + }); + + it("increments repeat on a repeating message", () => { + const { dispatch, getState } = setupStore([ + "console.log('foobar', 'test')", + "console.log('foobar', 'test')" + ]); + + const packet = stubPackets.get("console.log('foobar', 'test')"); + dispatch(actions.messageAdd(packet)); + dispatch(actions.messageAdd(packet)); + + const messages = getAllMessages(getState()); + + expect(messages.size).toBe(1); + expect(messages.first().repeat).toBe(4); + }); + + it("does not clobber a unique message", () => { + const { dispatch, getState } = setupStore([ + "console.log('foobar', 'test')", + "console.log('foobar', 'test')" + ]); + + const packet = stubPackets.get("console.log('foobar', 'test')"); + dispatch(actions.messageAdd(packet)); + + const packet2 = stubPackets.get("console.log(undefined)"); + dispatch(actions.messageAdd(packet2)); + + const messages = getAllMessages(getState()); + + expect(messages.size).toBe(2); + expect(messages.first().repeat).toBe(3); + expect(messages.last().repeat).toBe(1); + }); + + it("adds a message in response to console.clear()", () => { + const { dispatch, getState } = setupStore([]); + + dispatch(actions.messageAdd(stubPackets.get("console.clear()"))); + + const messages = getAllMessages(getState()); + + expect(messages.size).toBe(1); + expect(messages.first().parameters[0]).toBe("Console was cleared."); + }); + + it("clears the messages list in response to MESSAGES_CLEAR action", () => { + const { dispatch, getState } = setupStore([ + "console.log('foobar', 'test')", + "console.log(undefined)" + ]); + + dispatch(actions.messagesClear()); + + const messages = getAllMessages(getState()); + expect(messages.size).toBe(0); + }); + + it("limits the number of messages displayed", () => { + const { dispatch, getState } = setupStore([]); + + const logLimit = 1000; + const packet = stubPackets.get("console.log(undefined)"); + for (let i = 1; i <= logLimit + 1; i++) { + packet.message.arguments = [`message num ${i}`]; + dispatch(actions.messageAdd(packet)); + } + + const messages = getAllMessages(getState()); + expect(messages.count()).toBe(logLimit); + expect(messages.first().parameters[0]).toBe(`message num 2`); + expect(messages.last().parameters[0]).toBe(`message num ${logLimit + 1}`); + }); + + it("does not add null messages to the store", () => { + const { dispatch, getState } = setupStore([]); + + const message = stubPackets.get("console.time('bar')"); + dispatch(actions.messageAdd(message)); + + const messages = getAllMessages(getState()); + expect(messages.size).toBe(0); + }); }); - it("does not add null messages to the store", () => { - const { dispatch, getState } = setupStore([]); + describe("messagesUiById", () => { + it("opens console.trace messages when they are added", () => { + const { dispatch, getState } = setupStore([]); - const message = stubPackets.get("console.time('bar')"); - dispatch(actions.messageAdd(message)); + const message = stubPackets.get("console.trace()"); + dispatch(actions.messageAdd(message)); - const messages = getAllMessages(getState()); - expect(messages.size).toBe(0); + const messages = getAllMessages(getState()); + const messagesUi = getAllMessagesUiById(getState()); + expect(messagesUi.size).toBe(1); + expect(messagesUi.first()).toBe(messages.first().id); + }); + + it("clears the messages UI list in response to MESSAGES_CLEAR action", () => { + const { dispatch, getState } = setupStore([ + "console.log('foobar', 'test')", + "console.log(undefined)" + ]); + + const traceMessage = stubPackets.get("console.trace()"); + dispatch(actions.messageAdd(traceMessage)); + + dispatch(actions.messagesClear()); + + const messagesUi = getAllMessagesUiById(getState()); + expect(messagesUi.size).toBe(0); + }); }); }); diff --git a/devtools/client/webconsole/new-console-output/types.js b/devtools/client/webconsole/new-console-output/types.js index ed4fd3b3699b..2b21aaf61868 100644 --- a/devtools/client/webconsole/new-console-output/types.js +++ b/devtools/client/webconsole/new-console-output/types.js @@ -35,3 +35,14 @@ exports.ConsoleMessage = Immutable.Record({ stacktrace: null, frame: null, }); + +exports.NetworkEventMessage = Immutable.Record({ + id: null, + actor: null, + level: MESSAGE_LEVEL.LOG, + isXHR: false, + request: null, + response: null, + source: MESSAGE_SOURCE.NETWORK, + type: MESSAGE_TYPE.LOG, +}); diff --git a/devtools/client/webconsole/new-console-output/utils/messages.js b/devtools/client/webconsole/new-console-output/utils/messages.js index 61c32f7cdb86..b8685a16b4b3 100644 --- a/devtools/client/webconsole/new-console-output/utils/messages.js +++ b/devtools/client/webconsole/new-console-output/utils/messages.js @@ -15,7 +15,10 @@ const { MESSAGE_TYPE, MESSAGE_LEVEL, } = require("../constants"); -const { ConsoleMessage } = require("../types"); +const { + ConsoleMessage, + NetworkEventMessage, +} = require("../types"); function prepareMessage(packet, idGenerator) { // This packet is already in the expected packet structure. Simply return. @@ -127,10 +130,22 @@ function transformPacket(packet) { type: MESSAGE_TYPE.LOG, level, messageText: pageError.errorMessage, + stacktrace: pageError.stacktrace ? pageError.stacktrace : null, frame, }); } + case "networkEvent": { + let { networkEvent } = packet; + + return new NetworkEventMessage({ + actor: networkEvent.actor, + isXHR: networkEvent.isXHR, + request: networkEvent.request, + response: networkEvent.response, + }); + } + case "evaluationResult": default: { let { result } = packet; @@ -165,6 +180,9 @@ function convertCachedPacket(packet) { } else if ("_navPayload" in packet) { convertPacket.type = "navigationMessage"; convertPacket.message = packet; + } else if (packet._type === "NetworkEvent") { + convertPacket.networkEvent = packet; + convertPacket.type = "networkEvent"; } else { throw new Error("Unexpected packet type"); } diff --git a/devtools/client/webconsole/package.json b/devtools/client/webconsole/package.json index b03da8cabcec..ccc936237190 100644 --- a/devtools/client/webconsole/package.json +++ b/devtools/client/webconsole/package.json @@ -10,10 +10,12 @@ "jsdom": "^9.4.1", "jsdom-global": "^2.0.0", "mocha": "^2.5.3", + "redux-mock-store": "^1.1.4", "require-hacker": "^2.1.4", "sinon": "^1.17.5" }, "scripts": { + "postinstall": "cd ../ && npm install && cd webconsole", "test": "NODE_PATH=`pwd`/../../../:`pwd`/../../../devtools/client/shared/vendor/ mocha new-console-output/test/**/*.test.js --compilers js:babel-register -r jsdom-global/register -r ./new-console-output/test/requireHelper.js" } } diff --git a/devtools/client/webconsole/webconsole.js b/devtools/client/webconsole/webconsole.js index e21ee3b39190..e409ca1d5ec8 100644 --- a/devtools/client/webconsole/webconsole.js +++ b/devtools/client/webconsole/webconsole.js @@ -586,7 +586,8 @@ WebConsoleFrame.prototype = { this.outputNode.parentNode.appendChild(this.experimentalOutputNode); // @TODO Once the toolbox has been converted to React, see if passing // in JSTerm is still necessary. - this.newConsoleOutput = new this.window.NewConsoleOutput(this.experimentalOutputNode, this.jsterm, toolbox); + this.newConsoleOutput = new this.window.NewConsoleOutput( + this.experimentalOutputNode, this.jsterm, toolbox, this.owner); console.log("Created newConsoleOutput", this.newConsoleOutput); let filterToolbar = doc.querySelector(".hud-console-filter-toolbar"); @@ -3323,7 +3324,10 @@ WebConsoleConnectionProxy.prototype = { _onPageError: function (type, packet) { if (this.webConsoleFrame && packet.from == this._consoleActor) { if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) { - this.dispatchMessageAdd(packet); + let category = Utils.categoryForScriptError(packet.pageError); + if (category !== CATEGORY_CSS) { + this.dispatchMessageAdd(packet); + } return; } this.webConsoleFrame.handlePageError(packet.pageError); @@ -3378,7 +3382,11 @@ WebConsoleConnectionProxy.prototype = { */ _onNetworkEvent: function (type, networkInfo) { if (this.webConsoleFrame) { - this.webConsoleFrame.handleNetworkEvent(networkInfo); + if (this.webConsoleFrame.NEW_CONSOLE_OUTPUT_ENABLED) { + this.dispatchMessageAdd(networkInfo); + } else { + this.webConsoleFrame.handleNetworkEvent(networkInfo); + } } }, diff --git a/devtools/server/actors/styleeditor.js b/devtools/server/actors/styleeditor.js index 45d8d0828ae9..5793a2baf18e 100644 --- a/devtools/server/actors/styleeditor.js +++ b/devtools/server/actors/styleeditor.js @@ -208,18 +208,10 @@ var OldStyleSheetActor = protocol.ActorClassWithSpec(oldStyleSheetSpec, { /** * Get the charset of the stylesheet according to the character set rules * defined in . - * - * @param string channelCharset - * Charset of the source string if set by the HTTP channel. + * Note that some of the algorithm is implemented in DevToolsUtils.fetch. */ - _getCSSCharset: function (channelCharset) + _getCSSCharset: function () { - // StyleSheet's charset can be specified from multiple sources - if (channelCharset && channelCharset.length > 0) { - // step 1 of syndata.html: charset given in HTTP header. - return channelCharset; - } - let sheet = this.rawSheet; if (sheet) { // Do we have a @charset rule in the stylesheet? diff --git a/devtools/server/actors/stylesheets.js b/devtools/server/actors/stylesheets.js index 41e5bf1fb93a..f20634e6cb54 100644 --- a/devtools/server/actors/stylesheets.js +++ b/devtools/server/actors/stylesheets.js @@ -665,18 +665,10 @@ var StyleSheetActor = protocol.ActorClassWithSpec(styleSheetSpec, { /** * Get the charset of the stylesheet according to the character set rules * defined in . - * - * @param string channelCharset - * Charset of the source string if set by the HTTP channel. + * Note that some of the algorithm is implemented in DevToolsUtils.fetch. */ - _getCSSCharset: function (channelCharset) + _getCSSCharset: function () { - // StyleSheet's charset can be specified from multiple sources - if (channelCharset && channelCharset.length > 0) { - // step 1 of syndata.html: charset given in HTTP header. - return channelCharset; - } - let sheet = this.rawSheet; if (sheet) { // Do we have a @charset rule in the stylesheet? diff --git a/devtools/shared/DevToolsUtils.js b/devtools/shared/DevToolsUtils.js index 10e6bcc4c94c..3c57b029daa3 100644 --- a/devtools/shared/DevToolsUtils.js +++ b/devtools/shared/DevToolsUtils.js @@ -448,13 +448,31 @@ function mainThreadFetch(aURL, aOptions = { loadFromCache: true, let source = NetUtil.readInputStreamToString(stream, available); stream.close(); + // We do our own BOM sniffing here because there's no convenient + // implementation of the "decode" algorithm + // (https://encoding.spec.whatwg.org/#decode) exposed to JS. + let bomCharset = null; + if (available >= 3 && source.codePointAt(0) == 0xef && + source.codePointAt(1) == 0xbb && source.codePointAt(2) == 0xbf) { + bomCharset = "UTF-8"; + source = source.slice(3); + } else if (available >= 2 && source.codePointAt(0) == 0xfe && + source.codePointAt(1) == 0xff) { + bomCharset = "UTF-16BE"; + source = source.slice(2); + } else if (available >= 2 && source.codePointAt(0) == 0xff && + source.codePointAt(1) == 0xfe) { + bomCharset = "UTF-16LE"; + source = source.slice(2); + } + // If the channel or the caller has correct charset information, the // content will be decoded correctly. If we have to fall back to UTF-8 and // the guess is wrong, the conversion fails and convertToUnicode returns // the input unmodified. Essentially we try to decode the data as UTF-8 // and if that fails, we use the locale specific default encoding. This is // the best we can do if the source does not provide charset info. - let charset = channel.contentCharset || aOptions.charset || "UTF-8"; + let charset = bomCharset || channel.contentCharset || aOptions.charset || "UTF-8"; let unicodeSource = NetworkHelper.convertToUnicode(source, charset); deferred.resolve({ diff --git a/devtools/shared/tests/unit/test_fetch-bom.js b/devtools/shared/tests/unit/test_fetch-bom.js new file mode 100644 index 000000000000..7f299b1ce112 --- /dev/null +++ b/devtools/shared/tests/unit/test_fetch-bom.js @@ -0,0 +1,76 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Tests for DevToolsUtils.fetch BOM detection. + +const CC = Components.Constructor; + +const { HttpServer } = Cu.import("resource://testing-common/httpd.js", {}); +const BinaryOutputStream = CC("@mozilla.org/binaryoutputstream;1", + "nsIBinaryOutputStream", "setOutputStream"); + +function write8(bos) { + bos.write8(0xef); + bos.write8(0xbb); + bos.write8(0xbf); + bos.write8(0x68); + bos.write8(0xc4); + bos.write8(0xb1); +} + +function write16be(bos) { + bos.write8(0xfe); + bos.write8(0xff); + bos.write8(0x00); + bos.write8(0x68); + bos.write8(0x01); + bos.write8(0x31); +} + +function write16le(bos) { + bos.write8(0xff); + bos.write8(0xfe); + bos.write8(0x68); + bos.write8(0x00); + bos.write8(0x31); + bos.write8(0x01); +} + +function getHandler(writer) { + return function (request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + + let bos = new BinaryOutputStream(response.bodyOutputStream); + writer(bos); + }; +} + +const server = new HttpServer(); +server.registerDirectory("/", do_get_cwd()); +server.registerPathHandler("/u8", getHandler(write8)); +server.registerPathHandler("/u16be", getHandler(write16be)); +server.registerPathHandler("/u16le", getHandler(write16le)); +server.start(-1); + +const port = server.identity.primaryPort; +const serverURL = "http://localhost:" + port; + +do_register_cleanup(() => { + return new Promise(resolve => server.stop(resolve)); +}); + +add_task(function* () { + yield test_one(serverURL + "/u8", "UTF-8"); + yield test_one(serverURL + "/u16be", "UTF-16BE"); + yield test_one(serverURL + "/u16le", "UTF-16LE"); +}); + +function* test_one(url, encoding) { + // Be sure to set the encoding to something that will yield an + // invalid result if BOM sniffing is not done. + yield DevToolsUtils.fetch(url, { charset: "ISO-8859-1" }).then(({content}) => { + do_check_eq(content, "hı", "The content looks correct for " + encoding); + }); +} diff --git a/devtools/shared/tests/unit/xpcshell.ini b/devtools/shared/tests/unit/xpcshell.ini index fa9af33c9da0..d6772575d6f6 100644 --- a/devtools/shared/tests/unit/xpcshell.ini +++ b/devtools/shared/tests/unit/xpcshell.ini @@ -10,6 +10,7 @@ support-files = [test_assert.js] [test_csslexer.js] [test_css-properties-db.js] +[test_fetch-bom.js] [test_fetch-chrome.js] [test_fetch-file.js] [test_fetch-http.js] diff --git a/dom/animation/test/mochitest.ini b/dom/animation/test/mochitest.ini index 2bb949652241..805377cf7c01 100644 --- a/dom/animation/test/mochitest.ini +++ b/dom/animation/test/mochitest.ini @@ -45,6 +45,7 @@ support-files = mozilla/file_spacing_property_order.html mozilla/file_transform_limits.html mozilla/file_underlying-discrete-value.html + mozilla/file_set-easing.html style/file_animation-seeking-with-current-time.html style/file_animation-seeking-with-start-time.html style/file_animation-setting-effect.html diff --git a/dom/animation/test/mozilla/file_set-easing.html b/dom/animation/test/mozilla/file_set-easing.html new file mode 100644 index 000000000000..072b125cb0ce --- /dev/null +++ b/dom/animation/test/mozilla/file_set-easing.html @@ -0,0 +1,34 @@ + + + +Test setting easing in sandbox + + + + + diff --git a/dom/animation/test/mozilla/test_set-easing.html b/dom/animation/test/mozilla/test_set-easing.html index 99f1fdafc614..e0069ff1c888 100644 --- a/dom/animation/test/mozilla/test_set-easing.html +++ b/dom/animation/test/mozilla/test_set-easing.html @@ -1,35 +1,14 @@ - -Test setting easing in sandbox - - - - - - + + +
- diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 8f32d8f43d4e..2809743ae131 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -1637,20 +1637,6 @@ nsresult HTMLMediaElement::LoadResource() // Set the media element's CORS mode only when loading a resource mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin)); -#ifdef MOZ_EME - bool isBlob = false; - if (mMediaKeys && - Preferences::GetBool("media.eme.mse-only", true) && - // We only want mediaSource URLs, but they are BlobURL, so we have to - // check the schema and if they are not MediaStream or real Blob. - (NS_FAILED(mLoadingSrc->SchemeIs(BLOBURI_SCHEME, &isBlob)) || - !isBlob || - IsMediaStreamURI(mLoadingSrc) || - IsBlobURI(mLoadingSrc))) { - return NS_ERROR_DOM_NOT_SUPPORTED_ERR; - } -#endif - HTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc); if (other && other->mDecoder) { // Clone it. @@ -4340,8 +4326,10 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo, mDecoder->SetFragmentEndTime(mFragmentEnd); } if (mIsEncrypted) { + // We only support playback of encrypted content via MSE by default. if (!mMediaSource && Preferences::GetBool("media.eme.mse-only", true)) { - DecodeError(NS_ERROR_DOM_MEDIA_FATAL_ERR); + DecodeError(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, + "Encrypted content not supported outside of MSE")); return; } @@ -6110,16 +6098,6 @@ HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys, return nullptr; } - // We only support EME for MSE content by default. - if (mDecoder && - !mMediaSource && - Preferences::GetBool("media.eme.mse-only", true)) { - ShutdownDecoder(); - promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR, - NS_LITERAL_CSTRING("EME not supported on non-MSE streams")); - return promise.forget(); - } - // 1. If mediaKeys and the mediaKeys attribute are the same object, // return a resolved promise. if (mMediaKeys == aMediaKeys) { diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index c06443911634..9e4a27a15c23 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -142,36 +142,6 @@ static_assert(LOW_DATA_THRESHOLD_USECS > AMPLE_AUDIO_USECS, // Amount of excess usecs of data to add in to the "should we buffer" calculation. static const uint32_t EXHAUSTED_DATA_MARGIN_USECS = 100000; -// If we enter buffering within QUICK_BUFFER_THRESHOLD_USECS seconds of starting -// decoding, we'll enter "quick buffering" mode, which exits a lot sooner than -// normal buffering mode. This exists so that if the decode-ahead exhausts the -// downloaded data while decode/playback is just starting up (for example -// after a seek while the media is still playing, or when playing a media -// as soon as it's load started), we won't necessarily stop for 30s and wait -// for buffering. We may actually be able to playback in this case, so exit -// buffering early and try to play. If it turns out we can't play, we'll fall -// back to buffering normally. -static const uint32_t QUICK_BUFFER_THRESHOLD_USECS = 2000000; - -namespace detail { - -// If we're quick buffering, we'll remain in buffering mode while we have less than -// QUICK_BUFFERING_LOW_DATA_USECS of decoded data available. -static const uint32_t QUICK_BUFFERING_LOW_DATA_USECS = 1000000; - -// If QUICK_BUFFERING_LOW_DATA_USECS is > AMPLE_AUDIO_USECS, we won't exit -// quick buffering in a timely fashion, as the decode pauses when it -// reaches AMPLE_AUDIO_USECS decoded data, and thus we'll never reach -// QUICK_BUFFERING_LOW_DATA_USECS. -static_assert(QUICK_BUFFERING_LOW_DATA_USECS <= AMPLE_AUDIO_USECS, - "QUICK_BUFFERING_LOW_DATA_USECS is too large"); - -} // namespace detail - -static TimeDuration UsecsToDuration(int64_t aUsecs) { - return TimeDuration::FromMicroseconds(aUsecs); -} - static int64_t DurationToUsecs(TimeDuration aDuration) { return static_cast(aDuration.ToSeconds() * USECS_PER_S); } @@ -460,7 +430,36 @@ public: void Enter() override { - mMaster->StartDecoding(); + MOZ_ASSERT(mMaster->mSentFirstFrameLoadedEvent); + // Pending seek should've been handled by DECODING_FIRSTFRAME before + // transitioning to DECODING. + MOZ_ASSERT(!mMaster->mQueuedSeek.Exists()); + + if (mMaster->CheckIfDecodeComplete()) { + SetState(DECODER_STATE_COMPLETED); + return; + } + + mDecodeStartTime = TimeStamp::Now(); + + // Reset other state to pristine values before starting decode. + mMaster->mIsAudioPrerolling = !mMaster->DonePrerollingAudio() && + !Reader()->IsWaitingAudioData(); + mMaster->mIsVideoPrerolling = !mMaster->DonePrerollingVideo() && + !Reader()->IsWaitingVideoData(); + + // Ensure that we've got tasks enqueued to decode data if we need to. + mMaster->DispatchDecodeTasksIfNeeded(); + + mMaster->ScheduleStateMachine(); + } + + void Exit() override + { + if (!mDecodeStartTime.IsNull()) { + TimeDuration decodeDuration = TimeStamp::Now() - mDecodeStartTime; + SLOG("Exiting DECODING, decoded for %.3lfs", decodeDuration.ToSeconds()); + } } void Step() override @@ -472,6 +471,10 @@ public: { return DECODER_STATE_DECODING; } + +private: + // Time at which we started decoding. + TimeStamp mDecodeStartTime; }; class MediaDecoderStateMachine::SeekingState @@ -611,14 +614,12 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder, mPlaybackRate(1.0), mLowAudioThresholdUsecs(detail::LOW_AUDIO_USECS), mAmpleAudioThresholdUsecs(detail::AMPLE_AUDIO_USECS), - mQuickBufferingLowDataThresholdUsecs(detail::QUICK_BUFFERING_LOW_DATA_USECS), mIsAudioPrerolling(false), mIsVideoPrerolling(false), mAudioCaptured(false), INIT_WATCHABLE(mAudioCompleted, false), INIT_WATCHABLE(mVideoCompleted, false), mNotifyMetadataBeforeFirstFrame(false), - mQuickBuffering(false), mMinimizePreroll(false), mDecodeThreadWaiting(false), mSentLoadedMetadataEvent(false), @@ -916,11 +917,11 @@ MediaDecoderStateMachine::NeedToSkipToNextKeyframe() bool isLowOnDecodedVideo = !mIsVideoPrerolling && ((GetClock() - mDecodedVideoEndTime) * mPlaybackRate > LOW_VIDEO_THRESHOLD_USECS); - bool lowUndecoded = HasLowUndecodedData(); + bool lowBuffered = HasLowBufferedData(); - if ((isLowOnDecodedAudio || isLowOnDecodedVideo) && !lowUndecoded) { + if ((isLowOnDecodedAudio || isLowOnDecodedVideo) && !lowBuffered) { DECODER_LOG("Skipping video decode to the next keyframe lowAudio=%d lowVideo=%d lowUndecoded=%d async=%d", - isLowOnDecodedAudio, isLowOnDecodedVideo, lowUndecoded, mReader->IsAsync()); + isLowOnDecodedAudio, isLowOnDecodedVideo, lowBuffered, mReader->IsAsync()); return true; } @@ -1173,7 +1174,7 @@ MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideoSample, } TimeDuration decodeTime = TimeStamp::Now() - aDecodeStartTime; if (THRESHOLD_FACTOR * DurationToUsecs(decodeTime) > mLowAudioThresholdUsecs && - !HasLowUndecodedData()) + !HasLowBufferedData()) { mLowAudioThresholdUsecs = std::min(THRESHOLD_FACTOR * DurationToUsecs(decodeTime), mAmpleAudioThresholdUsecs); @@ -1386,7 +1387,7 @@ MediaDecoderStateMachine::MaybeStartBuffering() bool shouldBuffer; if (mReader->UseBufferingHeuristics()) { shouldBuffer = HasLowDecodedData(EXHAUSTED_DATA_MARGIN_USECS) && - (JustExitedQuickBuffering() || HasLowUndecodedData()); + HasLowBufferedData(); } else { MOZ_ASSERT(mReader->IsWaitForDataSupported()); shouldBuffer = (OutOfDecodedAudio() && mReader->IsWaitingAudioData()) || @@ -1656,34 +1657,6 @@ MediaDecoderStateMachine::DecodeFirstFrame() DispatchDecodeTasksIfNeeded(); } -void -MediaDecoderStateMachine::StartDecoding() -{ - MOZ_ASSERT(OnTaskQueue()); - // Should transition to DECODING only after decoding first frames. - MOZ_ASSERT(mSentFirstFrameLoadedEvent); - MOZ_ASSERT(mState == DECODER_STATE_DECODING); - // Pending seek should've been handled by DECODING_FIRSTFRAME before - // transitioning to DECODING. - MOZ_ASSERT(!mQueuedSeek.Exists()); - - if (CheckIfDecodeComplete()) { - SetState(DECODER_STATE_COMPLETED); - return; - } - - mDecodeStartTime = TimeStamp::Now(); - - // Reset other state to pristine values before starting decode. - mIsAudioPrerolling = !DonePrerollingAudio() && !mReader->IsWaitingAudioData(); - mIsVideoPrerolling = !DonePrerollingVideo() && !mReader->IsWaitingVideoData(); - - // Ensure that we've got tasks enqueued to decode data if we need to. - DispatchDecodeTasksIfNeeded(); - - ScheduleStateMachine(); -} - void MediaDecoderStateMachine::PlayStateChanged() { MOZ_ASSERT(OnTaskQueue()); @@ -2265,13 +2238,13 @@ bool MediaDecoderStateMachine::OutOfDecodedAudio() !mMediaSink->HasUnplayedFrames(TrackInfo::kAudioTrack); } -bool MediaDecoderStateMachine::HasLowUndecodedData() +bool MediaDecoderStateMachine::HasLowBufferedData() { MOZ_ASSERT(OnTaskQueue()); - return HasLowUndecodedData(mLowDataThresholdUsecs); + return HasLowBufferedData(mLowDataThresholdUsecs); } -bool MediaDecoderStateMachine::HasLowUndecodedData(int64_t aUsecs) +bool MediaDecoderStateMachine::HasLowBufferedData(int64_t aUsecs) { MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(mState >= DECODER_STATE_DECODING, @@ -2304,9 +2277,17 @@ bool MediaDecoderStateMachine::HasLowUndecodedData(int64_t aUsecs) // Our duration is not up to date. No point buffering. return false; } - media::TimeInterval interval(media::TimeUnit::FromMicroseconds(endOfDecodedData), - media::TimeUnit::FromMicroseconds(std::min(endOfDecodedData + aUsecs, Duration().ToMicroseconds()))); - return endOfDecodedData != INT64_MAX && !mBuffered.Ref().Contains(interval); + + if (endOfDecodedData == INT64_MAX) { + // Have decoded all samples. No point buffering. + return false; + } + + int64_t start = endOfDecodedData; + int64_t end = std::min(GetMediaTime() + aUsecs, Duration().ToMicroseconds()); + media::TimeInterval interval(media::TimeUnit::FromMicroseconds(start), + media::TimeUnit::FromMicroseconds(end)); + return !mBuffered.Ref().Contains(interval); } void @@ -2462,11 +2443,6 @@ MediaDecoderStateMachine::SeekCompleted() // Try to decode another frame to detect if we're at the end... DECODER_LOG("Seek completed, mCurrentPosition=%lld", mCurrentPosition.Ref()); - // Reset quick buffering status. This ensures that if we began the - // seek while quick-buffering, we won't bypass quick buffering mode - // if we need to buffer after the seek. - mQuickBuffering = false; - if (video) { mMediaSink->Redraw(mInfo.mVideo); mOnPlaybackEvent.Notify(MediaEventType::Invalidate); @@ -2542,12 +2518,10 @@ MediaDecoderStateMachine::StepBuffering() bool isLiveStream = mResource->IsLiveStream(); if ((isLiveStream || !CanPlayThrough()) && elapsed < TimeDuration::FromSeconds(mBufferingWait * mPlaybackRate) && - (mQuickBuffering ? HasLowDecodedData(mQuickBufferingLowDataThresholdUsecs) - : HasLowUndecodedData(mBufferingWait * USECS_PER_S)) && + HasLowBufferedData(mBufferingWait * USECS_PER_S) && mResource->IsExpectingMoreData()) { - DECODER_LOG("Buffering: wait %ds, timeout in %.3lfs %s", - mBufferingWait, mBufferingWait - elapsed.ToSeconds(), - (mQuickBuffering ? "(quick exit)" : "")); + DECODER_LOG("Buffering: wait %ds, timeout in %.3lfs", + mBufferingWait, mBufferingWait - elapsed.ToSeconds()); ScheduleStateMachineIn(USECS_PER_S); return; } @@ -2747,14 +2721,6 @@ void MediaDecoderStateMachine::UpdateNextFrameStatus() mNextFrameStatus = status; } -bool MediaDecoderStateMachine::JustExitedQuickBuffering() -{ - MOZ_ASSERT(OnTaskQueue()); - return !mDecodeStartTime.IsNull() && - mQuickBuffering && - (TimeStamp::Now() - mDecodeStartTime) < TimeDuration::FromMicroseconds(QUICK_BUFFER_THRESHOLD_USECS); -} - bool MediaDecoderStateMachine::CanPlayThrough() { @@ -2787,17 +2753,8 @@ MediaDecoderStateMachine::StartBuffering() StopPlayback(); } - TimeDuration decodeDuration = TimeStamp::Now() - mDecodeStartTime; - // Go into quick buffering mode provided we've not just left buffering using - // a "quick exit". This stops us flip-flopping between playing and buffering - // when the download speed is similar to the decode speed. - mQuickBuffering = - !JustExitedQuickBuffering() && - decodeDuration < UsecsToDuration(QUICK_BUFFER_THRESHOLD_USECS); mBufferingStart = TimeStamp::Now(); - DECODER_LOG("Changed state from DECODING to BUFFERING, decoded for %.3lfs", - decodeDuration.ToSeconds()); MediaStatistics stats = GetStatistics(); DECODER_LOG("Playback rate: %.1lfKB/s%s download rate: %.1lfKB/s%s", stats.mPlaybackRate/1024, stats.mPlaybackRateReliable ? "" : " (unreliable)", diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index 70760ad7614f..9d627b2b493c 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -401,20 +401,16 @@ protected: } - // Returns true if we're running low on data which is not yet decoded. - // The decoder monitor must be held. - bool HasLowUndecodedData(); + // Returns true if we're running low on buffered data. + bool HasLowBufferedData(); - // Returns true if we have less than aUsecs of undecoded data available. - bool HasLowUndecodedData(int64_t aUsecs); + // Returns true if we have less than aUsecs of buffered data available. + bool HasLowBufferedData(int64_t aUsecs); // Returns true when there's decoded audio waiting to play. // The decoder monitor must be held. bool HasFutureAudio(); - // Returns true if we recently exited "quick buffering" mode. - bool JustExitedQuickBuffering(); - // Recomputes mNextFrameStatus, possibly dispatching notifications to interested // parties. void UpdateNextFrameStatus(); @@ -475,9 +471,6 @@ protected: // The entry action of DECODER_STATE_DECODING_FIRSTFRAME. void DecodeFirstFrame(); - // The entry action of DECODER_STATE_DECODING. - void StartDecoding(); - // Moves the decoder into the shutdown state, and dispatches an error // event to the media element. This begins shutting down the decoder. // The decoder monitor must be held. This is only called on the @@ -682,9 +675,6 @@ private: // Playback rate. 1.0 : normal speed, 0.5 : two times slower. double mPlaybackRate; - // Time at which we started decoding. Synchronised via decoder monitor. - TimeStamp mDecodeStartTime; - // The maximum number of second we spend buffering when we are short on // unbuffered data. uint32_t mBufferingWait; @@ -713,10 +703,6 @@ private: // we detect that the decode can't keep up with rendering. int64_t mAmpleAudioThresholdUsecs; - // If we're quick buffering, we'll remain in buffering mode while we have less than - // QUICK_BUFFERING_LOW_DATA_USECS of decoded data available. - int64_t mQuickBufferingLowDataThresholdUsecs; - // At the start of decoding we want to "preroll" the decode until we've // got a few frames decoded before we consider whether decode is falling // behind. Otherwise our "we're falling behind" logic will trigger @@ -819,13 +805,6 @@ private: // simplified. bool mNotifyMetadataBeforeFirstFrame; - // If this is true while we're in buffering mode, we can exit early, - // as it's likely we may be able to playback. This happens when we enter - // buffering mode soon after the decode starts, because the decode-ahead - // ran fast enough to exhaust all data while the download is starting up. - // Synchronised via decoder monitor. - bool mQuickBuffering; - // True if we should not decode/preroll unnecessary samples, unless we're // played. "Prerolling" in this context refers to when we decode and // buffer decoded samples in advance of when they're needed for playback. diff --git a/dom/media/MediaFormatReader.cpp b/dom/media/MediaFormatReader.cpp index dda2af89babb..103fc3f077af 100644 --- a/dom/media/MediaFormatReader.cpp +++ b/dom/media/MediaFormatReader.cpp @@ -720,6 +720,7 @@ void MediaFormatReader::NotifyError(TrackType aTrack, const MediaResult& aError) { MOZ_ASSERT(OnTaskQueue()); + NS_WARNING(aError.Description().get()); LOGV("%s Decoding error", TrackTypeToStr(aTrack)); auto& decoder = GetDecoderData(aTrack); decoder.mError = decoder.HasFatalError() ? decoder.mError : Some(aError); diff --git a/dom/media/MediaResult.h b/dom/media/MediaResult.h index 214ad7f5a933..c1e0af64c90e 100644 --- a/dom/media/MediaResult.h +++ b/dom/media/MediaResult.h @@ -59,5 +59,7 @@ private: nsCString mMessage; }; +#define RESULT_DETAIL(arg, ...) nsPrintfCString("%s: " arg, __func__, ##__VA_ARGS__) + } // namespace mozilla #endif // MediaResult_h_ \ No newline at end of file diff --git a/dom/media/flac/FlacDemuxer.cpp b/dom/media/flac/FlacDemuxer.cpp index 63b1f6c0553d..7a98edbee688 100644 --- a/dom/media/flac/FlacDemuxer.cpp +++ b/dom/media/flac/FlacDemuxer.cpp @@ -676,7 +676,7 @@ FlacTrackDemuxer::Init() // Ensure that the next frame returned will be the first. mSource.Seek(SEEK_SET, mParser->FirstFrame().Offset()); mParser->EndFrameSession(); - } else if (!mParser->Info().IsValid()) { + } else if (!mParser->Info().IsValid() || !mParser->FirstFrame().IsValid()) { // We must find at least a frame to determine the metadata. // We can't play this stream. return false; diff --git a/dom/media/mediasink/VideoSink.cpp b/dom/media/mediasink/VideoSink.cpp index 394cdaeebff6..474b8899490d 100644 --- a/dom/media/mediasink/VideoSink.cpp +++ b/dom/media/mediasink/VideoSink.cpp @@ -355,7 +355,8 @@ VideoSink::RenderVideoFrames(int32_t aMaxFrames, frame->mSentToCompositor = true; - if (!frame->mImage || !frame->mImage->IsValid()) { + if (!frame->mImage || !frame->mImage->IsValid() || + !frame->mImage->GetSize().width || !frame->mImage->GetSize().height) { continue; } diff --git a/dom/media/platforms/agnostic/BlankDecoderModule.cpp b/dom/media/platforms/agnostic/BlankDecoderModule.cpp index 7609e377de90..7d7bae721302 100644 --- a/dom/media/platforms/agnostic/BlankDecoderModule.cpp +++ b/dom/media/platforms/agnostic/BlankDecoderModule.cpp @@ -82,7 +82,7 @@ private: void OutputFrame(MediaData* aData) { if (!aData) { - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__)); + mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__)); return; } diff --git a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp index 923970fd7db9..7d523d926f5b 100644 --- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp +++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp @@ -93,8 +93,9 @@ public: Input(aDecrypted.mSample); } else if (aDecrypted.mStatus != Ok) { if (mCallback) { - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - __func__)); + mCallback->Error(MediaResult( + NS_ERROR_DOM_MEDIA_FATAL_ERR, + RESULT_DETAIL("decrypted.mStatus=%u", uint32_t(aDecrypted.mStatus)))); } } else { MOZ_ASSERT(!mIsShutdown); diff --git a/dom/media/platforms/agnostic/gmp/GMPAudioDecoder.cpp b/dom/media/platforms/agnostic/gmp/GMPAudioDecoder.cpp index 796efbdfd3cb..d863d44d4e01 100644 --- a/dom/media/platforms/agnostic/gmp/GMPAudioDecoder.cpp +++ b/dom/media/platforms/agnostic/gmp/GMPAudioDecoder.cpp @@ -31,8 +31,10 @@ AudioCallbackAdapter::Decoded(const nsTArray& aPCM, uint64_t aTimeStamp MOZ_ASSERT(IsOnGMPThread()); if (aRate == 0 || aChannels == 0) { - NS_WARNING("Invalid rate or num channels returned on GMP audio samples"); - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__)); + mCallback->Error(MediaResult( + NS_ERROR_DOM_MEDIA_FATAL_ERR, + RESULT_DETAIL( + "Invalid rate or num channels returned on GMP audio samples"))); return; } @@ -40,7 +42,9 @@ AudioCallbackAdapter::Decoded(const nsTArray& aPCM, uint64_t aTimeStamp MOZ_ASSERT((aPCM.Length() % aChannels) == 0); AlignedAudioBuffer audioData(aPCM.Length()); if (!audioData) { - mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__)); + mCallback->Error( + MediaResult(NS_ERROR_OUT_OF_MEMORY, + RESULT_DETAIL("Unable to allocate audio buffer"))); return; } @@ -52,9 +56,8 @@ AudioCallbackAdapter::Decoded(const nsTArray& aPCM, uint64_t aTimeStamp mAudioFrameSum = 0; auto timestamp = UsecsToFrames(aTimeStamp, aRate); if (!timestamp.isValid()) { - NS_WARNING("Invalid timestamp"); mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_OVERFLOW_ERR, - __func__)); + RESULT_DETAIL("Invalid timestamp"))); return; } mAudioFrameOffset = timestamp.value(); @@ -63,18 +66,18 @@ AudioCallbackAdapter::Decoded(const nsTArray& aPCM, uint64_t aTimeStamp auto timestamp = FramesToUsecs(mAudioFrameOffset + mAudioFrameSum, aRate); if (!timestamp.isValid()) { - NS_WARNING("Invalid timestamp on audio samples"); - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_OVERFLOW_ERR, - __func__)); + mCallback->Error( + MediaResult(NS_ERROR_DOM_MEDIA_OVERFLOW_ERR, + RESULT_DETAIL("Invalid timestamp on audio samples"))); return; } mAudioFrameSum += numFrames; auto duration = FramesToUsecs(numFrames, aRate); if (!duration.isValid()) { - NS_WARNING("Invalid duration on audio samples"); - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_OVERFLOW_ERR, - __func__)); + mCallback->Error( + MediaResult(NS_ERROR_DOM_MEDIA_OVERFLOW_ERR, + RESULT_DETAIL("Invalid duration on audio samples"))); return; } @@ -120,16 +123,17 @@ void AudioCallbackAdapter::Error(GMPErr aErr) { MOZ_ASSERT(IsOnGMPThread()); - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - nsPrintfCString("%s: %d", __func__, aErr))); + mCallback->Error(MediaResult(aErr == GMPDecodeErr + ? NS_ERROR_DOM_MEDIA_DECODE_ERR + : NS_ERROR_DOM_MEDIA_FATAL_ERR, + RESULT_DETAIL("GMPErr:%x", aErr))); } void AudioCallbackAdapter::Terminated() { - NS_WARNING("AAC GMP decoder terminated."); mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - __func__)); + RESULT_DETAIL("Audio GMP decoder terminated."))); } GMPAudioDecoderParams::GMPAudioDecoderParams(const CreateDecoderParams& aParams) @@ -252,7 +256,8 @@ GMPAudioDecoder::Input(MediaRawData* aSample) RefPtr sample(aSample); if (!mGMP) { - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__)); + mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, + RESULT_DETAIL("mGMP not initialized"))); return; } @@ -261,9 +266,7 @@ GMPAudioDecoder::Input(MediaRawData* aSample) gmp::GMPAudioSamplesImpl samples(sample, mConfig.mChannels, mConfig.mRate); nsresult rv = mGMP->Decode(samples); if (NS_FAILED(rv)) { - mCallback->Error( - MediaResult(rv, nsPrintfCString("%s: decode error (%d)", - __func__, rv))); + mCallback->Error(MediaResult(rv, __func__)); } } diff --git a/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp b/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp index dad4466fd6e3..acc4cc9fb975 100644 --- a/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp +++ b/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp @@ -95,16 +95,18 @@ void VideoCallbackAdapter::Error(GMPErr aErr) { MOZ_ASSERT(IsOnGMPThread()); - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - nsPrintfCString("%s: %d", __func__, aErr))); + mCallback->Error(MediaResult(aErr == GMPDecodeErr + ? NS_ERROR_DOM_MEDIA_DECODE_ERR + : NS_ERROR_DOM_MEDIA_FATAL_ERR, + RESULT_DETAIL("GMPErr:%x", aErr))); } void VideoCallbackAdapter::Terminated() { // Note that this *may* be called from the proxy thread also. - NS_WARNING("GMP decoder terminated."); - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__)); + mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, + RESULT_DETAIL("Video GMP decoder terminated."))); } GMPVideoDecoderParams::GMPVideoDecoderParams(const CreateDecoderParams& aParams) @@ -184,14 +186,16 @@ GMPVideoDecoder::CreateFrame(MediaRawData* aSample) GMPVideoFrame* ftmp = nullptr; GMPErr err = mHost->CreateFrame(kGMPEncodedVideoFrame, &ftmp); if (GMP_FAILED(err)) { - mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__)); + mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, + RESULT_DETAIL("Host::CreateFrame:%x", err))); return nullptr; } GMPUniquePtr frame(static_cast(ftmp)); err = frame->CreateEmptyFrame(aSample->Size()); if (GMP_FAILED(err)) { - mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__)); + mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, + RESULT_DETAIL("GMPVideoEncodedFrame::CreateEmptyFrame:%x", err))); return nullptr; } @@ -322,7 +326,7 @@ GMPVideoDecoder::Input(MediaRawData* aSample) RefPtr sample(aSample); if (!mGMP) { mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - __func__)); + RESULT_DETAIL("mGMP not initialized"))); return; } @@ -330,13 +334,15 @@ GMPVideoDecoder::Input(MediaRawData* aSample) GMPUniquePtr frame = CreateFrame(sample); if (!frame) { - mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__)); + mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, + RESULT_DETAIL("CreateFrame returned null"))); return; } nsTArray info; // No codec specific per-frame info to pass. nsresult rv = mGMP->Decode(Move(frame), false, info, 0); if (NS_FAILED(rv)) { - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__)); + mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("mGMP->Decode:%x", rv))); } } diff --git a/dom/media/platforms/apple/AppleATDecoder.cpp b/dom/media/platforms/apple/AppleATDecoder.cpp index 28b4711e082c..0b8dfa46cf08 100644 --- a/dom/media/platforms/apple/AppleATDecoder.cpp +++ b/dom/media/platforms/apple/AppleATDecoder.cpp @@ -194,8 +194,8 @@ AppleATDecoder::SubmitSample(MediaRawData* aSample) if (!mConverter) { rv = SetupDecoder(aSample); if (rv != NS_OK && rv != NS_ERROR_NOT_INITIALIZED) { - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - __func__)); + mCallback->Error( + MediaResult(rv, RESULT_DETAIL("Unable to create decoder"))); return; } } @@ -207,7 +207,8 @@ AppleATDecoder::SubmitSample(MediaRawData* aSample) rv = DecodeSample(mQueuedSamples[i]); if (NS_FAILED(rv)) { mQueuedSamples.Clear(); - mCallback->Error(MediaResult(rv, __func__)); + mCallback->Error(MediaResult( + rv, RESULT_DETAIL("Unable to decode sample %lld", aSample->mTime))); return; } } diff --git a/dom/media/platforms/apple/AppleVTDecoder.cpp b/dom/media/platforms/apple/AppleVTDecoder.cpp index c58e77cab8d6..81638870a040 100644 --- a/dom/media/platforms/apple/AppleVTDecoder.cpp +++ b/dom/media/platforms/apple/AppleVTDecoder.cpp @@ -310,8 +310,10 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage, CVReturn rv = CVPixelBufferLockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly); if (rv != kCVReturnSuccess) { NS_ERROR("error locking pixel data"); - mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__)); - return NS_ERROR_OUT_OF_MEMORY; + mCallback->Error( + MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("CVPixelBufferLockBaseAddress:%x", rv))); + return NS_ERROR_DOM_MEDIA_DECODE_ERR; } // Y plane. buffer.mPlanes[0].mData = @@ -446,14 +448,17 @@ AppleVTDecoder::DoDecode(MediaRawData* aSample) block.receive()); if (rv != noErr) { NS_ERROR("Couldn't create CMBlockBuffer"); - mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__)); + mCallback->Error( + MediaResult(NS_ERROR_OUT_OF_MEMORY, + RESULT_DETAIL("CMBlockBufferCreateWithMemoryBlock:%x", rv))); return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__); } CMSampleTimingInfo timestamp = TimingInfoFromSample(aSample); rv = CMSampleBufferCreate(kCFAllocatorDefault, block, true, 0, 0, mFormat, 1, 1, ×tamp, 0, NULL, sample.receive()); if (rv != noErr) { NS_ERROR("Couldn't create CMSampleBuffer"); - mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__)); + mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, + RESULT_DETAIL("CMSampleBufferCreate:%x", rv))); return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__); } @@ -467,7 +472,9 @@ AppleVTDecoder::DoDecode(MediaRawData* aSample) if (rv != noErr && !(infoFlags & kVTDecodeInfo_FrameDropped)) { LOG("AppleVTDecoder: Error %d VTDecompressionSessionDecodeFrame", rv); NS_WARNING("Couldn't pass frame to decoder"); - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__)); + mCallback->Error( + MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("VTDecompressionSessionDecodeFrame:%x", rv))); return NS_ERROR_DOM_MEDIA_DECODE_ERR; } diff --git a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp index 72087cb53d9f..86fa3a4d6ce5 100644 --- a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp +++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp @@ -123,7 +123,8 @@ WMFMediaDataDecoder::ProcessDecode(MediaRawData* aSample) HRESULT hr = mMFTManager->Input(aSample); if (FAILED(hr)) { NS_WARNING("MFTManager rejected sample"); - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__)); + mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("MFTManager::Input:%x", hr))); if (!mRecordedError) { SendTelemetry(hr); mRecordedError = true; @@ -150,7 +151,8 @@ WMFMediaDataDecoder::ProcessOutput() mCallback->InputExhausted(); } else if (FAILED(hr)) { NS_WARNING("WMFMediaDataDecoder failed to output data"); - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__)); + mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("MFTManager::Output:%x", hr))); if (!mRecordedError) { SendTelemetry(hr); mRecordedError = true; diff --git a/dom/media/platforms/wrappers/H264Converter.cpp b/dom/media/platforms/wrappers/H264Converter.cpp index 95c1476779d9..d449c60cc3ec 100644 --- a/dom/media/platforms/wrappers/H264Converter.cpp +++ b/dom/media/platforms/wrappers/H264Converter.cpp @@ -55,7 +55,8 @@ H264Converter::Input(MediaRawData* aSample) if (!mp4_demuxer::AnnexB::ConvertSampleToAVCC(aSample)) { // We need AVCC content to be able to later parse the SPS. // This is a no-op if the data is already AVCC. - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__)); + mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, + RESULT_DETAIL("ConvertSampleToAVCC"))); return; } @@ -88,7 +89,9 @@ H264Converter::Input(MediaRawData* aSample) rv = CheckForSPSChange(aSample); } if (NS_FAILED(rv)) { - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__)); + mCallback->Error( + MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, + RESULT_DETAIL("Unable to create H264 decoder"))); return; } @@ -99,7 +102,8 @@ H264Converter::Input(MediaRawData* aSample) if (!mNeedAVCC && !mp4_demuxer::AnnexB::ConvertSampleToAnnexB(aSample)) { - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__)); + mCallback->Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, + RESULT_DETAIL("ConvertSampleToAnnexB"))); return; } @@ -262,8 +266,9 @@ void H264Converter::OnDecoderInitFailed(MediaResult aError) { mInitPromiseRequest.Complete(); - mCallback->Error(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - __func__)); + mCallback->Error( + MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, + RESULT_DETAIL("Unable to initialize H264 decoder"))); } nsresult diff --git a/dom/media/tests/mochitest/mochitest.ini b/dom/media/tests/mochitest/mochitest.ini index aa564f425e1c..30a27935b0eb 100644 --- a/dom/media/tests/mochitest/mochitest.ini +++ b/dom/media/tests/mochitest/mochitest.ini @@ -41,7 +41,7 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g emulator seems to be to [test_enumerateDevices.html] skip-if = buildapp == 'mulet' [test_ondevicechange.html] -skip-if = toolkit == 'gonk' || buildapp == 'mulet' || os == 'linux' || os == 'win' || os == 'android' +skip-if = toolkit == 'gonk' || buildapp == 'mulet' || os == 'win' || os == 'android' [test_getUserMedia_audioCapture.html] skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g emulator seems to be too slow (Bug 1016498 and 1008080), android(Bug 1189784, timeouts on 4.3 emulator) [test_getUserMedia_addTrackRemoveTrack.html] diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index a2852bfd5163..b7651be1ad00 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -222,12 +222,14 @@ nsPluginInstanceOwner::GetImageContainer() container = LayerManager::CreateImageContainer(); - // Try to get it as an EGLImage first. - RefPtr img; - AttachToContainerAsSurfaceTexture(container, mInstance, r, &img); + if (r.width && r.height) { + // Try to get it as an EGLImage first. + RefPtr img; + AttachToContainerAsSurfaceTexture(container, mInstance, r, &img); - if (img) { - container->SetCurrentImageInTransaction(img); + if (img) { + container->SetCurrentImageInTransaction(img); + } } #else if (NeedsScrollImageLayer()) { @@ -1578,11 +1580,13 @@ nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInf { RefPtr container = LayerManager::CreateImageContainer(); - RefPtr img = new SurfaceTextureImage( - aVideoInfo->mSurfaceTexture, - gfx::IntSize::Truncate(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height), - gl::OriginPos::BottomLeft); - container->SetCurrentImageInTransaction(img); + if (aVideoInfo->mDimensions.width && aVideoInfo->mDimensions.height) { + RefPtr img = new SurfaceTextureImage( + aVideoInfo->mSurfaceTexture, + gfx::IntSize::Truncate(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height), + gl::OriginPos::BottomLeft); + container->SetCurrentImageInTransaction(img); + } return container.forget(); } diff --git a/gfx/2d/Polygon.h b/gfx/2d/Polygon.h index 05798a4cbda1..795305854a9c 100644 --- a/gfx/2d/Polygon.h +++ b/gfx/2d/Polygon.h @@ -7,6 +7,7 @@ #ifndef MOZILLA_GFX_POLYGON_H #define MOZILLA_GFX_POLYGON_H +#include "Matrix.h" #include "mozilla/InitializerList.h" #include "nsTArray.h" #include "Point.h" @@ -14,21 +15,30 @@ namespace mozilla { namespace gfx { - // BasePolygon3D stores the points of a convex planar polygon. template class BasePolygon3D { public: - explicit BasePolygon3D(const std::initializer_list>& aPoints) - : mPoints(aPoints) + BasePolygon3D() {} + + explicit BasePolygon3D(const std::initializer_list>& aPoints, + Point3DTyped aNormal = + Point3DTyped(0.0f, 0.0f, 1.0f)) + : mNormal(aNormal), mPoints(aPoints) { - CalculateNormal(); +#ifdef DEBUG + EnsurePlanarPolygon(); +#endif } - explicit BasePolygon3D(nsTArray> && aPoints) - : mPoints(aPoints) + explicit BasePolygon3D(nsTArray>&& aPoints, + Point3DTyped aNormal = + Point3DTyped(0.0f, 0.0f, 1.0f)) + : mNormal(aNormal), mPoints(aPoints) { - CalculateNormal(); +#ifdef DEBUG + EnsurePlanarPolygon(); +#endif } const Point3DTyped& GetNormal() const @@ -36,7 +46,7 @@ public: return mNormal; } - const nsTArray& GetPoints() const + const nsTArray>& GetPoints() const { return mPoints; } @@ -47,40 +57,65 @@ public: return mPoints[aIndex]; } + void TransformToLayerSpace(const Matrix4x4Typed& aInverseTransform) + { + TransformPoints(aInverseTransform); + mNormal = Point3DTyped(0.0f, 0.0f, 1.0f); + } + + void TransformToScreenSpace(const Matrix4x4Typed& aTransform) + { + TransformPoints(aTransform); + + // Normal vectors should be transformed using inverse transpose. + mNormal = aTransform.Inverse().Transpose().TransformPoint(mNormal); + } + private: - // Calculates the polygon surface normal. - // The resulting normal vector will point towards the viewer when the polygon - // has a counter-clockwise winding order from the perspective of the viewer. - void CalculateNormal() + +#ifdef DEBUG + void EnsurePlanarPolygon() const { MOZ_ASSERT(mPoints.Length() >= 3); // This normal calculation method works only for planar polygons. - mNormal = (mPoints[1] - mPoints[0]).CrossProduct(mPoints[2] - mPoints[0]); + // The resulting normal vector will point towards the viewer when the polygon + // has a counter-clockwise winding order from the perspective of the viewer. + Point3DTyped normal; - const float epsilon = 0.001f; - if (mNormal.Length() < epsilon) { - // The first three points were too close. - // Use more points for better accuracy. - for (size_t i = 2; i < mPoints.Length() - 1; ++i) { - mNormal += (mPoints[i] - mPoints[0]).CrossProduct(mPoints[i + 1] - mPoints[0]); - } + for (size_t i = 1; i < mPoints.Length() - 1; ++i) { + normal += + (mPoints[i] - mPoints[0]).CrossProduct(mPoints[i + 1] - mPoints[0]); } - mNormal.Normalize(); + // Ensure that at least one component is greater than zero. + // This avoids division by zero when normalizing the vector. + bool hasNonZeroComponent = std::abs(normal.x) > 0.0f || + std::abs(normal.y) > 0.0f || + std::abs(normal.z) > 0.0f; + MOZ_ASSERT(hasNonZeroComponent); + + normal.Normalize(); - #ifdef DEBUG // Ensure that the polygon is planar. // http://mathworld.wolfram.com/Point-PlaneDistance.html - for (const gfx::Point3DTyped& point : mPoints) { - float d = mNormal.DotProduct(point - mPoints[0]); + const float epsilon = 0.01f; + for (const Point3DTyped& point : mPoints) { + float d = normal.DotProduct(point - mPoints[0]); MOZ_ASSERT(std::abs(d) < epsilon); } - #endif + } +#endif + + void TransformPoints(const Matrix4x4Typed& aTransform) + { + for (Point3DTyped& point : mPoints) { + point = aTransform.TransformPoint(point); + } } - nsTArray> mPoints; Point3DTyped mNormal; + nsTArray> mPoints; }; typedef BasePolygon3D Polygon3D; diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index df7567a715a1..126a4942e349 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -471,6 +471,7 @@ GLContext::GLContext(CreateContextFlags flags, const SurfaceCaps& caps, mNeedsTextureSizeChecks(false), mNeedsFlushBeforeDeleteFB(false), mTextureAllocCrashesOnMapFailure(false), + mNeedsCheckAfterAttachTextureToFb(false), mWorkAroundDriverBugs(true), mHeavyGLCallsSinceLastFlush(false) { @@ -1063,6 +1064,17 @@ GLContext::InitWithPrefixImpl(const char* prefix, bool trygl) mTextureAllocCrashesOnMapFailure = true; } #endif +#if MOZ_WIDGET_ANDROID + if (mWorkAroundDriverBugs && + Renderer() == GLRenderer::SGX540 && + AndroidBridge::Bridge()->GetAPIVersion() <= 15) { + // Bug 1288446. Driver sometimes crashes when uploading data to a + // texture if the render target has changed since the texture was + // rendered from. Calling glCheckFramebufferStatus after + // glFramebufferTexture2D prevents the crash. + mNeedsCheckAfterAttachTextureToFb = true; + } +#endif mMaxTextureImageSize = mMaxTextureSize; diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 41ec4ad8be9c..ac79c950283d 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -1967,6 +1967,9 @@ public: BEFORE_GL_CALL; mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget, texture, level); AFTER_GL_CALL; + if (mNeedsCheckAfterAttachTextureToFb) { + fCheckFramebufferStatus(target); + } } void fFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { @@ -3531,6 +3534,7 @@ protected: bool mNeedsTextureSizeChecks; bool mNeedsFlushBeforeDeleteFB; bool mTextureAllocCrashesOnMapFailure; + bool mNeedsCheckAfterAttachTextureToFb; bool mWorkAroundDriverBugs; bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const { diff --git a/gfx/layers/BSPTree.cpp b/gfx/layers/BSPTree.cpp index a0992e6558b0..aa8a4d4d89c8 100644 --- a/gfx/layers/BSPTree.cpp +++ b/gfx/layers/BSPTree.cpp @@ -9,58 +9,19 @@ namespace mozilla { namespace layers { -gfx::Polygon3D PopFront(std::deque& aPolygons) +LayerPolygon PopFront(std::deque& aLayers) { - gfx::Polygon3D polygon = std::move(aPolygons.front()); - aPolygons.pop_front(); - return polygon; + LayerPolygon layer = std::move(aLayers.front()); + aLayers.pop_front(); + return layer; } namespace { -static int sign(float d) { - if (d > 0) return 1; - if (d < 0) return -1; - - return 0; -} - -} - -void -BSPTree::BuildDrawOrder(const UniquePtr& aNode, - nsTArray& aPolygons) const -{ - const gfx::Point3D& normal = aNode->First().GetNormal(); - - UniquePtr *front = &aNode->front; - UniquePtr *back = &aNode->back; - - // Since the goal is to return the draw order from back to front, we reverse - // the traversal order if the current polygon is facing towards the camera. - const bool reverseOrder = normal.z > 0.0f; - - if (reverseOrder) { - std::swap(front, back); - } - - if (*front) { - BuildDrawOrder(*front, aPolygons); - } - - for (gfx::Polygon3D& polygon : aNode->polygons) { - aPolygons.AppendElement(std::move(polygon)); - } - - if (*back) { - BuildDrawOrder(*back, aPolygons); - } -} - nsTArray -BSPTree::CalculateDotProduct(const gfx::Polygon3D& aFirst, - const gfx::Polygon3D& aSecond, - size_t& aPos, size_t& aNeg) const +CalculateDotProduct(const gfx::Polygon3D& aFirst, + const gfx::Polygon3D& aSecond, + size_t& aPos, size_t& aNeg) { // Point classification might produce incorrect results due to numerical // inaccuracies. Using an epsilon value makes the splitting plane "thicker". @@ -89,65 +50,25 @@ BSPTree::CalculateDotProduct(const gfx::Polygon3D& aFirst, return dotProducts; } -void -BSPTree::BuildTree(UniquePtr& aRoot, - std::deque& aPolygons) -{ - if (aPolygons.empty()) { - return; - } +int Sign(float aValue) { + if (aValue > 0) return 1; + if (aValue < 0) return -1; - const gfx::Polygon3D& splittingPlane = aRoot->First(); - std::deque backPolygons, frontPolygons; - - for (gfx::Polygon3D& polygon : aPolygons) { - size_t pos = 0, neg = 0; - nsTArray dots = CalculateDotProduct(splittingPlane, polygon, - pos, neg); - - // Back polygon - if (pos == 0 && neg > 0) { - backPolygons.push_back(std::move(polygon)); - } - // Front polygon - else if (pos > 0 && neg == 0) { - frontPolygons.push_back(std::move(polygon)); - } - // Coplanar polygon - else if (pos == 0 && neg == 0) { - aRoot->polygons.push_back(std::move(polygon)); - } - // Polygon intersects with the splitting plane. - else if (pos > 0 && neg > 0) { - nsTArray backPoints, frontPoints; - SplitPolygon(splittingPlane, polygon, dots, backPoints, frontPoints); - - backPolygons.push_back(gfx::Polygon3D(std::move(backPoints))); - frontPolygons.push_back(gfx::Polygon3D(std::move(frontPoints))); - } - } - - if (!backPolygons.empty()) { - aRoot->back.reset(new BSPTreeNode(PopFront(backPolygons))); - BuildTree(aRoot->back, backPolygons); - } - - if (!frontPolygons.empty()) { - aRoot->front.reset(new BSPTreeNode(PopFront(frontPolygons))); - BuildTree(aRoot->front, frontPolygons); - } + return 0; } void -BSPTree::SplitPolygon(const gfx::Polygon3D& aSplittingPlane, - const gfx::Polygon3D& aPolygon, - const nsTArray& dots, - nsTArray& backPoints, - nsTArray& frontPoints) +SplitPolygon(const gfx::Polygon3D& aSplittingPlane, + const gfx::Polygon3D& aPolygon, + const nsTArray& dots, + gfx::Polygon3D& back, + gfx::Polygon3D& front) { const gfx::Point3D& normal = aSplittingPlane.GetNormal(); const size_t pointCount = aPolygon.GetPoints().Length(); + nsTArray backPoints, frontPoints; + for (size_t i = 0; i < pointCount; ++i) { size_t j = (i + 1) % pointCount; @@ -168,7 +89,7 @@ BSPTree::SplitPolygon(const gfx::Polygon3D& aSplittingPlane, // If the sign of the dot product changes between two consecutive vertices, // the splitting plane intersects the corresponding polygon edge. - if (sign(dotA) != sign(dotB)) { + if (Sign(dotA) != Sign(dotB)) { // Calculate the line segment and plane intersection point. const gfx::Point3D ab = b - a; @@ -181,6 +102,91 @@ BSPTree::SplitPolygon(const gfx::Polygon3D& aSplittingPlane, frontPoints.AppendElement(p); } } + + back = gfx::Polygon3D(std::move(backPoints), aPolygon.GetNormal()); + front = gfx::Polygon3D(std::move(frontPoints), aPolygon.GetNormal()); +} + +} // namespace + +void +BSPTree::BuildDrawOrder(const UniquePtr& aNode, + nsTArray& aLayers) const +{ + const gfx::Point3D& normal = aNode->First().GetNormal(); + + UniquePtr *front = &aNode->front; + UniquePtr *back = &aNode->back; + + // Since the goal is to return the draw order from back to front, we reverse + // the traversal order if the current polygon is facing towards the camera. + const bool reverseOrder = normal.z > 0.0f; + + if (reverseOrder) { + std::swap(front, back); + } + + if (*front) { + BuildDrawOrder(*front, aLayers); + } + + for (LayerPolygon& layer : aNode->layers) { + aLayers.AppendElement(std::move(layer)); + } + + if (*back) { + BuildDrawOrder(*back, aLayers); + } +} + +void +BSPTree::BuildTree(UniquePtr& aRoot, + std::deque& aLayers) +{ + if (aLayers.empty()) { + return; + } + + const gfx::Polygon3D& splittingPlane = aRoot->First(); + std::deque backLayers, frontLayers; + + for (LayerPolygon& layerPolygon : aLayers) { + size_t pos = 0, neg = 0; + + nsTArray dots = + CalculateDotProduct(splittingPlane, *layerPolygon.geometry, pos, neg); + + // Back polygon + if (pos == 0 && neg > 0) { + backLayers.push_back(std::move(layerPolygon)); + } + // Front polygon + else if (pos > 0 && neg == 0) { + frontLayers.push_back(std::move(layerPolygon)); + } + // Coplanar polygon + else if (pos == 0 && neg == 0) { + aRoot->layers.push_back(std::move(layerPolygon)); + } + // Polygon intersects with the splitting plane. + else if (pos > 0 && neg > 0) { + gfx::Polygon3D back, front; + SplitPolygon(splittingPlane, *layerPolygon.geometry, dots, back, front); + + backLayers.push_back(LayerPolygon(std::move(back), layerPolygon.layer)); + frontLayers.push_back(LayerPolygon(std::move(front), layerPolygon.layer)); + } + } + + if (!backLayers.empty()) { + aRoot->back.reset(new BSPTreeNode(PopFront(backLayers))); + BuildTree(aRoot->back, backLayers); + } + + if (!frontLayers.empty()) { + aRoot->front.reset(new BSPTreeNode(PopFront(frontLayers))); + BuildTree(aRoot->front, frontLayers); + } } } // namespace layers diff --git a/gfx/layers/BSPTree.h b/gfx/layers/BSPTree.h index c5d98f5fa2d1..ca956e79d434 100644 --- a/gfx/layers/BSPTree.h +++ b/gfx/layers/BSPTree.h @@ -15,28 +15,43 @@ namespace mozilla { namespace layers { -gfx::Polygon3D PopFront(std::deque& aPolygons); +class Layer; -// Represents a node in a BSP tree. The node contains at least one polygon that -// is used as a splitting plane, and at most two child nodes that represent the -// splitting planes that further subdivide the space. +// Represents a layer that might have a non-rectangular geometry. +struct LayerPolygon { + LayerPolygon(gfx::Polygon3D&& aGeometry, Layer *aLayer) + : layer(aLayer), geometry(Some(aGeometry)) {} + + explicit LayerPolygon(Layer *aLayer) + : layer(aLayer) {} + + Layer *layer; + Maybe geometry; +}; + +LayerPolygon PopFront(std::deque& aLayers); + +// Represents a node in a BSP tree. The node contains at least one layer with +// associated geometry that is used as a splitting plane, and at most two child +// nodes that represent the splitting planes that further subdivide the space. struct BSPTreeNode { - explicit BSPTreeNode(gfx::Polygon3D && aPolygon) + explicit BSPTreeNode(LayerPolygon&& layer) { - polygons.push_back(std::move(aPolygon)); + layers.push_back(std::move(layer)); } const gfx::Polygon3D& First() const { - return polygons[0]; + MOZ_ASSERT(layers[0].geometry); + return *layers[0].geometry; } UniquePtr front; UniquePtr back; - std::deque polygons; + std::deque layers; }; -// BSPTree class takes a list of polygons as an input and uses binary space +// BSPTree class takes a list of layers as an input and uses binary space // partitioning algorithm to create a tree structure that can be used for // depth sorting. // @@ -45,11 +60,13 @@ struct BSPTreeNode { // ftp://ftp.sgi.com/other/bspfaq/faq/bspfaq.html class BSPTree { public: - // This constructor takes the ownership of polygons in the given list. - explicit BSPTree(std::deque& aPolygons) - : mRoot(new BSPTreeNode(PopFront(aPolygons))) + // This constructor takes the ownership of layers in the given list. + explicit BSPTree(std::deque& aLayers) { - BuildTree(mRoot, aPolygons); + MOZ_ASSERT(!aLayers.empty()); + mRoot.reset(new BSPTreeNode(PopFront(aLayers))); + + BuildTree(mRoot, aLayers); } // Returns the root node of the BSP tree. @@ -59,31 +76,22 @@ public: } // Builds and returns the back-to-front draw order for the created BSP tree. - nsTArray GetDrawOrder() const + nsTArray GetDrawOrder() const { - nsTArray polygons; - BuildDrawOrder(mRoot, polygons); - return polygons; + nsTArray layers; + BuildDrawOrder(mRoot, layers); + return layers; } private: UniquePtr mRoot; + // BuildDrawOrder and BuildTree are called recursively. The depth of the + // recursion depends on the amount of polygons and their intersections. void BuildDrawOrder(const UniquePtr& aNode, - nsTArray& aPolygons) const; - + nsTArray& aLayers) const; void BuildTree(UniquePtr& aRoot, - std::deque& aPolygons); - - nsTArray CalculateDotProduct(const gfx::Polygon3D& aFirst, - const gfx::Polygon3D& aSecond, - size_t& aPos, size_t& aNeg) const; - - void SplitPolygon(const gfx::Polygon3D& aSplittingPlane, - const gfx::Polygon3D& aPolygon, - const nsTArray& dots, - nsTArray& backPoints, - nsTArray& frontPoints); + std::deque& aLayers); }; } // namespace layers diff --git a/gfx/src/nsColor.cpp b/gfx/src/nsColor.cpp index 5dc31ed2ff6f..359f9fde47dd 100644 --- a/gfx/src/nsColor.cpp +++ b/gfx/src/nsColor.cpp @@ -5,6 +5,7 @@ #include "mozilla/ArrayUtils.h" // for ArrayLength #include "mozilla/mozalloc.h" // for operator delete, etc +#include "mozilla/MathAlgorithms.h" #include "nsColor.h" #include // for int32_t @@ -256,6 +257,59 @@ NS_ComposeColors(nscolor aBG, nscolor aFG) return NS_RGBA(r, g, b, a); } +namespace mozilla { + +static uint32_t +BlendColorComponent(uint32_t aBg, uint32_t aFg, uint32_t aFgAlpha) +{ + return RoundingDivideBy255(aBg * (255 - aFgAlpha) + aFg * aFgAlpha); +} + +nscolor +LinearBlendColors(nscolor aBg, nscolor aFg, uint_fast8_t aFgRatio) +{ + // Common case that either pure background or pure foreground + if (aFgRatio == 0) { + return aBg; + } + if (aFgRatio == 255) { + return aFg; + } + // Common case that alpha channel is equal (usually both are opaque) + if (NS_GET_A(aBg) == NS_GET_A(aFg)) { + auto r = BlendColorComponent(NS_GET_R(aBg), NS_GET_R(aFg), aFgRatio); + auto g = BlendColorComponent(NS_GET_G(aBg), NS_GET_G(aFg), aFgRatio); + auto b = BlendColorComponent(NS_GET_B(aBg), NS_GET_B(aFg), aFgRatio); + return NS_RGBA(r, g, b, NS_GET_A(aFg)); + } + + constexpr float kFactor = 1.0f / 255.0f; + + float p1 = kFactor * (255 - aFgRatio); + float a1 = kFactor * NS_GET_A(aBg); + float r1 = a1 * NS_GET_R(aBg); + float g1 = a1 * NS_GET_G(aBg); + float b1 = a1 * NS_GET_B(aBg); + + float p2 = 1.0f - p1; + float a2 = kFactor * NS_GET_A(aFg); + float r2 = a2 * NS_GET_R(aFg); + float g2 = a2 * NS_GET_G(aFg); + float b2 = a2 * NS_GET_B(aFg); + + float a = p1 * a1 + p2 * a2; + if (a == 0.0) { + return NS_RGBA(0, 0, 0, 0); + } + + auto r = ClampColor((p1 * r1 + p2 * r2) / a); + auto g = ClampColor((p1 * g1 + p2 * g2) / a); + auto b = ClampColor((p1 * b1 + p2 * b2) / a); + return NS_RGBA(r, g, b, NSToIntRound(a * 255)); +} + +} // namespace mozilla + // Functions to convert from HSL color space to RGB color space. // This is the algorithm described in the CSS3 specification diff --git a/gfx/src/nsColor.h b/gfx/src/nsColor.h index 572f0d1fcf47..2f21c91bf2a8 100644 --- a/gfx/src/nsColor.h +++ b/gfx/src/nsColor.h @@ -9,6 +9,7 @@ #include // for size_t #include // for uint8_t, uint32_t #include "nscore.h" // for nsAString +#include "nsCoord.h" // for NSToIntRound class nsAString; class nsString; @@ -33,6 +34,22 @@ typedef uint32_t nscolor; #define NS_GET_B(_rgba) ((uint8_t) (((_rgba) >> 16) & 0xff)) #define NS_GET_A(_rgba) ((uint8_t) (((_rgba) >> 24) & 0xff)) +namespace mozilla { + +template +inline uint8_t ClampColor(T aColor) +{ + if (aColor >= 255) { + return 255; + } + if (aColor <= 0) { + return 0; + } + return NSToIntRound(aColor); +} + +} // namespace mozilla + // Fast approximate division by 255. It has the property that // for all 0 <= n <= 255*255, FAST_DIVIDE_BY_255(n) == n/255. // But it only uses two adds and two shifts instead of an @@ -60,6 +77,22 @@ NS_HexToRGBA(const nsAString& aBuf, nsHexColorType aType, nscolor* aResult); // you get if you draw aFG on top of aBG with operator OVER. nscolor NS_ComposeColors(nscolor aBG, nscolor aFG); +namespace mozilla { + +inline uint32_t RoundingDivideBy255(uint32_t n) +{ + // There is an approximate alternative: ((n << 8) + n + 32896) >> 16 + // But that is actually slower than this simple expression on a modern + // machine with a modern compiler. + return (n + 127) / 255; +} + +// Blend one RGBA color with another based on a given ratio. +// It is a linear interpolation on each channel with alpha premultipled. +nscolor LinearBlendColors(nscolor aBg, nscolor aFg, uint_fast8_t aFgRatio); + +} // namespace mozilla + // Translate a hex string to a color. Return true if it parses ok, // otherwise return false. // This version accepts 1 to 9 digits (missing digits are 0) diff --git a/gfx/tests/gtest/TestBSPTree.cpp b/gfx/tests/gtest/TestBSPTree.cpp index 4177057e1b84..cb88d54c23df 100644 --- a/gfx/tests/gtest/TestBSPTree.cpp +++ b/gfx/tests/gtest/TestBSPTree.cpp @@ -11,19 +11,23 @@ #include using mozilla::layers::BSPTree; +using mozilla::layers::LayerPolygon; using mozilla::gfx::Point3D; using mozilla::gfx::Polygon3D; -namespace -{ +namespace { // Compares two points while allowing some numerical inaccuracy. -static bool FuzzyCompare(const Point3D& lhs, const Point3D& rhs) +static bool FuzzyEquals(const Point3D& lhs, const Point3D& rhs) { const float epsilon = 0.001f; const Point3D d = lhs - rhs; - return (abs(d.x) > epsilon || abs(d.y) > epsilon || abs(d.z) > epsilon); + // The absolute difference between the points should be less than + // epsilon for every component. + return std::abs(d.x) < epsilon && + std::abs(d.y) < epsilon && + std::abs(d.z) < epsilon; } // Compares the points of two polygons and ensures @@ -44,7 +48,7 @@ static bool operator==(const Polygon3D& lhs, const Polygon3D& rhs) // This assumes that the polygons do not contain duplicate vertices. int start = -1; for (size_t i = 0; i < pointCount; ++i) { - if (FuzzyCompare(left[0], right[i])) { + if (FuzzyEquals(left[0], right[i])) { start = i; break; } @@ -59,7 +63,7 @@ static bool operator==(const Polygon3D& lhs, const Polygon3D& rhs) for (size_t i = 0; i < pointCount; ++i) { size_t j = (start + i) % pointCount; - if (!FuzzyCompare(left[i], right[j])) { + if (!FuzzyEquals(left[i], right[j])) { return false; } } @@ -70,16 +74,88 @@ static bool operator==(const Polygon3D& lhs, const Polygon3D& rhs) static void RunTest(std::deque aPolygons, std::deque aExpected) { - const BSPTree tree(aPolygons); - const nsTArray order = tree.GetDrawOrder(); + std::deque layers; + for (Polygon3D& polygon : aPolygons) { + layers.push_back(LayerPolygon(std::move(polygon), nullptr)); + } - EXPECT_EQ(order.Length(), aExpected.size()); + const BSPTree tree(layers); + const nsTArray order = tree.GetDrawOrder(); + + EXPECT_EQ(aExpected.size(), order.Length()); for (size_t i = 0; i < order.Length(); ++i) { - EXPECT_TRUE(order[i] == aExpected[i]); + EXPECT_TRUE(aExpected[i] == *order[i].geometry); } } +} // namespace + +TEST(BSPTree, TestSanity) +{ + EXPECT_TRUE(FuzzyEquals(Point3D(0.0f, 0.0f, 0.0f), + Point3D(0.0f, 0.0f, 0.0f))); + + EXPECT_TRUE(FuzzyEquals(Point3D(0.0f, 0.0f, 0.0f), + Point3D(0.00001f, 0.00001f, 0.00001f))); + + EXPECT_TRUE(FuzzyEquals(Point3D(0.00001f, 0.00001f, 0.00001f), + Point3D(0.0f, 0.0f, 0.0f))); + + EXPECT_FALSE(FuzzyEquals(Point3D(0.0f, 0.0f, 0.0f), + Point3D(0.01f, 0.01f, 0.01f))); + + EXPECT_FALSE(FuzzyEquals(Point3D(0.01f, 0.01f, 0.01f), + Point3D(0.0f, 0.0f, 0.0f))); + + Polygon3D p1 { + Point3D(0.0f, 0.0f, 1.0f), + Point3D(1.0f, 0.0f, 1.0f), + Point3D(1.0f, 1.0f, 1.0f), + Point3D(0.0f, 1.0f, 1.0f) + }; + + // Same points as above shifted forward by one position. + Polygon3D shifted { + Point3D(0.0f, 1.0f, 1.0f), + Point3D(0.0f, 0.0f, 1.0f), + Point3D(1.0f, 0.0f, 1.0f), + Point3D(1.0f, 1.0f, 1.0f) + }; + + Polygon3D p2 { + Point3D(0.00001f, 0.00001f, 1.00001f), + Point3D(1.00001f, 0.00001f, 1.00001f), + Point3D(1.00001f, 1.00001f, 1.00001f), + Point3D(0.00001f, 1.00001f, 1.00001f) + }; + + Polygon3D p3 { + Point3D(0.01f, 0.01f, 1.01f), + Point3D(1.01f, 0.01f, 1.01f), + Point3D(1.01f, 1.01f, 1.01f), + Point3D(0.01f, 1.01f, 1.01f) + }; + + // Trivial equals + EXPECT_TRUE(p1 == p1); + EXPECT_TRUE(p2 == p2); + EXPECT_TRUE(p3 == p3); + EXPECT_TRUE(shifted == shifted); + + // Polygons with the same point order + EXPECT_TRUE(p1 == p2); + EXPECT_TRUE(p1 == shifted); + + // Polygons containing different points + EXPECT_FALSE(p1 == p3); + EXPECT_FALSE(p2 == p3); + EXPECT_FALSE(shifted == p3); + + ::RunTest({p1}, {p1}); + ::RunTest({p2}, {p2}); + ::RunTest({p1}, {p2}); + ::RunTest({p1}, {shifted}); } TEST(BSPTree, SameNode) @@ -118,8 +194,8 @@ TEST(BSPTree, OneChild) Point3D(0.0f, 1.0f, 1.0f) }; - ::RunTest(std::deque {p1, p2}, {p1, p2}); - ::RunTest(std::deque {p2, p1}, {p1, p2}); + ::RunTest({p1, p2}, {p1, p2}); + ::RunTest({p2, p1}, {p1, p2}); } TEST(BSPTree, SplitSimple1) @@ -274,114 +350,6 @@ TEST(BSPTree, NoSplit2) { ::RunTest(polygons, expected); } -TEST(BSPTree, SplitComplex1) { - const std::deque polygons { - Polygon3D { - Point3D(0.00000f, -5.00000f, -15.00000f), - Point3D(0.00000f, 5.00000f, -15.00000f), - Point3D(0.00000f, 5.00000f, -10.00000f), - Point3D(0.00000f, -5.00000f, -10.00000f) - }, - Polygon3D { - Point3D(-5.00000f, -5.00000f, 0.00000f), - Point3D(-5.00000f, 5.00000f, 0.00000f), - Point3D(5.00000f, 5.00000f, 0.00000f), - Point3D(5.00000f, -5.00000f, 0.00000f) - } - }; - - const std::deque expected { - Polygon3D { - Point3D(0.00000f, 5.00000f, 0.00000f), - Point3D(5.00000f, 5.00000f, 0.00000f), - Point3D(5.00000f, -5.00000f, 0.00000f), - Point3D(0.00000f, -5.00000f, 0.00000f) - }, - Polygon3D { - Point3D(0.00000f, -5.00000f, -15.00000f), - Point3D(0.00000f, 5.00000f, -15.00000f), - Point3D(0.00000f, 5.00000f, -10.00000f), - Point3D(0.00000f, -5.00000f, -10.00000f) - }, - Polygon3D { - Point3D(0.00000f, -5.00000f, 0.00000f), - Point3D(-5.00000f, -5.00000f, 0.00000f), - Point3D(-5.00000f, 5.00000f, 0.00000f), - Point3D(0.00000f, 5.00000f, 0.00000f) - } - }; - ::RunTest(polygons, expected); -} - -TEST(BSPTree, SplitComplex2) { - const std::deque polygons { - Polygon3D { - Point3D(-5.00000f, -5.00000f, 0.00000f), - Point3D(-5.00000f, 5.00000f, 0.00000f), - Point3D(5.00000f, 5.00000f, 0.00000f), - Point3D(5.00000f, -5.00000f, 0.00000f) - }, - Polygon3D { - Point3D(0.00000f, -5.00000f, -5.00000f), - Point3D(0.00000f, 5.00000f, -5.00000f), - Point3D(0.00000f, 5.00000f, 5.00000f), - Point3D(0.00000f, -5.00000f, 5.00000f) - }, - Polygon3D { - Point3D(-5.00000f, 0.00000f, -5.00000f), - Point3D(-5.00000f, 0.00000f, 5.00000f), - Point3D(5.00000f, 0.00000f, 5.00000f), - Point3D(5.00000f, 0.00000f, -5.00000f) - } - }; - - const std::deque expected { - Polygon3D { - Point3D(0.00000f, 0.00000f, 0.00000f), - Point3D(5.00000f, 0.00000f, 0.00000f), - Point3D(5.00000f, 0.00000f, -5.00000f), - Point3D(0.00000f, 0.00000f, -5.00000f) - }, - Polygon3D { - Point3D(0.00000f, -5.00000f, 0.00000f), - Point3D(0.00000f, -5.00000f, -5.00000f), - Point3D(0.00000f, 5.00000f, -5.00000f), - Point3D(0.00000f, 5.00000f, 0.00000f) - }, - Polygon3D { - Point3D(0.00000f, 0.00000f, -5.00000f), - Point3D(-5.00000f, 0.00000f, -5.00000f), - Point3D(-5.00000f, 0.00000f, 0.00000f), - Point3D(0.00000f, 0.00000f, 0.00000f) - }, - Polygon3D { - Point3D(-5.00000f, -5.00000f, 0.00000f), - Point3D(-5.00000f, 5.00000f, 0.00000f), - Point3D(5.00000f, 5.00000f, 0.00000f), - Point3D(5.00000f, -5.00000f, 0.00000f) - }, - Polygon3D { - Point3D(0.00000f, 0.00000f, 5.00000f), - Point3D(5.00000f, 0.00000f, 5.00000f), - Point3D(5.00000f, 0.00000f, 0.00000f), - Point3D(0.00000f, 0.00000f, 0.00000f) - }, - Polygon3D { - Point3D(0.00000f, 5.00000f, 0.00000f), - Point3D(0.00000f, 5.00000f, 5.00000f), - Point3D(0.00000f, -5.00000f, 5.00000f), - Point3D(0.00000f, -5.00000f, 0.00000f) - }, - Polygon3D { - Point3D(0.00000f, 0.00000f, 0.00000f), - Point3D(-5.00000f, 0.00000f, 0.00000f), - Point3D(-5.00000f, 0.00000f, 5.00000f), - Point3D(0.00000f, 0.00000f, 5.00000f) - } - }; - ::RunTest(polygons, expected); -} - TEST(BSPTree, TwoPlaneIntersectRotate0degrees) { const std::deque polygons { Polygon3D { @@ -400,22 +368,16 @@ TEST(BSPTree, TwoPlaneIntersectRotate0degrees) { const std::deque expected { Polygon3D { - Point3D(0.00010f, 0.00000f, -2.00000f), + Point3D(2.00000f, 0.00000f, 2.00000f), + Point3D(2.00000f, -0.00000f, -2.00000f), Point3D(-2.00000f, 0.00000f, -2.00000f), - Point3D(-2.00000f, 0.00010f, 2.00000f), - Point3D(0.00000f, 0.00005f, 2.00000f) + Point3D(-2.00000f, 0.00010f, 2.00000f) }, Polygon3D { Point3D(-0.00000f, 2.00000f, 2.00000f), Point3D(-0.00000f, -2.00000f, 2.00000f), Point3D(0.00010f, -2.00000f, -2.00000f), Point3D(0.00010f, 2.00000f, -2.00000f) - }, - Polygon3D { - Point3D(0.00000f, 0.00005f, 2.00000f), - Point3D(2.00000f, 0.00000f, 2.00000f), - Point3D(2.00000f, -0.00000f, -2.00000f), - Point3D(0.00010f, 0.00000f, -2.00000f) } }; ::RunTest(polygons, expected); @@ -439,22 +401,16 @@ TEST(BSPTree, TwoPlaneIntersectRotate20degrees) { const std::deque expected { Polygon3D { - Point3D(0.00010f, 0.68410f, -1.87930f), + Point3D(2.00000f, -0.68400f, 1.87940f), + Point3D(2.00000f, 0.68410f, -1.87930f), Point3D(-2.00000f, 0.68410f, -1.87930f), - Point3D(-2.00000f, -0.68400f, 1.87940f), - Point3D(0.00000f, -0.68400f, 1.87940f) + Point3D(-2.00000f, -0.68400f, 1.87940f) }, Polygon3D { Point3D(-0.00000f, 1.19540f, 2.56350f), Point3D(-0.00000f, -2.56340f, 1.19540f), Point3D(0.00010f, -1.19530f, -2.56340f), Point3D(0.00010f, 2.56350f, -1.19530f) - }, - Polygon3D { - Point3D(0.00000f, -0.68400f, 1.87940f), - Point3D(2.00000f, -0.68400f, 1.87940f), - Point3D(2.00000f, 0.68410f, -1.87930f), - Point3D(0.00010f, 0.68410f, -1.87930f) } }; ::RunTest(polygons, expected); @@ -478,22 +434,16 @@ TEST(BSPTree, TwoPlaneIntersectRotate40degrees) { const std::deque expected { Polygon3D { - Point3D(0.00010f, 1.73210f, -0.99990f), + Point3D(2.00000f, -1.73200f, 1.00000f), + Point3D(2.00000f, 1.73210f, -0.99990f), Point3D(-2.00000f, 1.73210f, -0.99990f), - Point3D(-2.00000f, -1.73200f, 1.00000f), - Point3D(0.00000f, -1.73200f, 1.00000f) + Point3D(-2.00000f, -1.73200f, 1.00000f) }, Polygon3D { Point3D(-0.00000f, -0.73200f, 2.73210f), Point3D(-0.00000f, -2.73200f, -0.73200f), Point3D(0.00010f, 0.73210f, -2.73200f), Point3D(0.00010f, 2.73210f, 0.73210f) - }, - Polygon3D { - Point3D(0.00000f, -1.73200f, 1.00000f), - Point3D(2.00000f, -1.73200f, 1.00000f), - Point3D(2.00000f, 1.73210f, -0.99990f), - Point3D(0.00010f, 1.73210f, -0.99990f) } }; ::RunTest(polygons, expected); @@ -517,10 +467,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate60degrees) { const std::deque expected { Polygon3D { - Point3D(0.00000f, -1.73200f, -1.00000f), + Point3D(-2.00000f, 1.26793f, 0.73210f), + Point3D(-2.00000f, -1.73200f, -1.00000f), Point3D(2.00000f, -1.73200f, -1.00000f), - Point3D(2.00000f, 1.73210f, 1.00010f), - Point3D(0.00010f, 1.73210f, 1.00010f) + Point3D(2.00000f, 1.26793f, 0.73210f) }, Polygon3D { Point3D(-0.00000f, -2.73200f, 0.73210f), @@ -529,10 +479,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate60degrees) { Point3D(0.00010f, 0.73210f, 2.73210f) }, Polygon3D { - Point3D(0.00010f, 1.73210f, 1.00010f), + Point3D(2.00000f, 1.26793f, 0.73210f), + Point3D(2.00000f, 1.73210f, 1.00010f), Point3D(-2.00000f, 1.73210f, 1.00010f), - Point3D(-2.00000f, -1.73200f, -1.00000f), - Point3D(0.00000f, -1.73200f, -1.00000f) + Point3D(-2.00000f, 1.26793f, 0.73210f) } }; ::RunTest(polygons, expected); @@ -555,12 +505,6 @@ TEST(BSPTree, TwoPlaneIntersectRotate80degrees) { }; const std::deque expected { - Polygon3D { - Point3D(0.00000f, 0.68410f, -1.87930f), - Point3D(2.00000f, 0.68410f, -1.87930f), - Point3D(2.00000f, -0.68400f, 1.87940f), - Point3D(0.00010f, -0.68400f, 1.87940f) - }, Polygon3D { Point3D(-0.00000f, -1.19530f, -2.56340f), Point3D(-0.00000f, 2.56350f, -1.19530f), @@ -568,10 +512,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate80degrees) { Point3D(0.00010f, -2.56340f, 1.19540f) }, Polygon3D { - Point3D(0.00010f, -0.68400f, 1.87940f), + Point3D(2.00000f, 0.68410f, -1.87930f), + Point3D(2.00000f, -0.68400f, 1.87940f), Point3D(-2.00000f, -0.68400f, 1.87940f), - Point3D(-2.00000f, 0.68410f, -1.87930f), - Point3D(0.00000f, 0.68410f, -1.87930f) + Point3D(-2.00000f, 0.68410f, -1.87930f) } }; ::RunTest(polygons, expected); @@ -595,10 +539,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate100degrees) { const std::deque expected { Polygon3D { - Point3D(0.00010f, -1.73200f, -1.00000f), + Point3D(2.00000f, -1.26783f, -0.73200f), + Point3D(2.00000f, -1.73200f, -1.00000f), Point3D(-2.00000f, -1.73200f, -1.00000f), - Point3D(-2.00000f, 1.73210f, 1.00010f), - Point3D(0.00000f, 1.73210f, 1.00010f) + Point3D(-2.00000f, -1.26783f, -0.73200f) }, Polygon3D { Point3D(-0.00000f, 2.73210f, -0.73200f), @@ -607,10 +551,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate100degrees) { Point3D(0.00010f, -0.73200f, -2.73200f) }, Polygon3D { - Point3D(0.00000f, 1.73210f, 1.00010f), + Point3D(-2.00000f, -1.26783f, -0.73200f), + Point3D(-2.00000f, 1.73210f, 1.00010f), Point3D(2.00000f, 1.73210f, 1.00010f), - Point3D(2.00000f, -1.73200f, -1.00000f), - Point3D(0.00010f, -1.73200f, -1.00000f) + Point3D(2.00000f, -1.26783f, -0.73200f) } }; ::RunTest(polygons, expected); @@ -634,22 +578,16 @@ TEST(BSPTree, TwoPlaneIntersectRotate120degrees) { const std::deque expected { Polygon3D { - Point3D(0.00010f, 1.73210f, -0.99990f), + Point3D(2.00000f, -1.73200f, 1.00000f), + Point3D(2.00000f, 1.73210f, -0.99990f), Point3D(-2.00000f, 1.73210f, -0.99990f), - Point3D(-2.00000f, -1.73200f, 1.00000f), - Point3D(0.00000f, -1.73200f, 1.00000f) + Point3D(-2.00000f, -1.73200f, 1.00000f) }, Polygon3D { Point3D(-0.00000f, -0.73200f, 2.73210f), Point3D(-0.00000f, -2.73200f, -0.73200f), Point3D(0.00010f, 0.73210f, -2.73200f), Point3D(0.00010f, 2.73210f, 0.73210f) - }, - Polygon3D { - Point3D(0.00000f, -1.73200f, 1.00000f), - Point3D(2.00000f, -1.73200f, 1.00000f), - Point3D(2.00000f, 1.73210f, -0.99990f), - Point3D(0.00010f, 1.73210f, -0.99990f) } }; ::RunTest(polygons, expected); @@ -672,12 +610,6 @@ TEST(BSPTree, TwoPlaneIntersectRotate140degrees) { }; const std::deque expected { - Polygon3D { - Point3D(0.00000f, 0.68410f, -1.87930f), - Point3D(2.00000f, 0.68410f, -1.87930f), - Point3D(2.00000f, -0.68400f, 1.87940f), - Point3D(0.00010f, -0.68400f, 1.87940f) - }, Polygon3D { Point3D(-0.00000f, -1.19530f, -2.56340f), Point3D(-0.00000f, 2.56350f, -1.19530f), @@ -685,10 +617,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate140degrees) { Point3D(0.00010f, -2.56340f, 1.19540f) }, Polygon3D { - Point3D(0.00010f, -0.68400f, 1.87940f), + Point3D(2.00000f, 0.68410f, -1.87930f), + Point3D(2.00000f, -0.68400f, 1.87940f), Point3D(-2.00000f, -0.68400f, 1.87940f), - Point3D(-2.00000f, 0.68410f, -1.87930f), - Point3D(0.00000f, 0.68410f, -1.87930f) + Point3D(-2.00000f, 0.68410f, -1.87930f) } }; ::RunTest(polygons, expected); @@ -712,22 +644,16 @@ TEST(BSPTree, TwoPlaneIntersectRotate160degrees) { const std::deque expected { Polygon3D { - Point3D(0.00010f, 0.00010f, -2.00000f), + Point3D(2.00000f, -0.00000f, 2.00000f), + Point3D(2.00000f, 0.00010f, -2.00000f), Point3D(-2.00000f, 0.00010f, -2.00000f), - Point3D(-2.00000f, -0.00000f, 2.00000f), - Point3D(0.00000f, 0.00000f, 2.00000f) + Point3D(-2.00000f, -0.00000f, 2.00000f) }, Polygon3D { Point3D(-0.00000f, 2.00000f, 2.00000f), Point3D(-0.00000f, -2.00000f, 2.00000f), Point3D(0.00010f, -2.00000f, -2.00000f), Point3D(0.00010f, 2.00000f, -2.00000f) - }, - Polygon3D { - Point3D(0.00000f, 0.00000f, 2.00000f), - Point3D(2.00000f, -0.00000f, 2.00000f), - Point3D(2.00000f, 0.00010f, -2.00000f), - Point3D(0.00010f, 0.00010f, -2.00000f) } }; ::RunTest(polygons, expected); @@ -750,12 +676,6 @@ TEST(BSPTree, TwoPlaneIntersectRotate180degrees) { }; const std::deque expected { - Polygon3D { - Point3D(0.00000f, 0.00010f, -2.00000f), - Point3D(2.00000f, 0.00010f, -2.00000f), - Point3D(2.00000f, -0.00000f, 2.00000f), - Point3D(0.00010f, 0.00000f, 2.00000f) - }, Polygon3D { Point3D(-0.00000f, -2.00000f, -2.00000f), Point3D(-0.00000f, 2.00000f, -2.00000f), @@ -763,10 +683,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate180degrees) { Point3D(0.00010f, -2.00000f, 2.00000f) }, Polygon3D { - Point3D(0.00010f, 0.00000f, 2.00000f), + Point3D(2.00000f, 0.00010f, -2.00000f), + Point3D(2.00000f, -0.00000f, 2.00000f), Point3D(-2.00000f, -0.00000f, 2.00000f), - Point3D(-2.00000f, 0.00010f, -2.00000f), - Point3D(0.00000f, 0.00010f, -2.00000f) + Point3D(-2.00000f, 0.00010f, -2.00000f) } }; ::RunTest(polygons, expected); @@ -790,22 +710,16 @@ TEST(BSPTree, TwoPlaneIntersectRotate200degrees) { const std::deque expected { Polygon3D { - Point3D(0.00010f, 0.68410f, -1.87930f), + Point3D(2.00000f, -0.68400f, 1.87940f), + Point3D(2.00000f, 0.68410f, -1.87930f), Point3D(-2.00000f, 0.68410f, -1.87930f), - Point3D(-2.00000f, -0.68400f, 1.87940f), - Point3D(0.00000f, -0.68400f, 1.87940f) + Point3D(-2.00000f, -0.68400f, 1.87940f) }, Polygon3D { Point3D(-0.00000f, 1.19540f, 2.56350f), Point3D(-0.00000f, -2.56340f, 1.19540f), Point3D(0.00010f, -1.19530f, -2.56340f), Point3D(0.00010f, 2.56350f, -1.19530f) - }, - Polygon3D { - Point3D(0.00000f, -0.68400f, 1.87940f), - Point3D(2.00000f, -0.68400f, 1.87940f), - Point3D(2.00000f, 0.68410f, -1.87930f), - Point3D(0.00010f, 0.68410f, -1.87930f) } }; ::RunTest(polygons, expected); @@ -828,12 +742,6 @@ TEST(BSPTree, TwoPlaneIntersectRotate220degrees) { }; const std::deque expected { - Polygon3D { - Point3D(0.00000f, 1.73210f, -0.99990f), - Point3D(2.00000f, 1.73210f, -0.99990f), - Point3D(2.00000f, -1.73200f, 1.00000f), - Point3D(0.00010f, -1.73200f, 1.00000f) - }, Polygon3D { Point3D(-0.00000f, 0.73210f, -2.73200f), Point3D(-0.00000f, 2.73210f, 0.73210f), @@ -841,10 +749,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate220degrees) { Point3D(0.00010f, -2.73200f, -0.73200f) }, Polygon3D { - Point3D(0.00010f, -1.73200f, 1.00000f), + Point3D(2.00000f, 1.73210f, -0.99990f), + Point3D(2.00000f, -1.73200f, 1.00000f), Point3D(-2.00000f, -1.73200f, 1.00000f), - Point3D(-2.00000f, 1.73210f, -0.99990f), - Point3D(0.00000f, 1.73210f, -0.99990f) + Point3D(-2.00000f, 1.73210f, -0.99990f) } }; ::RunTest(polygons, expected); @@ -868,10 +776,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate240degrees) { const std::deque expected { Polygon3D { - Point3D(0.00000f, -1.73200f, -1.00000f), + Point3D(-2.00000f, 1.26793f, 0.73210f), + Point3D(-2.00000f, -1.73200f, -1.00000f), Point3D(2.00000f, -1.73200f, -1.00000f), - Point3D(2.00000f, 1.73210f, 1.00010f), - Point3D(0.00010f, 1.73210f, 1.00010f) + Point3D(2.00000f, 1.26793f, 0.73210f) }, Polygon3D { Point3D(-0.00000f, -2.73200f, 0.73210f), @@ -880,10 +788,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate240degrees) { Point3D(0.00010f, 0.73210f, 2.73210f) }, Polygon3D { - Point3D(0.00010f, 1.73210f, 1.00010f), + Point3D(2.00000f, 1.26793f, 0.73210f), + Point3D(2.00000f, 1.73210f, 1.00010f), Point3D(-2.00000f, 1.73210f, 1.00010f), - Point3D(-2.00000f, -1.73200f, -1.00000f), - Point3D(0.00000f, -1.73200f, -1.00000f) + Point3D(-2.00000f, 1.26793f, 0.73210f) } }; ::RunTest(polygons, expected); @@ -907,22 +815,16 @@ TEST(BSPTree, TwoPlaneIntersectRotate260degrees) { const std::deque expected { Polygon3D { - Point3D(0.00010f, 0.68410f, -1.87930f), + Point3D(2.00000f, -0.68400f, 1.87940f), + Point3D(2.00000f, 0.68410f, -1.87930f), Point3D(-2.00000f, 0.68410f, -1.87930f), - Point3D(-2.00000f, -0.68400f, 1.87940f), - Point3D(0.00000f, -0.68400f, 1.87940f) + Point3D(-2.00000f, -0.68400f, 1.87940f) }, Polygon3D { Point3D(-0.00000f, 1.19540f, 2.56350f), Point3D(-0.00000f, -2.56340f, 1.19540f), Point3D(0.00010f, -1.19530f, -2.56340f), Point3D(0.00010f, 2.56350f, -1.19530f) - }, - Polygon3D { - Point3D(0.00000f, -0.68400f, 1.87940f), - Point3D(2.00000f, -0.68400f, 1.87940f), - Point3D(2.00000f, 0.68410f, -1.87930f), - Point3D(0.00010f, 0.68410f, -1.87930f) } }; ::RunTest(polygons, expected); @@ -946,10 +848,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate280degrees) { const std::deque expected { Polygon3D { - Point3D(0.00010f, -1.73200f, -1.00000f), + Point3D(2.00000f, -1.26783f, -0.73200f), + Point3D(2.00000f, -1.73200f, -1.00000f), Point3D(-2.00000f, -1.73200f, -1.00000f), - Point3D(-2.00000f, 1.73210f, 1.00010f), - Point3D(0.00000f, 1.73210f, 1.00010f) + Point3D(-2.00000f, -1.26783f, -0.73200f) }, Polygon3D { Point3D(-0.00000f, 2.73210f, -0.73200f), @@ -958,10 +860,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate280degrees) { Point3D(0.00010f, -0.73200f, -2.73200f) }, Polygon3D { - Point3D(0.00000f, 1.73210f, 1.00010f), + Point3D(-2.00000f, -1.26783f, -0.73200f), + Point3D(-2.00000f, 1.73210f, 1.00010f), Point3D(2.00000f, 1.73210f, 1.00010f), - Point3D(2.00000f, -1.73200f, -1.00000f), - Point3D(0.00010f, -1.73200f, -1.00000f) + Point3D(2.00000f, -1.26783f, -0.73200f) } }; ::RunTest(polygons, expected); @@ -984,12 +886,6 @@ TEST(BSPTree, TwoPlaneIntersectRotate300degrees) { }; const std::deque expected { - Polygon3D { - Point3D(0.00000f, 1.73210f, -0.99990f), - Point3D(2.00000f, 1.73210f, -0.99990f), - Point3D(2.00000f, -1.73200f, 1.00000f), - Point3D(0.00010f, -1.73200f, 1.00000f) - }, Polygon3D { Point3D(-0.00000f, 0.73210f, -2.73200f), Point3D(-0.00000f, 2.73210f, 0.73210f), @@ -997,10 +893,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate300degrees) { Point3D(0.00010f, -2.73200f, -0.73200f) }, Polygon3D { - Point3D(0.00010f, -1.73200f, 1.00000f), + Point3D(2.00000f, 1.73210f, -0.99990f), + Point3D(2.00000f, -1.73200f, 1.00000f), Point3D(-2.00000f, -1.73200f, 1.00000f), - Point3D(-2.00000f, 1.73210f, -0.99990f), - Point3D(0.00000f, 1.73210f, -0.99990f) + Point3D(-2.00000f, 1.73210f, -0.99990f) } }; ::RunTest(polygons, expected); @@ -1023,12 +919,6 @@ TEST(BSPTree, TwoPlaneIntersectRotate320degrees) { }; const std::deque expected { - Polygon3D { - Point3D(0.00000f, 0.68410f, -1.87930f), - Point3D(2.00000f, 0.68410f, -1.87930f), - Point3D(2.00000f, -0.68400f, 1.87940f), - Point3D(0.00010f, -0.68400f, 1.87940f) - }, Polygon3D { Point3D(-0.00000f, -1.19530f, -2.56340f), Point3D(-0.00000f, 2.56350f, -1.19530f), @@ -1036,10 +926,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate320degrees) { Point3D(0.00010f, -2.56340f, 1.19540f) }, Polygon3D { - Point3D(0.00010f, -0.68400f, 1.87940f), + Point3D(2.00000f, 0.68410f, -1.87930f), + Point3D(2.00000f, -0.68400f, 1.87940f), Point3D(-2.00000f, -0.68400f, 1.87940f), - Point3D(-2.00000f, 0.68410f, -1.87930f), - Point3D(0.00000f, 0.68410f, -1.87930f) + Point3D(-2.00000f, 0.68410f, -1.87930f) } }; ::RunTest(polygons, expected); @@ -1062,12 +952,6 @@ TEST(BSPTree, TwoPlaneIntersectRotate340degrees) { }; const std::deque expected { - Polygon3D { - Point3D(0.00000f, 0.00010f, -2.00000f), - Point3D(2.00000f, 0.00010f, -2.00000f), - Point3D(2.00000f, -0.00000f, 2.00000f), - Point3D(0.00010f, 0.00000f, 2.00000f) - }, Polygon3D { Point3D(-0.00000f, -2.00000f, -2.00000f), Point3D(-0.00000f, 2.00000f, -2.00000f), @@ -1075,10 +959,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate340degrees) { Point3D(0.00010f, -2.00000f, 2.00000f) }, Polygon3D { - Point3D(0.00010f, 0.00000f, 2.00000f), + Point3D(2.00000f, 0.00010f, -2.00000f), + Point3D(2.00000f, -0.00000f, 2.00000f), Point3D(-2.00000f, -0.00000f, 2.00000f), - Point3D(-2.00000f, 0.00010f, -2.00000f), - Point3D(0.00000f, 0.00010f, -2.00000f) + Point3D(-2.00000f, 0.00010f, -2.00000f) } }; ::RunTest(polygons, expected); @@ -1101,12 +985,6 @@ TEST(BSPTree, TwoPlaneIntersectRotate360degrees) { }; const std::deque expected { - Polygon3D { - Point3D(0.00000f, 0.00010f, -2.00000f), - Point3D(2.00000f, 0.00010f, -2.00000f), - Point3D(2.00000f, -0.00000f, 2.00000f), - Point3D(0.00010f, 0.00000f, 2.00000f) - }, Polygon3D { Point3D(-0.00000f, -2.00000f, -2.00000f), Point3D(-0.00000f, 2.00000f, -2.00000f), @@ -1114,10 +992,10 @@ TEST(BSPTree, TwoPlaneIntersectRotate360degrees) { Point3D(0.00010f, -2.00000f, 2.00000f) }, Polygon3D { - Point3D(0.00010f, 0.00000f, 2.00000f), + Point3D(2.00000f, 0.00010f, -2.00000f), + Point3D(2.00000f, -0.00000f, 2.00000f), Point3D(-2.00000f, -0.00000f, 2.00000f), - Point3D(-2.00000f, 0.00010f, -2.00000f), - Point3D(0.00000f, 0.00010f, -2.00000f) + Point3D(-2.00000f, 0.00010f, -2.00000f) } }; ::RunTest(polygons, expected); diff --git a/js/src/doc/Debugger/Debugger.Source.md b/js/src/doc/Debugger/Debugger.Source.md index 64e5af73e588..0c62c60f8149 100644 --- a/js/src/doc/Debugger/Debugger.Source.md +++ b/js/src/doc/Debugger/Debugger.Source.md @@ -67,21 +67,6 @@ differ, no such emphasized headings will appear. A `Debugger.Source` instance inherits the following accessor properties from its prototype: -`canonicalId` -: **If the instance refers to JavaScript source**, a stable, unique - identifier for the source referent. This identifier is suitable for - checking if two `Debugger.Source` instances originating from different - `Debugger` instances refer to the same source that was compiled by - SpiderMonkey. The `canonicalId` is reliable even when the source does not - have a URL, or shares the same URL as another source but has different - source text. It is more efficient to compare `canonicalId`s than to - compare source text character-by-character. The `canonicalId` is not - suitable for ordering comparisons such as "greater than" or "less - than". It is not suitable for checking the equality of sources across - worker threads. - - **If the instance refers to WebAssembly code**, throw a `TypeError`. - `text` : **If the instance refers to JavaScript source**, the JavaScript source code, as a string. The value satisfies the `Program`, diff --git a/js/src/jit-test/tests/debug/Source-canonicalId.js b/js/src/jit-test/tests/debug/Source-canonicalId.js deleted file mode 100644 index 2d9b46bf96c7..000000000000 --- a/js/src/jit-test/tests/debug/Source-canonicalId.js +++ /dev/null @@ -1,32 +0,0 @@ -// Test Debugger.Source.prototype.canonicalId - -const g = newGlobal(); - -const dbg1 = new Debugger; -const dbg2 = new Debugger; - -const gw1 = dbg1.addDebuggee(g); -const gw2 = dbg2.addDebuggee(g); - -g.eval("function f(x) { return 2*x; }"); -g.eval("function g(x) { return 2+x; }"); - -const fw1 = gw1.getOwnPropertyDescriptor('f').value; -const fw2 = gw2.getOwnPropertyDescriptor('f').value; -const hw1 = gw1.getOwnPropertyDescriptor('g').value; -const hw2 = gw2.getOwnPropertyDescriptor('g').value; - -const fs1 = fw1.script.source; -const fs2 = fw2.script.source; -const gs1 = hw1.script.source; -const gs2 = hw2.script.source; - -assertEq(!!fs1, true); -assertEq(!!fs2, true); -assertEq(fs1.canonicalId, fs2.canonicalId); - -assertEq(!!gs1, true); -assertEq(!!gs2, true); -assertEq(gs1.canonicalId, gs2.canonicalId); - -assertEq(fs1.canonicalId !== gs1.canonicalId, true); diff --git a/js/src/jit-test/tests/debug/wasm-03.js b/js/src/jit-test/tests/debug/wasm-03.js index 0bc9922e5193..f10812e61f5a 100644 --- a/js/src/jit-test/tests/debug/wasm-03.js +++ b/js/src/jit-test/tests/debug/wasm-03.js @@ -34,7 +34,3 @@ source.element; source.displayURL; source.introductionOffset; source.elementAttributeName; - -// canonicalId doesn't make sense since wasm sources aren't backed by -// ScriptSource. -assertThrowsInstanceOf(() => source.canonicalId, Error); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index c66b8a6f10d8..ff29502984de 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -7149,31 +7149,6 @@ DebuggerSource_getSourceMapURL(JSContext* cx, unsigned argc, Value* vp) return true; } -static bool -DebuggerSource_getCanonicalId(JSContext* cx, unsigned argc, Value* vp) -{ - THIS_DEBUGSOURCE_SOURCE(cx, argc, vp, "(get sourceMapURL)", args, obj, sourceObject); - - ScriptSource* ss = sourceObject->source(); - MOZ_ASSERT(ss); - - static_assert(!mozilla::IsBaseOf::value, - "We rely on ScriptSource* pointers to be stable, and not move in memory. " - "Currently, this holds true because ScriptSource is not managed by the GC. If " - "that changes, it doesn't necessarily mean that it will start moving, but we " - "will need a new assertion here. If we do start moving ScriptSources in memory, " - "then DebuggerSource_getCanonicalId will need to be reworked!"); - auto id = uintptr_t(ss); - - // IEEE 754 doubles can precisely store integers of up 53 bits. On 32 bit - // platforms, pointers trivially fit. On 64 bit platforms, pointers only use - // 48 bits so we are still good. - MOZ_ASSERT(Value::isNumberRepresentable(id)); - - args.rval().set(NumberValue(id)); - return true; -} - static const JSPropertySpec DebuggerSource_properties[] = { JS_PSG("text", DebuggerSource_getText, 0), JS_PSG("url", DebuggerSource_getURL, 0), @@ -7184,7 +7159,6 @@ static const JSPropertySpec DebuggerSource_properties[] = { JS_PSG("introductionType", DebuggerSource_getIntroductionType, 0), JS_PSG("elementAttributeName", DebuggerSource_getElementProperty, 0), JS_PSGS("sourceMapURL", DebuggerSource_getSourceMapURL, DebuggerSource_setSourceMapURL, 0), - JS_PSG("canonicalId", DebuggerSource_getCanonicalId, 0), JS_PS_END }; diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index aa282ac5d748..2130b158c697 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -602,13 +602,8 @@ bool XPCJSContext::UsefulToMergeZones() const void XPCJSContext::TraceNativeBlackRoots(JSTracer* trc) { - // Skip this part if XPConnect is shutting down. We get into - // bad locking problems with the thread iteration otherwise. - if (!nsXPConnect::XPConnect()->IsShuttingDown()) { - // Trace those AutoMarkingPtr lists! - if (AutoMarkingPtr* roots = Get()->mAutoRoots) - roots->TraceJSAll(trc); - } + if (AutoMarkingPtr* roots = Get()->mAutoRoots) + roots->TraceJSAll(trc); // XPCJSObjectHolders don't participate in cycle collection, so always // trace them here. @@ -784,14 +779,8 @@ XPCJSContext::FinalizeCallback(JSFreeOp* fop, MOZ_ASSERT(!self->mGCIsRunning, "bad state"); self->mGCIsRunning = true; - // Skip this part if XPConnect is shutting down. We get into - // bad locking problems with the thread iteration otherwise. - if (!nsXPConnect::XPConnect()->IsShuttingDown()) { - - // Mark those AutoMarkingPtr lists! - if (AutoMarkingPtr* roots = Get()->mAutoRoots) - roots->MarkAfterJSFinalizeAll(); - } + if (AutoMarkingPtr* roots = Get()->mAutoRoots) + roots->MarkAfterJSFinalizeAll(); // Now we are going to recycle any unused WrappedNativeTearoffs. // We do this by iterating all the live callcontexts @@ -805,30 +794,23 @@ XPCJSContext::FinalizeCallback(JSFreeOp* fop, // // XXX We may decide to not do this on *every* gc cycle. - // Skip this part if XPConnect is shutting down. We get into - // bad locking problems with the thread iteration otherwise. - if (!nsXPConnect::XPConnect()->IsShuttingDown()) { - // Do the marking... - - XPCCallContext* ccxp = XPCJSContext::Get()->GetCallContext(); - while (ccxp) { - // Deal with the strictness of callcontext that - // complains if you ask for a tearoff when - // it is in a state where the tearoff could not - // possibly be valid. - if (ccxp->CanGetTearOff()) { - XPCWrappedNativeTearOff* to = - ccxp->GetTearOff(); - if (to) - to->Mark(); - } - ccxp = ccxp->GetPrevCallContext(); + XPCCallContext* ccxp = XPCJSContext::Get()->GetCallContext(); + while (ccxp) { + // Deal with the strictness of callcontext that + // complains if you ask for a tearoff when + // it is in a state where the tearoff could not + // possibly be valid. + if (ccxp->CanGetTearOff()) { + XPCWrappedNativeTearOff* to = + ccxp->GetTearOff(); + if (to) + to->Mark(); } - - // Do the sweeping... - XPCWrappedNativeScope::SweepAllWrappedNativeTearOffs(); + ccxp = ccxp->GetPrevCallContext(); } + XPCWrappedNativeScope::SweepAllWrappedNativeTearOffs(); + // Now we need to kill the 'Dying' XPCWrappedNativeProtos. // We transfered these native objects to this table when their // JSObject's were finalized. We did not destroy them immediately diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp index 5b52e0f75ea5..e8f6c5b43e5d 100644 --- a/layout/generic/TextOverflow.cpp +++ b/layout/generic/TextOverflow.cpp @@ -214,8 +214,8 @@ void nsDisplayTextOverflowMarker::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { - nsCSSPropertyID colorProp = mFrame->StyleContext()->GetTextFillColorProp(); - nscolor foregroundColor = nsLayoutUtils::GetColor(mFrame, colorProp); + nscolor foregroundColor = nsLayoutUtils:: + GetColor(mFrame, eCSSProperty__webkit_text_fill_color); // Paint the text-shadows for the overflow marker nsLayoutUtils::PaintTextShadow(mFrame, aCtx, mRect, mVisibleRect, diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 78e2c33e9401..5aa46eb030d5 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -332,7 +332,8 @@ public: if (mFrame->IsSVGText()) { return 0; } - return mFrame->StyleContext()->GetTextStrokeColor(); + return mFrame->StyleColor()-> + CalcComplexColor(mFrame->StyleText()->mWebkitTextStrokeColor); } float GetWebkitTextStrokeWidth() { if (mFrame->IsSVGText()) { @@ -3707,8 +3708,7 @@ nsTextPaintStyle::GetTextColor() } } - return nsLayoutUtils::GetColor(mFrame, - mFrame->StyleContext()->GetTextFillColorProp()); + return nsLayoutUtils::GetColor(mFrame, eCSSProperty__webkit_text_fill_color); } bool @@ -3901,7 +3901,8 @@ nsTextPaintStyle::InitSelectionColorsAndShadow() if (sc) { mSelectionBGColor = sc->GetVisitedDependentColor(eCSSProperty_background_color); - mSelectionTextColor = sc->GetVisitedDependentColor(sc->GetTextFillColorProp()); + mSelectionTextColor = + sc->GetVisitedDependentColor(eCSSProperty__webkit_text_fill_color); mHasSelectionShadow = nsRuleNode::HasAuthorSpecifiedRules(sc, NS_AUTHOR_SPECIFIED_TEXT_SHADOW, @@ -3939,13 +3940,13 @@ nsTextPaintStyle::InitSelectionColorsAndShadow() if (mSelectionTextColor == NS_DONT_CHANGE_COLOR) { nsCSSPropertyID property = mFrame->IsSVGText() ? eCSSProperty_fill - : mFrame->StyleContext()->GetTextFillColorProp(); + : eCSSProperty__webkit_text_fill_color; nscoord frameColor = mFrame->GetVisitedDependentColor(property); mSelectionTextColor = EnsureDifferentColors(frameColor, mSelectionBGColor); } else if (mSelectionTextColor == NS_CHANGE_COLOR_IF_SAME_AS_BG) { nsCSSPropertyID property = mFrame->IsSVGText() ? eCSSProperty_fill - : mFrame->StyleContext()->GetTextFillColorProp(); + : eCSSProperty__webkit_text_fill_color; nscolor frameColor = mFrame->GetVisitedDependentColor(property); if (frameColor == mSelectionBGColor) { mSelectionTextColor = @@ -4952,9 +4953,11 @@ nsTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, DO_GLOBAL_REFLOW_COUNT_DSP("nsTextFrame"); - nsStyleContext* sc = StyleContext(); - bool isTextTransparent = (NS_GET_A(sc->GetTextFillColor()) == 0) && - (NS_GET_A(sc->GetTextStrokeColor()) == 0); + const nsStyleColor* sc = StyleColor(); + const nsStyleText* st = StyleText(); + bool isTextTransparent = + NS_GET_A(sc->CalcComplexColor(st->mWebkitTextFillColor)) == 0 && + NS_GET_A(sc->CalcComplexColor(st->mWebkitTextStrokeColor)) == 0; Maybe isSelected; if (((GetStateBits() & TEXT_NO_RENDERED_GLYPHS) || (isTextTransparent && !StyleText()->HasTextShadow())) && diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp index cf6a488cfd13..2edc1fa0d978 100644 --- a/layout/mathml/nsMathMLChar.cpp +++ b/layout/mathml/nsMathMLChar.cpp @@ -2124,8 +2124,8 @@ nsMathMLChar::PaintForeground(nsPresContext* aPresContext, RefPtr thebesContext = aRenderingContext.ThebesContext(); // Set color ... - nsCSSPropertyID colorProp = styleContext->GetTextFillColorProp(); - nscolor fgColor = styleContext->GetVisitedDependentColor(colorProp); + nscolor fgColor = styleContext-> + GetVisitedDependentColor(eCSSProperty__webkit_text_fill_color); if (aIsSelected) { // get color to use for selection from the look&feel object fgColor = LookAndFeel::GetColor(LookAndFeel::eColorID_TextSelectForeground, diff --git a/layout/mathml/nsMathMLFrame.cpp b/layout/mathml/nsMathMLFrame.cpp index 24cc19c72e9b..82c3a4a38ef5 100644 --- a/layout/mathml/nsMathMLFrame.cpp +++ b/layout/mathml/nsMathMLFrame.cpp @@ -365,9 +365,8 @@ void nsDisplayMathMLBar::Paint(nsDisplayListBuilder* aBuilder, NSRectToNonEmptySnappedRect(mRect + ToReferenceFrame(), mFrame->PresContext()->AppUnitsPerDevPixel(), *drawTarget); - nsCSSPropertyID colorProp = mFrame->StyleContext()->GetTextFillColorProp(); ColorPattern color(ToDeviceColor( - mFrame->GetVisitedDependentColor(colorProp))); + mFrame->GetVisitedDependentColor(eCSSProperty__webkit_text_fill_color))); drawTarget->FillRect(rect, color); } diff --git a/layout/mathml/nsMathMLmencloseFrame.cpp b/layout/mathml/nsMathMLmencloseFrame.cpp index 1b463299171a..64277a92e97a 100644 --- a/layout/mathml/nsMathMLmencloseFrame.cpp +++ b/layout/mathml/nsMathMLmencloseFrame.cpp @@ -779,9 +779,8 @@ void nsDisplayNotation::Paint(nsDisplayListBuilder* aBuilder, presContext->AppUnitsPerDevPixel()); rect.Deflate(strokeWidth / 2.f); - nsCSSPropertyID colorProp = mFrame->StyleContext()->GetTextFillColorProp(); ColorPattern color(ToDeviceColor( - mFrame->GetVisitedDependentColor(colorProp))); + mFrame->GetVisitedDependentColor(eCSSProperty__webkit_text_fill_color))); StrokeOptions strokeOptions(strokeWidth); diff --git a/layout/mathml/nsMathMLmfracFrame.cpp b/layout/mathml/nsMathMLmfracFrame.cpp index 1e19aec87f9a..d4ed988c89aa 100644 --- a/layout/mathml/nsMathMLmfracFrame.cpp +++ b/layout/mathml/nsMathMLmfracFrame.cpp @@ -628,12 +628,11 @@ void nsDisplayMathMLSlash::Paint(nsDisplayListBuilder* aBuilder, nsPresContext* presContext = mFrame->PresContext(); Rect rect = NSRectToRect(mRect + ToReferenceFrame(), presContext->AppUnitsPerDevPixel()); - - nsCSSPropertyID colorProp = mFrame->StyleContext()->GetTextFillColorProp(); + ColorPattern color(ToDeviceColor( - mFrame->GetVisitedDependentColor(colorProp))); - - // draw the slash as a parallelogram + mFrame->GetVisitedDependentColor(eCSSProperty__webkit_text_fill_color))); + + // draw the slash as a parallelogram Point delta = Point(presContext->AppUnitsToGfxUnits(mThickness), 0); RefPtr builder = aDrawTarget.CreatePathBuilder(); if (mRTL) { diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index e3e439962472..ee7ef1934aff 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -34,6 +34,7 @@ #include "gfx2DGlue.h" using namespace mozilla; +using namespace mozilla::css; using namespace mozilla::gfx; // HELPER METHODS @@ -69,6 +70,15 @@ GetCommonUnit(nsCSSPropertyID aProperty, // We can use calc() as the common unit. return StyleAnimationValue::eUnit_Calc; } + if ((aFirstUnit == StyleAnimationValue::eUnit_Color || + aFirstUnit == StyleAnimationValue::eUnit_CurrentColor || + aFirstUnit == StyleAnimationValue::eUnit_ComplexColor) && + (aSecondUnit == StyleAnimationValue::eUnit_Color || + aSecondUnit == StyleAnimationValue::eUnit_CurrentColor || + aSecondUnit == StyleAnimationValue::eUnit_ComplexColor)) { + // We can use complex color as the common unit. + return StyleAnimationValue::eUnit_ComplexColor; + } return StyleAnimationValue::eUnit_Null; } return aFirstUnit; @@ -487,6 +497,77 @@ CalcPositionCoordSquareDistance(const nsCSSValue& aPos1, // CLASS METHODS // ------------- +static RGBAColorData +ExtractColor(const nsCSSValue& aValue) +{ + MOZ_ASSERT(aValue.IsNumericColorUnit(), "The unit should be color"); + // PercentageRGBColor and PercentageRGBAColor component value might be + // greater than 1.0 in case when the color value is accumulated, so we + // can't use nsCSSValue::GetColorValue() here because that function + // clamps its values. + if (aValue.GetUnit() == eCSSUnit_PercentageRGBColor || + aValue.GetUnit() == eCSSUnit_PercentageRGBAColor) { + nsCSSValueFloatColor* floatColor = aValue.GetFloatColorValue(); + return { + floatColor->Comp1(), + floatColor->Comp2(), + floatColor->Comp3(), + floatColor->Alpha() + }; + } + return RGBAColorData(aValue.GetColorValue()); +} + +static RGBAColorData +ExtractColor(const StyleAnimationValue& aValue) +{ + MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Color); + nsCSSValue* value = aValue.GetCSSValueValue(); + MOZ_ASSERT(value, "CSS value must be valid"); + return ExtractColor(*value); +} + +static ComplexColorData +ExtractComplexColor(const StyleAnimationValue& aValue) +{ + switch (aValue.GetUnit()) { + case StyleAnimationValue::eUnit_Color: + return ComplexColorData(ExtractColor(aValue), 0.0f); + case StyleAnimationValue::eUnit_CurrentColor: + return ComplexColorData({0, 0, 0, 0}, 1.0f); + case StyleAnimationValue::eUnit_ComplexColor: + return ComplexColorData(aValue.GetComplexColorData()); + default: + MOZ_ASSERT_UNREACHABLE("Unknown unit"); + return ComplexColorData({0, 0, 0, 0}, 0.0f); + } +} + +double +StyleAnimationValue::ComputeColorDistance(const RGBAColorData& aStartColor, + const RGBAColorData& aEndColor) +{ + // http://www.w3.org/TR/smil-animation/#animateColorElement says + // that we should use Euclidean RGB cube distance. However, we + // have to extend that to RGBA. For now, we'll just use the + // Euclidean distance in the (part of the) 4-cube of premultiplied + // colors. + double startA = aStartColor.mA; + double startR = aStartColor.mR * startA; + double startG = aStartColor.mG * startA; + double startB = aStartColor.mB * startA; + double endA = aEndColor.mA; + double endR = aEndColor.mR * endA; + double endG = aEndColor.mG * endA; + double endB = aEndColor.mB * endA; + + double diffA = startA - endA; + double diffR = startR - endR; + double diffG = startG - endG; + double diffB = startB - endB; + return sqrt(diffA * diffA + diffR * diffR + diffG * diffG + diffB * diffB); +} + bool StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty, const StyleAnimationValue& aStartValue, @@ -503,7 +584,6 @@ StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty, case eUnit_Normal: case eUnit_UnparsedString: case eUnit_URL: - case eUnit_CurrentColor: case eUnit_DiscreteCSSValue: return false; @@ -558,40 +638,33 @@ StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty, return true; } case eUnit_Color: { - // http://www.w3.org/TR/smil-animation/#animateColorElement says - // that we should use Euclidean RGB cube distance. However, we - // have to extend that to RGBA. For now, we'll just use the - // Euclidean distance in the (part of the) 4-cube of premultiplied - // colors. - // FIXME (spec): The CSS transitions spec doesn't say whether - // colors are premultiplied, but things work better when they are, - // so use premultiplication. Spec issue is still open per - // http://lists.w3.org/Archives/Public/www-style/2009Jul/0050.html - nscolor startColor = aStartValue.GetCSSValueValue()->GetColorValue(); - nscolor endColor = aEndValue.GetCSSValueValue()->GetColorValue(); - - // Get a color component on a 0-1 scale, which is much easier to - // deal with when working with alpha. - #define GET_COMPONENT(component_, color_) \ - (NS_GET_##component_(color_) * (1.0 / 255.0)) - - double startA = GET_COMPONENT(A, startColor); - double startR = GET_COMPONENT(R, startColor) * startA; - double startG = GET_COMPONENT(G, startColor) * startA; - double startB = GET_COMPONENT(B, startColor) * startA; - double endA = GET_COMPONENT(A, endColor); - double endR = GET_COMPONENT(R, endColor) * endA; - double endG = GET_COMPONENT(G, endColor) * endA; - double endB = GET_COMPONENT(B, endColor) * endA; - - #undef GET_COMPONENT - - double diffA = startA - endA; - double diffR = startR - endR; - double diffG = startG - endG; - double diffB = startB - endB; - aDistance = sqrt(diffA * diffA + diffR * diffR + - diffG * diffG + diffB * diffB); + aDistance = ComputeColorDistance(ExtractColor(aStartValue), + ExtractColor(aEndValue)); + return true; + } + case eUnit_CurrentColor: { + aDistance = 0; + return true; + } + case eUnit_ComplexColor: { + ComplexColorData color1 = ExtractComplexColor(aStartValue); + ComplexColorData color2 = ExtractComplexColor(aEndValue); + // Common case is interpolating between a color and a currentcolor + if (color1.IsNumericColor() && color2.IsCurrentColor()) { + double dist = ComputeColorDistance(color1.mColor, NS_RGBA(0, 0, 0, 0)); + aDistance = sqrt(dist * dist + 1); + return true; + } + if (color1.IsCurrentColor() && color2.IsNumericColor()) { + double dist = ComputeColorDistance(NS_RGBA(0, 0, 0, 0), color2.mColor); + aDistance = sqrt(dist * dist + 1); + return true; + } + // If we ever reach here, we may want to use the code in + // bug 1299741 comment 79 to compute it. + MOZ_ASSERT_UNREACHABLE("We shouldn't get here as we only call " + "ComputeDistance on pre-interpolation values"); + aDistance = 0.0; return true; } case eUnit_Calc: { @@ -848,17 +921,8 @@ StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty, #endif if (color1.GetUnit() != eCSSUnit_Null) { - StyleAnimationValue color1Value - (color1.GetColorValue(), StyleAnimationValue::ColorConstructor); - StyleAnimationValue color2Value - (color2.GetColorValue(), StyleAnimationValue::ColorConstructor); - double colorDistance; - - DebugOnly ok = - StyleAnimationValue::ComputeDistance(eCSSProperty_color, - color1Value, color2Value, - colorDistance); - MOZ_ASSERT(ok, "should not fail"); + double colorDistance = ComputeColorDistance(color1.GetColorValue(), + color2.GetColorValue()); squareDistance += colorDistance * colorDistance; } @@ -960,17 +1024,6 @@ StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty, return false; } -#define MAX_PACKED_COLOR_COMPONENT 255 - -inline uint8_t ClampColor(double aColor) -{ - if (aColor >= MAX_PACKED_COLOR_COMPONENT) - return MAX_PACKED_COLOR_COMPONENT; - if (aColor <= 0.0) - return 0; - return NSToIntRound(aColor); -} - // Ensure that a float/double value isn't NaN by returning zero instead // (NaN doesn't have a sign) as a general restriction for floating point // values in RestrictValue. @@ -1163,119 +1216,59 @@ AddCSSValuePercentNumber(const uint32_t aValueRestrictions, eCSSUnit_Number); } -// Returns Tuple(Red, Green, Blue, Alpha). -// Red, Green, and Blue are scaled to the [0, 255] range, and Alpha is scaled -// to the [0, 1] range (though values are allowed to fall outside of these -// ranges). -static Tuple -GetPremultipliedColorComponents(const nsCSSValue& aValue) -{ - // PercentageRGBColor and PercentageRGBAColor component value might be - // greater than 1.0 in case when the color value is accumulated, so we - // can't use nsCSSValue::GetColorValue() here because that function - // clamps its values. - if (aValue.GetUnit() == eCSSUnit_PercentageRGBColor || - aValue.GetUnit() == eCSSUnit_PercentageRGBAColor) { - nsCSSValueFloatColor* floatColor = aValue.GetFloatColorValue(); - double alpha = floatColor->Alpha(); - return MakeTuple(floatColor->Comp1() * 255.0 * alpha, - floatColor->Comp2() * 255.0 * alpha, - floatColor->Comp3() * 255.0 * alpha, - alpha); - } - - nscolor color = aValue.GetColorValue(); - double alpha = NS_GET_A(color) * (1.0 / 255.0); - return MakeTuple(NS_GET_R(color) * alpha, - NS_GET_G(color) * alpha, - NS_GET_B(color) * alpha, - alpha); -} - enum class ColorAdditionType { Clamped, // Clamp each color channel after adding. Unclamped // Do not clamp color channels after adding. }; -// |aAdditionType| should be Clamped in case of interpolation or SMIL -// animation (e.g. 'by' attribute). For now, Unclamped is only for -// accumulation. -static void -AddWeightedColors(double aCoeff1, const nsCSSValue& aValue1, - double aCoeff2, const nsCSSValue& aValue2, - ColorAdditionType aAdditionType, - nsCSSValue& aResult) +// Unclamped AddWeightedColors. +static RGBAColorData +AddWeightedColors(double aCoeff1, const RGBAColorData& aValue1, + double aCoeff2, const RGBAColorData& aValue2) { - MOZ_ASSERT(aValue1.IsNumericColorUnit() && aValue2.IsNumericColorUnit(), - "The unit should be color"); - // FIXME (spec): The CSS transitions spec doesn't say whether - // colors are premultiplied, but things work better when they are, - // so use premultiplication. Spec issue is still open per - // http://lists.w3.org/Archives/Public/www-style/2009Jul/0050.html - - // To save some math, scale the alpha down to a 0-1 scale, but - // leave the color components on a 0-255 scale. - - double R1, G1, B1, A1; - Tie(R1, G1, B1, A1) = GetPremultipliedColorComponents(aValue1); - double R2, G2, B2, A2; - Tie(R2, G2, B2, A2) = GetPremultipliedColorComponents(aValue2); - double Aresf = (A1 * aCoeff1 + A2 * aCoeff2); - if (Aresf <= 0.0) { - aResult.SetColorValue(NS_RGBA(0, 0, 0, 0)); - return; + float factor1 = aValue1.mA * aCoeff1; + float factor2 = aValue2.mA * aCoeff2; + float resultA = factor1 + factor2; + if (resultA <= 0.0) { + return {0, 0, 0, 0}; } - if (Aresf > 1.0) { - Aresf = 1.0; + if (resultA > 1.0) { + resultA = 1.0; } - double factor = 1.0 / Aresf; - double Rres = (R1 * aCoeff1 + R2 * aCoeff2) * factor; - double Gres = (G1 * aCoeff1 + G2 * aCoeff2) * factor; - double Bres = (B1 * aCoeff1 + B2 * aCoeff2) * factor; - - if (aAdditionType == ColorAdditionType::Clamped) { - aResult.SetColorValue( - NS_RGBA(ClampColor(Rres), ClampColor(Gres), ClampColor(Bres), - NSToIntRound(Aresf * 255.0))); - return; - } - - Rres = Rres * (1.0 / 255.0); - Gres = Gres * (1.0 / 255.0); - Bres = Bres * (1.0 / 255.0); - - aResult.SetFloatColorValue(Rres, Gres, Bres, Aresf, - eCSSUnit_PercentageRGBAColor); + float resultFactor = 1.0f / resultA; + return RGBAColorData( + (aValue1.mR * factor1 + aValue2.mR * factor2) * resultFactor, + (aValue1.mG * factor1 + aValue2.mG * factor2) * resultFactor, + (aValue1.mB * factor1 + aValue2.mB * factor2) * resultFactor, + resultA); } -// Multiplies |aValue| color by |aDilutionRation| with premultiplication. -// The result is stored in |aResult|. -// (The logic here should pretty closely match AddWeightedColors()' logic.) -static void -DiluteColor(const nsCSSValue& aValue, double aDilutionRatio, - nsCSSValue& aResult) +// Multiplies |aValue| color by |aDilutionRation|. +static nscolor +DiluteColor(const RGBAColorData& aValue, double aDilutionRatio) { - MOZ_ASSERT(aValue.IsNumericColorUnit(), "The unit should be color"); MOZ_ASSERT(aDilutionRatio >= 0.0 && aDilutionRatio <= 1.0, "Dilution ratio should be in [0, 1]"); + float resultA = aValue.mA * aDilutionRatio; + return resultA <= 0.0 ? NS_RGBA(0, 0, 0, 0) + : aValue.WithAlpha(resultA).ToColor(); +} - // Premultiplication - double R, G, B, A; - Tie(R, G, B, A) = GetPremultipliedColorComponents(aValue); - double Aresf = A * aDilutionRatio; - if (Aresf <= 0.0) { - aResult.SetColorValue(NS_RGBA(0, 0, 0, 0)); - return; - } - - double factor = 1.0 / Aresf; - aResult.SetColorValue( - NS_RGBA(ClampColor(R * aDilutionRatio * factor), - ClampColor(G * aDilutionRatio * factor), - ClampColor(B * aDilutionRatio * factor), - NSToIntRound(Aresf * 255.0))); +// Clamped AddWeightedColors. +static nscolor +AddWeightedColorsAndClamp(double aCoeff1, const RGBAColorData& aValue1, + double aCoeff2, const RGBAColorData& aValue2) +{ + // We are using AddWeighted() with a zero aCoeff2 for colors to + // pretend AddWeighted() against transparent color, i.e. rgba(0, 0, 0, 0). + // But unpremultiplication in AddWeightedColors() does not work well + // for such cases, so we use another function named DiluteColor() which + // has a similar logic to AddWeightedColors(). + return aCoeff2 == 0.0 + ? DiluteColor(aValue1, aCoeff1) + : AddWeightedColors(aCoeff1, aValue1, aCoeff2, aValue2).ToColor(); } void @@ -1315,12 +1308,13 @@ AddWeightedShadowItems(double aCoeff1, const nsCSSValue &aValue1, (i == 2) ? CSS_PROPERTY_VALUE_NONNEGATIVE : 0); } - const nsCSSValue& color1 = array1->Item(4); - const nsCSSValue& color2 = array2->Item(4); + const nsCSSValue& colorValue1 = array1->Item(4); + const nsCSSValue& colorValue2 = array2->Item(4); const nsCSSValue& inset1 = array1->Item(5); const nsCSSValue& inset2 = array2->Item(5); - if ((color1.GetUnit() != color2.GetUnit() && - (!color1.IsNumericColorUnit() || !color2.IsNumericColorUnit())) || + if ((colorValue1.GetUnit() != colorValue2.GetUnit() && + (!colorValue1.IsNumericColorUnit() || + !colorValue2.IsNumericColorUnit())) || inset1.GetUnit() != inset2.GetUnit()) { // We don't know how to animate between color and no-color, or // between inset and not-inset. @@ -1329,13 +1323,15 @@ AddWeightedShadowItems(double aCoeff1, const nsCSSValue &aValue1, return nullptr; } - if (color1.GetUnit() != eCSSUnit_Null) { - if (aCoeff2 == 0.0 && aCoeff1 != 1.0) { - DiluteColor(color1, aCoeff1, resultArray->Item(4)); + if (colorValue1.GetUnit() != eCSSUnit_Null) { + RGBAColorData color1 = ExtractColor(colorValue1); + RGBAColorData color2 = ExtractColor(colorValue2); + if (aColorAdditionType == ColorAdditionType::Clamped) { + resultArray->Item(4).SetColorValue( + AddWeightedColorsAndClamp(aCoeff1, color1, aCoeff2, color2)); } else { - AddWeightedColors(aCoeff1, color1, aCoeff2, color2, - aColorAdditionType, - resultArray->Item(4)); + resultArray->Item(4).SetRGBAColorValue( + AddWeightedColors(aCoeff1, color1, aCoeff2, color2)); } } @@ -2491,7 +2487,6 @@ StyleAnimationValue::AddWeighted(nsCSSPropertyID aProperty, case eUnit_Normal: case eUnit_UnparsedString: case eUnit_URL: - case eUnit_CurrentColor: case eUnit_DiscreteCSSValue: return false; @@ -2568,26 +2563,46 @@ StyleAnimationValue::AddWeighted(nsCSSPropertyID aProperty, return true; } case eUnit_Color: { - const nsCSSValue* value1 = aValue1.GetCSSValueValue(); - const nsCSSValue* value2 = aValue2.GetCSSValueValue(); - MOZ_ASSERT(value1 && value2, "Both of CSS value should be valid"); + RGBAColorData color1 = ExtractColor(aValue1); + RGBAColorData color2 = ExtractColor(aValue2); auto resultColor = MakeUnique(); - - // We are using AddWeighted() with a zero aCoeff2 for colors to - // pretend AddWeighted() against transparent color, i.e. rgba(0, 0, 0, 0). - // But unpremultiplication in AddWeightedColors() does not work well - // for such cases, so we use another function named DiluteColor() which - // has a similar logic to AddWeightedColors(). - if (aCoeff2 == 0.0) { - DiluteColor(*value1, aCoeff1, *resultColor); - } else { - AddWeightedColors(aCoeff1, *value1, aCoeff2, *value2, - ColorAdditionType::Clamped, - *resultColor); - } + resultColor->SetColorValue( + AddWeightedColorsAndClamp(aCoeff1, color1, aCoeff2, color2)); aResultValue.SetAndAdoptCSSValueValue(resultColor.release(), eUnit_Color); return true; } + case eUnit_CurrentColor: { + aResultValue.SetCurrentColorValue(); + return true; + } + case eUnit_ComplexColor: { + ComplexColorData color1 = ExtractComplexColor(aValue1); + ComplexColorData color2 = ExtractComplexColor(aValue2); + RefPtr result = new ComplexColorValue; + // Common case is interpolating between a color and a currentcolor. + if (color1.IsNumericColor() && color2.IsCurrentColor()) { + result->mColor = color1.mColor; + result->mForegroundRatio = aCoeff2; + } else if (color1.IsCurrentColor() && color2.IsNumericColor()) { + result->mColor = color2.mColor; + result->mForegroundRatio = aCoeff1; + } else { + float ratio1 = 1.0f - color1.mForegroundRatio; + float ratio2 = 1.0f - color2.mForegroundRatio; + float alpha1 = color1.mColor.mA * ratio1; + float alpha2 = color2.mColor.mA * ratio2; + RGBAColorData resultColor = + AddWeightedColors(aCoeff1, color1.mColor.WithAlpha(alpha1), + aCoeff2, color2.mColor.WithAlpha(alpha2)); + float resultRatio = color1.mForegroundRatio * aCoeff1 + + color2.mForegroundRatio * aCoeff2; + float resultAlpha = resultColor.mA / (1.0f - resultRatio); + result->mColor = resultColor.WithAlpha(resultAlpha); + result->mForegroundRatio = resultRatio; + } + aResultValue.SetComplexColorValue(result.forget()); + return true; + } case eUnit_Calc: { PixelCalcValue v1 = ExtractCalcValue(aValue1); PixelCalcValue v2 = ExtractCalcValue(aValue2); @@ -2942,14 +2957,11 @@ StyleAnimationValue::Accumulate(nsCSSPropertyID aProperty, return true; } case eUnit_Color: { + RGBAColorData color1 = ExtractColor(aDest); + RGBAColorData color2 = ExtractColor(aValueToAccumulate); auto resultColor = MakeUnique(); - AddWeightedColors(1.0, - *aDest.GetCSSValueValue(), - aCount, - *aValueToAccumulate.GetCSSValueValue(), - ColorAdditionType::Unclamped, - *resultColor); - + resultColor->SetRGBAColorValue( + AddWeightedColors(1.0, color1, aCount, color2)); aDest.SetAndAdoptCSSValueValue(resultColor.release(), eUnit_Color); return true; } @@ -3279,6 +3291,11 @@ StyleAnimationValue::UncomputeValue(nsCSSPropertyID aProperty, aSpecifiedValue = *val; break; } + case eUnit_ComplexColor: { + aSpecifiedValue.SetComplexColorValue( + do_AddRef(aComputedValue.mValue.mComplexColor)); + break; + } case eUnit_CSSValuePair: { // Rule node processing expects pair values to be collapsed to a // single value if both halves would be equal, for most but not @@ -3394,27 +3411,12 @@ StyleAnimationValue::UncomputeValue(nsCSSPropertyID aProperty, return true; } -inline const void* +template +inline const T& StyleDataAtOffset(const void* aStyleStruct, ptrdiff_t aOffset) { - return reinterpret_cast(aStyleStruct) + aOffset; -} - -inline void* -StyleDataAtOffset(void* aStyleStruct, ptrdiff_t aOffset) -{ - return reinterpret_cast(aStyleStruct) + aOffset; -} - -static void -SetCurrentOrActualColor(bool aIsForeground, nscolor aActualColor, - StyleAnimationValue& aComputedValue) -{ - if (aIsForeground) { - aComputedValue.SetCurrentColorValue(); - } else { - aComputedValue.SetColorValue(aActualColor); - } + return *reinterpret_cast( + reinterpret_cast(aStyleStruct) + aOffset); } static void @@ -3914,30 +3916,6 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty, break; } - case eCSSProperty_text_emphasis_color: { - auto styleText = static_cast(styleStruct); - SetCurrentOrActualColor(styleText->mTextEmphasisColorForeground, - styleText->mTextEmphasisColor, - aComputedValue); - break; - } - - case eCSSProperty__webkit_text_fill_color: { - auto styleText = static_cast(styleStruct); - SetCurrentOrActualColor(styleText->mWebkitTextFillColorForeground, - styleText->mWebkitTextFillColor, - aComputedValue); - break; - } - - case eCSSProperty__webkit_text_stroke_color: { - auto styleText = static_cast(styleStruct); - SetCurrentOrActualColor(styleText->mWebkitTextStrokeColorForeground, - styleText->mWebkitTextStrokeColor, - aComputedValue); - break; - } - case eCSSProperty_border_spacing: { const nsStyleTableBorder *styleTableBorder = static_cast(styleStruct); @@ -4277,8 +4255,8 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty, }; return true; case eStyleAnimType_Coord: { - const nsStyleCoord& coord = *static_cast( - StyleDataAtOffset(styleStruct, ssOffset)); + const nsStyleCoord& coord = + StyleDataAtOffset(styleStruct, ssOffset); if (nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_NUMBERS_ARE_PIXELS) && coord.GetUnit() == eStyleUnit_Coord) { // For SVG properties where number means the same thing as length, @@ -4301,8 +4279,8 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty, NS_SIDE_LEFT == eStyleAnimType_Sides_Left -eStyleAnimType_Sides_Top, "box side constants out of sync with animation side constants"); - const nsStyleCoord &coord = static_cast( - StyleDataAtOffset(styleStruct, ssOffset))-> + const nsStyleCoord &coord = + StyleDataAtOffset(styleStruct, ssOffset). Get(mozilla::css::Side(animType - eStyleAnimType_Sides_Top)); return StyleCoordToValue(coord, aComputedValue); } @@ -4321,13 +4299,13 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty, eStyleAnimType_Corner_TopLeft, "box corner constants out of sync with animation corner constants"); - const nsStyleCorners *corners = static_cast( - StyleDataAtOffset(styleStruct, ssOffset)); + const nsStyleCorners& corners = + StyleDataAtOffset(styleStruct, ssOffset); uint8_t fullCorner = animType - eStyleAnimType_Corner_TopLeft; const nsStyleCoord &horiz = - corners->Get(NS_FULL_TO_HALF_CORNER(fullCorner, false)); + corners.Get(NS_FULL_TO_HALF_CORNER(fullCorner, false)); const nsStyleCoord &vert = - corners->Get(NS_FULL_TO_HALF_CORNER(fullCorner, true)); + corners.Get(NS_FULL_TO_HALF_CORNER(fullCorner, true)); nsAutoPtr pair(new nsCSSValuePair); if (!StyleCoordToCSSValue(horiz, pair->mXValue) || !StyleCoordToCSSValue(vert, pair->mYValue)) { @@ -4338,12 +4316,12 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty, return true; } case eStyleAnimType_nscoord: - aComputedValue.SetCoordValue(*static_cast( - StyleDataAtOffset(styleStruct, ssOffset))); + aComputedValue.SetCoordValue( + StyleDataAtOffset(styleStruct, ssOffset)); return true; case eStyleAnimType_float: - aComputedValue.SetFloatValue(*static_cast( - StyleDataAtOffset(styleStruct, ssOffset))); + aComputedValue.SetFloatValue( + StyleDataAtOffset(styleStruct, ssOffset)); if (aProperty == eCSSProperty_font_size_adjust && aComputedValue.GetFloatValue() == -1.0f) { // In nsStyleFont, we set mFont.sizeAdjust to -1.0 to represent @@ -4354,12 +4332,17 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty, } return true; case eStyleAnimType_Color: - aComputedValue.SetColorValue(*static_cast( - StyleDataAtOffset(styleStruct, ssOffset))); + aComputedValue.SetColorValue( + StyleDataAtOffset(styleStruct, ssOffset)); return true; + case eStyleAnimType_ComplexColor: { + aComputedValue.SetComplexColorValue( + StyleDataAtOffset(styleStruct, ssOffset)); + return true; + } case eStyleAnimType_PaintServer: { - const nsStyleSVGPaint &paint = *static_cast( - StyleDataAtOffset(styleStruct, ssOffset)); + const nsStyleSVGPaint& paint = + StyleDataAtOffset(styleStruct, ssOffset); if (paint.mType == eStyleSVGPaintType_Color) { aComputedValue.SetColorValue(paint.mPaint.mColor); return true; @@ -4398,9 +4381,8 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty, return true; } case eStyleAnimType_Shadow: { - const nsCSSShadowArray *shadowArray = - *static_cast*>( - StyleDataAtOffset(styleStruct, ssOffset)); + const nsCSSShadowArray* shadowArray = + StyleDataAtOffset>(styleStruct, ssOffset); if (!shadowArray) { aComputedValue.SetAndAdoptCSSValueListValue(nullptr, eUnit_Shadow); return true; @@ -4585,6 +4567,11 @@ StyleAnimationValue::operator=(const StyleAnimationValue& aOther) mValue.mString = aOther.mValue.mString; mValue.mString->AddRef(); break; + case eUnit_ComplexColor: + MOZ_ASSERT(aOther.mValue.mComplexColor); + mValue.mComplexColor = aOther.mValue.mComplexColor; + mValue.mComplexColor->AddRef(); + break; } return *this; @@ -4662,6 +4649,27 @@ StyleAnimationValue::SetCurrentColorValue() mUnit = eUnit_CurrentColor; } +void +StyleAnimationValue::SetComplexColorValue(const StyleComplexColor& aColor) +{ + if (aColor.IsCurrentColor()) { + SetCurrentColorValue(); + } else if (aColor.IsNumericColor()) { + SetColorValue(aColor.mColor); + } else { + SetComplexColorValue(do_AddRef(new ComplexColorValue(aColor))); + } +} + +void +StyleAnimationValue::SetComplexColorValue( + already_AddRefed aValue) +{ + FreeValue(); + mUnit = eUnit_ComplexColor; + mValue.mComplexColor = aValue.take(); +} + void StyleAnimationValue::SetUnparsedStringValue(const nsString& aString) { @@ -4780,6 +4788,8 @@ StyleAnimationValue::FreeValue() } else if (IsStringUnit(mUnit)) { MOZ_ASSERT(mValue.mString, "expecting non-null string"); mValue.mString->Release(); + } else if (mUnit == eUnit_ComplexColor) { + mValue.mComplexColor->Release(); } } @@ -4836,6 +4846,8 @@ StyleAnimationValue::operator==(const StyleAnimationValue& aOther) const case eUnit_UnparsedString: return (NS_strcmp(GetStringBufferValue(), aOther.GetStringBufferValue()) == 0); + case eUnit_ComplexColor: + return *mValue.mComplexColor == *aOther.mValue.mComplexColor; } NS_NOTREACHED("incomplete case"); diff --git a/layout/style/StyleAnimationValue.h b/layout/style/StyleAnimationValue.h index 915db2e65a91..d1d72d7fbfd0 100644 --- a/layout/style/StyleAnimationValue.h +++ b/layout/style/StyleAnimationValue.h @@ -59,6 +59,18 @@ public: return AddWeighted(aProperty, 1.0, aDest, aCount, aValueToAdd, aDest); } + /** + * Calculates a measure of 'distance' between two colors. + * + * @param aStartColor The start of the interval for which the distance + * should be calculated. + * @param aEndColor The end of the interval for which the distance + * should be calculated. + * @return the result of the calculation. + */ + static double ComputeColorDistance(const css::RGBAColorData& aStartColor, + const css::RGBAColorData& aEndColor); + /** * Calculates a measure of 'distance' between two values. * @@ -308,6 +320,7 @@ public: eUnit_Color, // nsCSSValue* (never null), always with an nscolor or // an nsCSSValueFloatColor eUnit_CurrentColor, + eUnit_ComplexColor, // ComplexColorValue* (never null) eUnit_Calc, // nsCSSValue* (never null), always with a single // calc() expression that's either length or length+percent eUnit_ObjectPosition, // nsCSSValue* (never null), always with a @@ -342,6 +355,7 @@ private: nsCSSValueSharedList* mCSSValueSharedList; nsCSSValuePairList* mCSSValuePairList; nsStringBuffer* mString; + css::ComplexColorValue* mComplexColor; } mValue; public: @@ -419,6 +433,14 @@ public: /// @return the scale for this value, calculated with reference to @aForFrame. gfxSize GetScaleValue(const nsIFrame* aForFrame) const; + const css::ComplexColorData& GetComplexColorData() const { + MOZ_ASSERT(mUnit == eUnit_ComplexColor, "unit mismatch"); + return *mValue.mComplexColor; + } + StyleComplexColor GetStyleComplexColorValue() const { + return GetComplexColorData().ToComplexColor(); + } + UniquePtr TakeCSSValueListValue() { nsCSSValueList* list = GetCSSValueListValue(); mValue.mCSSValueList = nullptr; @@ -475,6 +497,8 @@ public: void SetFloatValue(float aFloat); void SetColorValue(nscolor aColor); void SetCurrentColorValue(); + void SetComplexColorValue(const StyleComplexColor& aColor); + void SetComplexColorValue(already_AddRefed aValue); void SetUnparsedStringValue(const nsString& aString); void SetCSSValueArrayValue(nsCSSValue::Array* aValue, Unit aUnit); diff --git a/layout/style/StyleComplexColor.h b/layout/style/StyleComplexColor.h new file mode 100644 index 000000000000..d7732e5b01f2 --- /dev/null +++ b/layout/style/StyleComplexColor.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +/* represent a color combines a numeric color and currentcolor */ + +#ifndef mozilla_StyleComplexColor_h_ +#define mozilla_StyleComplexColor_h_ + +#include "nsColor.h" + +namespace mozilla { + +/** + * This struct represents a combined color from a numeric color and + * the current foreground color (currentcolor keyword). + * Conceptually, the formula is "color * (1 - p) + currentcolor * p" + * where p is mForegroundRatio. See mozilla::LinearBlendColors for + * the actual algorithm. + */ +struct StyleComplexColor +{ + nscolor mColor; + uint8_t mForegroundRatio; + + StyleComplexColor() {} + StyleComplexColor(nscolor aColor, uint_fast8_t aForegroundRatio) + : mColor(aColor), mForegroundRatio(aForegroundRatio) {} + + static StyleComplexColor FromColor(nscolor aColor) + { return StyleComplexColor(aColor, 0); } + static StyleComplexColor CurrentColor() + { return StyleComplexColor(NS_RGBA(0, 0, 0, 0), 255); } + + bool IsNumericColor() const { return mForegroundRatio == 0; } + bool IsCurrentColor() const { return mForegroundRatio == 255; } + + bool operator==(const StyleComplexColor& aOther) const { + return mForegroundRatio == aOther.mForegroundRatio && + (IsCurrentColor() || mColor == aOther.mColor); + } + bool operator!=(const StyleComplexColor& aOther) const { + return !(*this == aOther); + } +}; + +} + +#endif // mozilla_StyleComplexColor_h_ diff --git a/layout/style/moz.build b/layout/style/moz.build index 14e8af469f00..6dbdb52be220 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -100,6 +100,7 @@ EXPORTS.mozilla += [ 'SheetType.h', 'StyleAnimationValue.h', 'StyleBackendType.h', + 'StyleComplexColor.h', 'StyleContextSource.h', 'StyleSetHandle.h', 'StyleSetHandleInlines.h', diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 6320917528c0..042c256b1e72 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -3981,8 +3981,8 @@ CSS_PROP_TEXT( "", VARIANT_HC, nullptr, - CSS_PROP_NO_OFFSET, - eStyleAnimType_Custom) + offsetof(nsStyleText, mTextEmphasisColor), + eStyleAnimType_ComplexColor) CSS_PROP_TEXT( text-emphasis-position, text_emphasis_position, @@ -4017,7 +4017,7 @@ CSS_PROP_TEXT( VARIANT_HC, nullptr, offsetof(nsStyleText, mWebkitTextFillColor), - eStyleAnimType_Custom) + eStyleAnimType_ComplexColor) CSS_PROP_TEXT( text-indent, text_indent, @@ -4106,7 +4106,7 @@ CSS_PROP_TEXT( VARIANT_HC, nullptr, offsetof(nsStyleText, mWebkitTextStrokeColor), - eStyleAnimType_Custom) + eStyleAnimType_ComplexColor) CSS_PROP_TEXT( -webkit-text-stroke-width, _webkit_text_stroke_width, diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 5f6f31703ff2..15f394162edd 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -315,6 +315,9 @@ enum nsStyleAnimType { // nscolor values eStyleAnimType_Color, + // StyleComplexColor values + eStyleAnimType_ComplexColor, + // nsStyleSVGPaint values eStyleAnimType_PaintServer, diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 609517315f80..9121dde36270 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -161,6 +161,10 @@ nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) mValue.mFloatColor = aCopy.mValue.mFloatColor; mValue.mFloatColor->AddRef(); } + else if (eCSSUnit_ComplexColor == mUnit) { + mValue.mComplexColor = aCopy.mValue.mComplexColor; + mValue.mComplexColor->AddRef(); + } else if (UnitHasArrayValue()) { mValue.mArray = aCopy.mValue.mArray; mValue.mArray->AddRef(); @@ -271,6 +275,9 @@ bool nsCSSValue::operator==(const nsCSSValue& aOther) const else if (IsFloatColorUnit()) { return *mValue.mFloatColor == *aOther.mValue.mFloatColor; } + else if (eCSSUnit_ComplexColor == mUnit) { + return *mValue.mComplexColor == *aOther.mValue.mComplexColor; + } else if (UnitHasArrayValue()) { return *mValue.mArray == *aOther.mValue.mArray; } @@ -377,6 +384,8 @@ void nsCSSValue::DoReset() mValue.mString->Release(); } else if (IsFloatColorUnit()) { mValue.mFloatColor->Release(); + } else if (eCSSUnit_ComplexColor == mUnit) { + mValue.mComplexColor->Release(); } else if (UnitHasArrayValue()) { mValue.mArray->Release(); } else if (eCSSUnit_URL == mUnit) { @@ -478,6 +487,21 @@ void nsCSSValue::SetFloatColorValue(float aComponent1, mValue.mFloatColor->AddRef(); } +void +nsCSSValue::SetRGBAColorValue(const RGBAColorData& aValue) +{ + SetFloatColorValue(aValue.mR, aValue.mG, aValue.mB, + aValue.mA, eCSSUnit_PercentageRGBAColor); +} + +void +nsCSSValue::SetComplexColorValue(already_AddRefed aValue) +{ + Reset(); + mUnit = eCSSUnit_ComplexColor; + mValue.mComplexColor = aValue.take(); +} + void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit) { Reset(); @@ -1566,6 +1590,18 @@ nsCSSValue::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult, mValue.mFloatColor->AppendToString(unit, aResult); } } + else if (eCSSUnit_ComplexColor == unit) { + StyleComplexColor color = GetStyleComplexColorValue(); + nsCSSValue serializable; + if (color.IsCurrentColor()) { + serializable.SetIntValue(NS_COLOR_CURRENTCOLOR, eCSSUnit_EnumColor); + } else if (color.IsNumericColor()) { + serializable.SetColorValue(color.mColor); + } else { + MOZ_ASSERT_UNREACHABLE("Cannot serialize a complex color"); + } + serializable.AppendToString(aProperty, aResult, aSerialization); + } else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) { aResult.AppendLiteral("url("); nsStyleUtil::AppendEscapedCSSString( @@ -1862,6 +1898,7 @@ nsCSSValue::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult, case eCSSUnit_PercentageRGBAColor: break; case eCSSUnit_HSLColor: break; case eCSSUnit_HSLAColor: break; + case eCSSUnit_ComplexColor: break; case eCSSUnit_Percent: aResult.Append(char16_t('%')); break; case eCSSUnit_Number: break; case eCSSUnit_Gradient: break; @@ -2049,6 +2086,11 @@ nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const n += mValue.mFloatColor->SizeOfIncludingThis(aMallocSizeOf); break; + // Complex Color + case eCSSUnit_ComplexColor: + n += mValue.mComplexColor->SizeOfIncludingThis(aMallocSizeOf); + break; + // Float: nothing extra to measure. case eCSSUnit_Percent: case eCSSUnit_Number: @@ -2777,6 +2819,17 @@ css::ImageValue::~ImageValue() } } +size_t +css::ComplexColorValue::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const +{ + // Only measure it if it's unshared, to avoid double-counting. + size_t n = 0; + if (mRefCnt <= 1) { + n += aMallocSizeOf(this); + } + return n; +} + nsCSSValueGradientStop::nsCSSValueGradientStop() : mLocation(eCSSUnit_None), mColor(eCSSUnit_Null), diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h index 196ec0b7ddd1..06e85e47255f 100644 --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -13,6 +13,7 @@ #include "mozilla/Attributes.h" #include "mozilla/MemoryReporting.h" #include "mozilla/SheetType.h" +#include "mozilla/StyleComplexColor.h" #include "mozilla/UniquePtr.h" #include "nsIPrincipal.h" @@ -299,6 +300,102 @@ private: } }; +struct RGBAColorData +{ + // 1.0 means 100% for all components, but the value may fall outside + // the range of [0.0, 1.0], so it is necessary to clamp them when + // converting to nscolor. + float mR; + float mG; + float mB; + float mA; + + RGBAColorData() = default; + MOZ_IMPLICIT RGBAColorData(nscolor aColor) + : mR(NS_GET_R(aColor) * (1.0f / 255.0f)) + , mG(NS_GET_G(aColor) * (1.0f / 255.0f)) + , mB(NS_GET_B(aColor) * (1.0f / 255.0f)) + , mA(NS_GET_A(aColor) * (1.0f / 255.0f)) + {} + RGBAColorData(float aR, float aG, float aB, float aA) + : mR(aR), mG(aG), mB(aB), mA(aA) {} + + bool operator==(const RGBAColorData& aOther) const + { + return mR == aOther.mR && mG == aOther.mG && + mB == aOther.mB && mA == aOther.mA; + } + bool operator!=(const RGBAColorData& aOther) const + { + return !(*this == aOther); + } + + nscolor ToColor() const + { + return NS_RGBA(ClampColor(mR * 255.0f), + ClampColor(mG * 255.0f), + ClampColor(mB * 255.0f), + ClampColor(mA * 255.0f)); + } + + RGBAColorData WithAlpha(float aAlpha) const + { + RGBAColorData result = *this; + result.mA = aAlpha; + return result; + } +}; + +struct ComplexColorData +{ + RGBAColorData mColor; + float mForegroundRatio; + + ComplexColorData() = default; + ComplexColorData(const RGBAColorData& aColor, float aForegroundRatio) + : mColor(aColor), mForegroundRatio(aForegroundRatio) {} + ComplexColorData(nscolor aColor, float aForegroundRatio) + : mColor(aColor), mForegroundRatio(aForegroundRatio) {} + explicit ComplexColorData(const StyleComplexColor& aColor) + : mColor(aColor.mColor) + , mForegroundRatio(aColor.mForegroundRatio * (1.0f / 255.0f)) {} + + bool operator==(const ComplexColorData& aOther) const + { + return mForegroundRatio == aOther.mForegroundRatio && + (IsCurrentColor() || mColor == aOther.mColor); + } + bool operator!=(const ComplexColorData& aOther) const + { + return !(*this == aOther); + } + + bool IsCurrentColor() const { return mForegroundRatio >= 1.0f; } + bool IsNumericColor() const { return mForegroundRatio <= 0.0f; } + + StyleComplexColor ToComplexColor() const + { + return StyleComplexColor( + mColor.ToColor(), ClampColor(mForegroundRatio * 255.0f)); + } +}; + +struct ComplexColorValue final : public ComplexColorData +{ + // Just redirect any parameter to the data struct. + template + explicit ComplexColorValue(Args&&... aArgs) + : ComplexColorData(Forward(aArgs)...) {} + ComplexColorValue(const ComplexColorValue&) = delete; + + NS_INLINE_DECL_REFCOUNTING(ComplexColorValue) + + size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; + +private: + ~ComplexColorValue() {} +}; + } // namespace css } // namespace mozilla @@ -393,6 +490,7 @@ enum nsCSSUnit { // allowed. eCSSUnit_HSLColor = 89, // (nsCSSValueFloatColor*) eCSSUnit_HSLAColor = 90, // (nsCSSValueFloatColor*) + eCSSUnit_ComplexColor = 91, // (ComplexColorValue*) eCSSUnit_Percent = 100, // (float) 1.0 == 100%) value is percentage of something eCSSUnit_Number = 101, // (float) value is numeric (usually multiplier, different behavior than percent) @@ -641,6 +739,11 @@ public: nscolor GetColorValue() const; bool IsNonTransparentColor() const; + mozilla::StyleComplexColor GetStyleComplexColorValue() const + { + MOZ_ASSERT(mUnit == eCSSUnit_ComplexColor); + return mValue.mComplexColor->ToComplexColor(); + } Array* GetArrayValue() const { @@ -771,6 +874,9 @@ public: float aComponent2, float aComponent3, float aAlpha, nsCSSUnit aUnit); + void SetRGBAColorValue(const mozilla::css::RGBAColorData& aValue); + void SetComplexColorValue( + already_AddRefed aValue); void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit); void SetURLValue(mozilla::css::URLValue* aURI); void SetImageValue(mozilla::css::ImageValue* aImage); @@ -878,6 +984,7 @@ protected: nsCSSValuePairList* mPairListDependent; nsCSSValueFloatColor* MOZ_OWNING_REF mFloatColor; mozilla::css::FontFamilyListRefCnt* MOZ_OWNING_REF mFontFamilyList; + mozilla::css::ComplexColorValue* MOZ_OWNING_REF mComplexColor; } mValue; }; diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 09b006744480..669ce277e598 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -957,6 +957,13 @@ nsComputedDOMStyle::SetToRGBAColor(nsROCSSPrimitiveValue* aValue, aValue->SetColor(rgbColor); } +void +nsComputedDOMStyle::SetValueFromComplexColor(nsROCSSPrimitiveValue* aValue, + const StyleComplexColor& aColor) +{ + SetToRGBAColor(aValue, StyleColor()->CalcComplexColor(aColor)); +} + already_AddRefed nsComputedDOMStyle::DoGetColor() { @@ -3828,10 +3835,7 @@ already_AddRefed nsComputedDOMStyle::DoGetTextEmphasisColor() { RefPtr val = new nsROCSSPrimitiveValue; - const nsStyleText* text = StyleText(); - nscolor color = text->mTextEmphasisColorForeground ? - StyleColor()->mColor : text->mTextEmphasisColor; - SetToRGBAColor(val, color); + SetValueFromComplexColor(val, StyleText()->mTextEmphasisColor); return val.forget(); } @@ -4076,7 +4080,7 @@ already_AddRefed nsComputedDOMStyle::DoGetWebkitTextFillColor() { RefPtr val = new nsROCSSPrimitiveValue; - SetToRGBAColor(val, mStyleContext->GetTextFillColor()); + SetValueFromComplexColor(val, StyleText()->mWebkitTextFillColor); return val.forget(); } @@ -4084,7 +4088,7 @@ already_AddRefed nsComputedDOMStyle::DoGetWebkitTextStrokeColor() { RefPtr val = new nsROCSSPrimitiveValue; - SetToRGBAColor(val, mStyleContext->GetTextStrokeColor()); + SetValueFromComplexColor(val, StyleText()->mWebkitTextStrokeColor); return val.forget(); } diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 60c7fef53f04..cd404594498d 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -11,6 +11,7 @@ #include "mozilla/ArenaRefPtr.h" #include "mozilla/ArenaRefPtrInlines.h" #include "mozilla/Attributes.h" +#include "mozilla/StyleComplexColor.h" #include "nsCOMPtr.h" #include "nscore.h" #include "nsCSSProps.h" @@ -583,6 +584,8 @@ private: /* Helper functions */ void SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor); + void SetValueFromComplexColor(nsROCSSPrimitiveValue* aValue, + const mozilla::StyleComplexColor& aColor); void SetValueToStyleImage(const nsStyleImage& aStyleImage, nsROCSSPrimitiveValue* aValue); void SetValueToPositionCoord(const mozilla::Position::Coord& aCoord, diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 4160a00b4d1c..76748174bc6e 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -75,6 +75,16 @@ using std::min; using namespace mozilla; using namespace mozilla::dom; +namespace mozilla { + +enum UnsetAction +{ + eUnsetInitial, + eUnsetInherit +}; + +} // namespace mozilla + void* nsConditionalResetStyleData::GetConditionalStyleData(nsStyleStructID aSID, nsStyleContext* aStyleContext) const @@ -1091,6 +1101,41 @@ static bool SetColor(const nsCSSValue& aValue, const nscolor aParentColor, return result; } +template +static void +SetComplexColor(const nsCSSValue& aValue, + const StyleComplexColor& aParentColor, + const StyleComplexColor& aInitialColor, + nsPresContext* aPresContext, + StyleComplexColor& aResult, + RuleNodeCacheConditions& aConditions) +{ + nsCSSUnit unit = aValue.GetUnit(); + if (unit == eCSSUnit_Null) { + return; + } + if (unit == eCSSUnit_Initial || + (UnsetTo == eUnsetInitial && unit == eCSSUnit_Unset)) { + aResult = aInitialColor; + } else if (unit == eCSSUnit_Inherit || + (UnsetTo == eUnsetInherit && unit == eCSSUnit_Unset)) { + aConditions.SetUncacheable(); + aResult = aParentColor; + } else if (unit == eCSSUnit_EnumColor && + aValue.GetIntValue() == NS_COLOR_CURRENTCOLOR) { + aResult = StyleComplexColor::CurrentColor(); + } else if (unit == eCSSUnit_ComplexColor) { + aResult = aValue.GetStyleComplexColorValue(); + } else { + if (!SetColor(aValue, aParentColor.mColor, aPresContext, + nullptr, aResult.mColor, aConditions)) { + MOZ_ASSERT_UNREACHABLE("Unknown color value"); + return; + } + aResult.mForegroundRatio = 0; + } +} + static void SetGradientCoord(const nsCSSValue& aValue, nsPresContext* aPresContext, nsStyleContext* aContext, nsStyleCoord& aResult, RuleNodeCacheConditions& aConditions) @@ -4473,6 +4518,13 @@ nsRuleNode::ComputeTextData(void* aStartStruct, { COMPUTE_START_INHERITED(Text, text, parentText) + auto setComplexColor = [&](const nsCSSValue* aValue, + StyleComplexColor nsStyleText::* aField) { + SetComplexColor(*aValue, parentText->*aField, + StyleComplexColor::CurrentColor(), + mPresContext, text->*aField, conditions); + }; + // tab-size: integer, inherit SetValue(*aRuleData->ValueForTabSize(), text->mTabSize, conditions, @@ -4716,26 +4768,8 @@ nsRuleNode::ComputeTextData(void* aStartStruct, NS_STYLE_TEXT_COMBINE_UPRIGHT_NONE); // text-emphasis-color: color, string, inherit, initial - const nsCSSValue* - textEmphasisColorValue = aRuleData->ValueForTextEmphasisColor(); - if (textEmphasisColorValue->GetUnit() == eCSSUnit_Null) { - // We don't want to change anything in this case. - } else if (textEmphasisColorValue->GetUnit() == eCSSUnit_Inherit || - textEmphasisColorValue->GetUnit() == eCSSUnit_Unset) { - conditions.SetUncacheable(); - text->mTextEmphasisColorForeground = - parentText->mTextEmphasisColorForeground; - text->mTextEmphasisColor = parentText->mTextEmphasisColor; - } else if ((textEmphasisColorValue->GetUnit() == eCSSUnit_EnumColor && - textEmphasisColorValue->GetIntValue() == NS_COLOR_CURRENTCOLOR) || - textEmphasisColorValue->GetUnit() == eCSSUnit_Initial) { - text->mTextEmphasisColorForeground = true; - text->mTextEmphasisColor = mPresContext->DefaultColor(); - } else { - text->mTextEmphasisColorForeground = false; - SetColor(*textEmphasisColorValue, 0, mPresContext, aContext, - text->mTextEmphasisColor, conditions); - } + setComplexColor(aRuleData->ValueForTextEmphasisColor(), + &nsStyleText::mTextEmphasisColor); // text-emphasis-position: enum, inherit, initial SetValue(*aRuleData->ValueForTextEmphasisPosition(), @@ -4809,47 +4843,12 @@ nsRuleNode::ComputeTextData(void* aStartStruct, NS_STYLE_TEXT_RENDERING_AUTO); // -webkit-text-fill-color: color, string, inherit, initial - const nsCSSValue* - webkitTextFillColorValue = aRuleData->ValueForWebkitTextFillColor(); - if (webkitTextFillColorValue->GetUnit() == eCSSUnit_Null) { - // We don't want to change anything in this case. - } else if (webkitTextFillColorValue->GetUnit() == eCSSUnit_Inherit || - webkitTextFillColorValue->GetUnit() == eCSSUnit_Unset) { - conditions.SetUncacheable(); - text->mWebkitTextFillColorForeground = parentText->mWebkitTextFillColorForeground; - text->mWebkitTextFillColor = parentText->mWebkitTextFillColor; - } else if ((webkitTextFillColorValue->GetUnit() == eCSSUnit_EnumColor && - webkitTextFillColorValue->GetIntValue() == NS_COLOR_CURRENTCOLOR) || - webkitTextFillColorValue->GetUnit() == eCSSUnit_Initial) { - text->mWebkitTextFillColorForeground = true; - text->mWebkitTextFillColor = mPresContext->DefaultColor(); - } else { - text->mWebkitTextFillColorForeground = false; - SetColor(*webkitTextFillColorValue, 0, mPresContext, aContext, - text->mWebkitTextFillColor, conditions); - } + setComplexColor(aRuleData->ValueForWebkitTextFillColor(), + &nsStyleText::mWebkitTextFillColor); // -webkit-text-stroke-color: color, string, inherit, initial - const nsCSSValue* webkitTextStrokeColorValue = - aRuleData->ValueForWebkitTextStrokeColor(); - if (webkitTextStrokeColorValue->GetUnit() == eCSSUnit_Null) { - // We don't want to change anything in this case. - } else if (webkitTextStrokeColorValue->GetUnit() == eCSSUnit_Inherit || - webkitTextStrokeColorValue->GetUnit() == eCSSUnit_Unset) { - conditions.SetUncacheable(); - text->mWebkitTextStrokeColorForeground = - parentText->mWebkitTextStrokeColorForeground; - text->mWebkitTextStrokeColor = parentText->mWebkitTextStrokeColor; - } else if ((webkitTextStrokeColorValue->GetUnit() == eCSSUnit_EnumColor && - webkitTextStrokeColorValue->GetIntValue() == NS_COLOR_CURRENTCOLOR) || - webkitTextStrokeColorValue->GetUnit() == eCSSUnit_Initial) { - text->mWebkitTextStrokeColorForeground = true; - text->mWebkitTextStrokeColor = mPresContext->DefaultColor(); - } else { - text->mWebkitTextStrokeColorForeground = false; - SetColor(*webkitTextStrokeColorValue, 0, mPresContext, aContext, - text->mWebkitTextStrokeColor, conditions); - } + setComplexColor(aRuleData->ValueForWebkitTextStrokeColor(), + &nsStyleText::mWebkitTextStrokeColor); // -webkit-text-stroke-width: length, inherit, initial, enum const nsCSSValue* diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 15d1fcc1fa81..366e54520e62 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -7,6 +7,7 @@ #include "CSSVariableImageTable.h" #include "mozilla/DebugOnly.h" +#include "mozilla/Maybe.h" #include "nsCSSAnonBoxes.h" #include "nsCSSPseudoElements.h" @@ -1221,14 +1222,8 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, if (!change && PeekStyleText()) { const nsStyleText* thisVisText = thisVis->StyleText(); const nsStyleText* otherVisText = otherVis->StyleText(); - if (thisVisText->mTextEmphasisColorForeground != - otherVisText->mTextEmphasisColorForeground || - thisVisText->mTextEmphasisColor != otherVisText->mTextEmphasisColor || - thisVisText->mWebkitTextFillColorForeground != - otherVisText->mWebkitTextFillColorForeground || + if (thisVisText->mTextEmphasisColor != otherVisText->mTextEmphasisColor || thisVisText->mWebkitTextFillColor != otherVisText->mWebkitTextFillColor || - thisVisText->mWebkitTextStrokeColorForeground != - otherVisText->mWebkitTextStrokeColorForeground || thisVisText->mWebkitTextStrokeColor != otherVisText->mWebkitTextStrokeColor) { change = true; } @@ -1481,29 +1476,30 @@ ExtractAnimationValue(nsCSSPropertyID aProperty, "aProperty must be extractable by StyleAnimationValue"); } -static nscolor +static Maybe ExtractColor(nsCSSPropertyID aProperty, nsStyleContext *aStyleContext) { StyleAnimationValue val; ExtractAnimationValue(aProperty, aStyleContext, val); - return val.GetUnit() == StyleAnimationValue::eUnit_CurrentColor - ? aStyleContext->StyleColor()->mColor - : val.GetCSSValueValue()->GetColorValue(); + switch (val.GetUnit()) { + case StyleAnimationValue::eUnit_Color: + return Some(val.GetCSSValueValue()->GetColorValue()); + case StyleAnimationValue::eUnit_CurrentColor: + return Some(aStyleContext->StyleColor()->mColor); + case StyleAnimationValue::eUnit_ComplexColor: + return Some(aStyleContext->StyleColor()-> + CalcComplexColor(val.GetStyleComplexColorValue())); + default: + return Nothing(); + } } static nscolor ExtractColorLenient(nsCSSPropertyID aProperty, nsStyleContext *aStyleContext) { - StyleAnimationValue val; - ExtractAnimationValue(aProperty, aStyleContext, val); - if (val.GetUnit() == StyleAnimationValue::eUnit_Color) { - return val.GetCSSValueValue()->GetColorValue(); - } else if (val.GetUnit() == StyleAnimationValue::eUnit_CurrentColor) { - return aStyleContext->StyleColor()->mColor; - } - return NS_RGBA(0, 0, 0, 0); + return ExtractColor(aProperty, aStyleContext).valueOr(NS_RGBA(0, 0, 0, 0)); } struct ColorIndexSet { @@ -1536,7 +1532,7 @@ nsStyleContext::GetVisitedDependentColor(nsCSSPropertyID aProperty) nscolor colors[2]; colors[0] = isPaintProperty ? ExtractColorLenient(aProperty, this) - : ExtractColor(aProperty, this); + : ExtractColor(aProperty, this).value(); nsStyleContext *visitedStyle = this->GetStyleIfVisited(); if (!visitedStyle) { @@ -1544,7 +1540,7 @@ nsStyleContext::GetVisitedDependentColor(nsCSSPropertyID aProperty) } colors[1] = isPaintProperty ? ExtractColorLenient(aProperty, visitedStyle) - : ExtractColor(aProperty, visitedStyle); + : ExtractColor(aProperty, visitedStyle).value(); return nsStyleContext::CombineVisitedColors(colors, this->RelevantLinkVisited()); diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 9e5bf5895e8b..2c9fbfbdd7ab 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -178,32 +178,6 @@ public: mozilla::NonOwningStyleContextSource aSource, mozilla::NonOwningStyleContextSource aSourceIfVisited, bool aRelevantLinkVisited); - /** - * Get the color property that should be used to fill text. - */ - nsCSSPropertyID GetTextFillColorProp() { - return StyleText()->mWebkitTextFillColorForeground - ? eCSSProperty_color : eCSSProperty__webkit_text_fill_color; - } - - /** - * Get the color that should be used to fill text: either - * the current foreground color, or a separately-specified text fill color. - */ - nscolor GetTextFillColor() { - return (GetTextFillColorProp() == eCSSProperty_color) - ? StyleColor()->mColor : StyleText()->mWebkitTextFillColor; - } - - /** - * Get the color that should be used to stroke text: either - * the current foreground color, or a separately-specified text stroke color. - */ - nscolor GetTextStrokeColor() { - const nsStyleText* textStyle = StyleText(); - return textStyle->mWebkitTextStrokeColorForeground - ? StyleColor()->mColor : textStyle->mWebkitTextStrokeColor; - } // Does this style context or any of its ancestors have text // decoration lines? diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 32ef718112ab..904ff53480bf 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -3679,9 +3679,6 @@ nsStyleText::nsStyleText(StyleStructContext aContext) , mTextAlignLast(NS_STYLE_TEXT_ALIGN_AUTO) , mTextAlignTrue(false) , mTextAlignLastTrue(false) - , mTextEmphasisColorForeground(true) - , mWebkitTextFillColorForeground(true) - , mWebkitTextStrokeColorForeground(true) , mTextTransform(NS_STYLE_TEXT_TRANSFORM_NONE) , mWhiteSpace(NS_STYLE_WHITESPACE_NORMAL) , mWordBreak(NS_STYLE_WORDBREAK_NORMAL) @@ -3695,9 +3692,9 @@ nsStyleText::nsStyleText(StyleStructContext aContext) , mTextEmphasisStyle(NS_STYLE_TEXT_EMPHASIS_STYLE_NONE) , mTextRendering(NS_STYLE_TEXT_RENDERING_AUTO) , mTabSize(NS_STYLE_TABSIZE_INITIAL) - , mTextEmphasisColor(aContext.DefaultColor()) - , mWebkitTextFillColor(aContext.DefaultColor()) - , mWebkitTextStrokeColor(aContext.DefaultColor()) + , mTextEmphasisColor(StyleComplexColor::CurrentColor()) + , mWebkitTextFillColor(StyleComplexColor::CurrentColor()) + , mWebkitTextStrokeColor(StyleComplexColor::CurrentColor()) , mWordSpacing(0, nsStyleCoord::CoordConstructor) , mLetterSpacing(eStyleUnit_Normal) , mLineHeight(eStyleUnit_Normal) @@ -3718,9 +3715,6 @@ nsStyleText::nsStyleText(const nsStyleText& aSource) , mTextAlignLast(aSource.mTextAlignLast) , mTextAlignTrue(false) , mTextAlignLastTrue(false) - , mTextEmphasisColorForeground(aSource.mTextEmphasisColorForeground) - , mWebkitTextFillColorForeground(aSource.mWebkitTextFillColorForeground) - , mWebkitTextStrokeColorForeground(aSource.mWebkitTextStrokeColorForeground) , mTextTransform(aSource.mTextTransform) , mWhiteSpace(aSource.mWhiteSpace) , mWordBreak(aSource.mWordBreak) @@ -3818,16 +3812,8 @@ nsStyleText::CalcDifference(const nsStyleText& aNewData) const return hint; } - MOZ_ASSERT(!mTextEmphasisColorForeground || - !aNewData.mTextEmphasisColorForeground || - mTextEmphasisColor == aNewData.mTextEmphasisColor, - "If the text-emphasis-color are both foreground color, " - "mTextEmphasisColor should also be identical"); - if (mTextEmphasisColorForeground != aNewData.mTextEmphasisColorForeground || - mTextEmphasisColor != aNewData.mTextEmphasisColor || - mWebkitTextFillColorForeground != aNewData.mWebkitTextFillColorForeground || + if (mTextEmphasisColor != aNewData.mTextEmphasisColor || mWebkitTextFillColor != aNewData.mWebkitTextFillColor || - mWebkitTextStrokeColorForeground != aNewData.mWebkitTextStrokeColorForeground || mWebkitTextStrokeColor != aNewData.mWebkitTextStrokeColor) { hint |= nsChangeHint_SchedulePaint | nsChangeHint_RepaintFrame; diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 2586439c34e6..0ad6fd9a68e7 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -18,6 +18,7 @@ #include "mozilla/Maybe.h" #include "mozilla/SheetType.h" #include "mozilla/StaticPtr.h" +#include "mozilla/StyleComplexColor.h" #include "mozilla/StyleStructContext.h" #include "mozilla/UniquePtr.h" #include "nsColor.h" @@ -480,6 +481,11 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColor MOZ_COUNT_DTOR(nsStyleColor); } + nscolor CalcComplexColor(const mozilla::StyleComplexColor& aColor) const { + return mozilla::LinearBlendColors(aColor.mColor, mColor, + aColor.mForegroundRatio); + } + nsChangeHint CalcDifference(const nsStyleColor& aNewData) const; static nsChangeHint MaxDifference() { return nsChangeHint_RepaintFrame; @@ -2084,9 +2090,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText uint8_t mTextAlignLast; // [inherited] see nsStyleConsts.h bool mTextAlignTrue : 1; // [inherited] see nsStyleConsts.h bool mTextAlignLastTrue : 1; // [inherited] see nsStyleConsts.h - bool mTextEmphasisColorForeground : 1;// [inherited] whether text-emphasis-color is currentColor - bool mWebkitTextFillColorForeground : 1; // [inherited] whether -webkit-text-fill-color is currentColor - bool mWebkitTextStrokeColorForeground : 1; // [inherited] whether -webkit-text-stroke-color is currentColor uint8_t mTextTransform; // [inherited] see nsStyleConsts.h uint8_t mWhiteSpace; // [inherited] see nsStyleConsts.h uint8_t mWordBreak; // [inherited] see nsStyleConsts.h @@ -2101,9 +2104,9 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText uint8_t mTextEmphasisStyle; // [inherited] see nsStyleConsts.h uint8_t mTextRendering; // [inherited] see nsStyleConsts.h int32_t mTabSize; // [inherited] see nsStyleConsts.h - nscolor mTextEmphasisColor; // [inherited] - nscolor mWebkitTextFillColor; // [inherited] - nscolor mWebkitTextStrokeColor; // [inherited] + mozilla::StyleComplexColor mTextEmphasisColor; // [inherited] + mozilla::StyleComplexColor mWebkitTextFillColor; // [inherited] + mozilla::StyleComplexColor mWebkitTextStrokeColor; // [inherited] nsStyleCoord mWordSpacing; // [inherited] coord, percent, calc nsStyleCoord mLetterSpacing; // [inherited] coord, normal diff --git a/layout/style/test/test_transitions_per_property.html b/layout/style/test/test_transitions_per_property.html index a506fd8db388..6061e989736b 100644 --- a/layout/style/test/test_transitions_per_property.html +++ b/layout/style/test/test_transitions_per_property.html @@ -265,7 +265,8 @@ var supported_properties = { "text-decoration-color": [ test_color_transition, test_currentcolor_transition, test_border_color_transition ], - "text-emphasis-color": [ test_color_transition ], + "text-emphasis-color": [ test_color_transition, + test_true_currentcolor_transition ], "text-indent": [ test_length_transition, test_percent_transition, test_length_percent_calc_transition, test_length_unclamped, test_percent_unclamped ], @@ -286,8 +287,10 @@ var supported_properties = { test_length_clamped, test_percent_clamped ], "word-spacing": [ test_length_transition, test_length_unclamped ], "z-index": [ test_integer_transition, test_pos_integer_or_auto_transition ], - "-webkit-text-fill-color": [ test_color_transition ], - "-webkit-text-stroke-color": [ test_color_transition ] + "-webkit-text-fill-color": [ test_color_transition, + test_true_currentcolor_transition ], + "-webkit-text-stroke-color": [ test_color_transition, + test_true_currentcolor_transition ] }; if (SupportsMaskShorthand()) { @@ -1329,6 +1332,47 @@ function test_currentcolor_transition(prop, get_color=(x => x), is_shorthand=fal (prop == "color" ? div.parentNode : div).style.removeProperty("color"); } +function test_true_currentcolor_transition(prop, get_color=(x => x), is_shorthand=false) { + const msg_prefix = `color-valued property ${prop}: `; + div.style.setProperty("transition-property", "none", ""); + div.style.setProperty("color", "rgb(128, 0, 0)", ""); + div.style.setProperty(prop, "rgb(0, 0, 128)", ""); + is(get_color(cs.getPropertyValue(prop)), "rgb(0, 0, 128)", + msg_prefix + "computed value before transition"); + div.style.setProperty("transition-property", prop, ""); + div.style.setProperty(prop, "currentcolor", ""); + is(get_color(cs.getPropertyValue(prop)), "rgb(32, 0, 96)", + msg_prefix + "interpolation of rgb color and currentcolor"); + + div.style.setProperty("transition-property", "none", ""); + div.style.setProperty("color", "rgb(128, 0, 0)", ""); + div.style.setProperty(prop, "rgb(0, 0, 128)", ""); + is(get_color(cs.getPropertyValue(prop)), "rgb(0, 0, 128)", + msg_prefix + "computed value before transition"); + div.style.setProperty("transition-property", `color, ${prop}`, ""); + div.style.setProperty("color", "rgb(0, 128, 0)", ""); + div.style.setProperty(prop, "currentcolor", ""); + is(cs.getPropertyValue("color"), "rgb(96, 32, 0)", + "interpolation of rgb color property"); + is(get_color(cs.getPropertyValue(prop)), "rgb(24, 8, 96)", + msg_prefix + "interpolation of rgb color and interpolated currentcolor"); + + div.style.setProperty("transition-property", "none", ""); + div.style.setProperty("color", "rgba(128, 0, 0, 0.1)", ""); + div.style.setProperty(prop, "rgba(0, 0, 128, 0.9)", ""); + is(get_color(cs.getPropertyValue(prop)), "rgba(0, 0, 128, 0.9)", + msg_prefix + "computed value before transition"); + div.style.setProperty("transition-property", prop, ""); + div.style.setProperty(prop, "currentcolor", ""); + is(get_color(cs.getPropertyValue(prop)), "rgba(5, 0, 123, 0.7)", + msg_prefix + "interpolation of rgba color and currentcolor"); + + // It is not possible to check distance, because there is a hidden + // dimension for ratio of currentcolor. + + div.style.removeProperty("color"); +} + function test_border_color_transition(prop, get_color=(x => x), is_shorthand=false) { div.style.setProperty("transition-property", "none", ""); div.style.setProperty(prop, "rgb(128, 64, 0)", ""); diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc b/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc index 6c9295a1c9f2..b3957706d896 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc +++ b/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc @@ -29,6 +29,8 @@ #include "webrtc/system_wrappers/interface/ref_count.h" #include "webrtc/system_wrappers/interface/trace.h" +#define EVENT_SIZE ( sizeof (struct inotify_event) ) +#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) namespace webrtc { @@ -47,9 +49,128 @@ VideoCaptureImpl::CreateDeviceInfo(const int32_t id) return deviceInfo; } +void DeviceInfoLinux::HandleEvent(inotify_event* event) +{ + switch (event->mask) { + case IN_CREATE: + DeviceChange(); + break; + case IN_DELETE: + DeviceChange(); + break; + default: + char* cur_event_filename = NULL; + int cur_event_wd = event->wd; + if (event->len) { + cur_event_filename = event->name; + } + + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, + "UNKNOWN EVENT OCCURRED for file \"%s\" on WD #%i\n", + cur_event_filename, cur_event_wd); + break; + } +} + +int DeviceInfoLinux::EventCheck() +{ + struct timeval timeout; + fd_set rfds; + + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + + FD_ZERO(&rfds); + FD_SET(_fd, &rfds); + + return select(_fd+1, &rfds, NULL, NULL, &timeout); +} + +int DeviceInfoLinux::HandleEvents() +{ + char buffer[BUF_LEN]; + + ssize_t r = read(_fd, buffer, BUF_LEN); + + if (r <= 0) { + return r; + } + + ssize_t buffer_i = 0; + inotify_event* pevent; + size_t eventSize; + int count = 0; + + while (buffer_i < r) + { + pevent = (inotify_event *) (&buffer[buffer_i]); + eventSize = sizeof(inotify_event) + pevent->len; + char event[sizeof(inotify_event) + FILENAME_MAX + 1] // null-terminated + __attribute__ ((aligned(__alignof__(struct inotify_event)))); + + memcpy(event, pevent, eventSize); + + HandleEvent((inotify_event*)(event)); + + buffer_i += eventSize; + count++; + } + + return count; +} + +int DeviceInfoLinux::ProcessInotifyEvents() +{ + while (0 == _isShutdown.Value()) { + if (EventCheck() > 0) { + if (HandleEvents() < 0) { + break; + } + } + } + return 0; +} + +bool DeviceInfoLinux::InotifyEventThread(void* obj) +{ + return static_cast (obj)->InotifyProcess(); +} + +bool DeviceInfoLinux::InotifyProcess() +{ + _fd = inotify_init(); + if (_fd >= 0) { + _wd_v4l = inotify_add_watch(_fd, "/dev/v4l/by-path/", IN_CREATE | IN_DELETE); + _wd_snd = inotify_add_watch(_fd, "/dev/snd/by-path/", IN_CREATE | IN_DELETE); + ProcessInotifyEvents(); + + if (_wd_v4l >= 0) { + inotify_rm_watch(_fd, _wd_v4l); + } + + if (_wd_snd >= 0) { + inotify_rm_watch(_fd, _wd_snd); + } + + close(_fd); + return true; + } else { + return false; + } +} + DeviceInfoLinux::DeviceInfoLinux(const int32_t id) : DeviceInfoImpl(id) + , _isShutdown(0) { + _inotifyEventThread = ThreadWrapper::CreateThread( + InotifyEventThread, this, "InotifyEventThread"); + + if (_inotifyEventThread) + { + _inotifyEventThread->Start(); + _inotifyEventThread->SetPriority(kHighPriority); + } } int32_t DeviceInfoLinux::Init() @@ -59,6 +180,12 @@ int32_t DeviceInfoLinux::Init() DeviceInfoLinux::~DeviceInfoLinux() { + ++_isShutdown; + + if (_inotifyEventThread) { + _inotifyEventThread->Stop(); + _inotifyEventThread.reset(); + } } uint32_t DeviceInfoLinux::NumberOfDevices() diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.h b/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.h index cffb22256ce2..9261a17f81bd 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.h +++ b/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.h @@ -13,6 +13,9 @@ #include "webrtc/modules/video_capture/device_info_impl.h" #include "webrtc/modules/video_capture/video_capture_impl.h" +#include "webrtc/system_wrappers/interface/thread_wrapper.h" +#include "webrtc/system_wrappers/interface/atomic32.h" +#include namespace webrtc { @@ -47,6 +50,16 @@ public: private: bool IsDeviceNameMatches(const char* name, const char* deviceUniqueIdUTF8); + + void HandleEvent(inotify_event* event); + int EventCheck(); + int HandleEvents(); + int ProcessInotifyEvents(); + rtc::scoped_ptr _inotifyEventThread; + static bool InotifyEventThread(void*); + bool InotifyProcess(); + int _fd, _wd_v4l, _wd_snd; /* accessed on InotifyEventThread thread */ + Atomic32 _isShutdown; }; } // namespace videocapturemodule } // namespace webrtc diff --git a/mobile/android/base/AndroidManifest.xml.in b/mobile/android/base/AndroidManifest.xml.in index 7ede86a6f1a6..4b5ebc90d415 100644 --- a/mobile/android/base/AndroidManifest.xml.in +++ b/mobile/android/base/AndroidManifest.xml.in @@ -421,7 +421,7 @@ #endif mProxies = new LinkedList(); - private volatile ICodecManager mRemote; + private volatile IMediaManager mRemote; private volatile CountDownLatch mConnectionLatch; private final ServiceConnection mConnection = new ServiceConnection() { @Override @@ -48,7 +48,7 @@ public final class RemoteManager implements IBinder.DeathRecipient { } catch (RemoteException e) { e.printStackTrace(); } - mRemote = ICodecManager.Stub.asInterface(service); + mRemote = IMediaManager.Stub.asInterface(service); if (mConnectionLatch != null) { mConnectionLatch.countDown(); } @@ -83,7 +83,7 @@ public final class RemoteManager implements IBinder.DeathRecipient { if (DEBUG) Log.d(LOGTAG, "init remote manager " + this); Context appCtxt = GeckoAppShell.getApplicationContext(); if (DEBUG) Log.d(LOGTAG, "ctxt=" + appCtxt); - appCtxt.bindService(new Intent(appCtxt, CodecManager.class), + appCtxt.bindService(new Intent(appCtxt, MediaManager.class), mConnection, Context.BIND_AUTO_CREATE); if (!waitConnection()) { appCtxt.unbindService(mConnection); diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build index 678a59034ab5..81e5cc6cfbd0 100644 --- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -557,11 +557,11 @@ gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [ 'media/AsyncCodecFactory.java', 'media/AudioFocusAgent.java', 'media/Codec.java', - 'media/CodecManager.java', 'media/CodecProxy.java', 'media/FormatParam.java', 'media/JellyBeanAsyncCodec.java', 'media/MediaControlService.java', + 'media/MediaManager.java', 'media/RemoteManager.java', 'media/Sample.java', 'media/VideoPlayer.java', @@ -1109,5 +1109,5 @@ OBJDIR_PP_FILES.mobile.android.base += [ gbjar.sources += ['generated/org/mozilla/gecko/' + x for x in [ 'media/ICodec.java', 'media/ICodecCallbacks.java', - 'media/ICodecManager.java', + 'media/IMediaManager.java', ]] diff --git a/services/sync/modules/bookmark_validator.js b/services/sync/modules/bookmark_validator.js index 81db5d9373b8..b1ce1bade573 100644 --- a/services/sync/modules/bookmark_validator.js +++ b/services/sync/modules/bookmark_validator.js @@ -21,7 +21,8 @@ this.EXPORTED_SYMBOLS = ["BookmarkValidator", "BookmarkProblemData"]; * - parentChildMismatches (array of {parent: parentid, child: childid}): * instances where the child's parentid and the parent's children array * do not match - * - cycles (array of array of ids). List of cycles found in the "tree". + * - cycles (array of array of ids). List of cycles found in the server-side tree. + * - clientCycles (array of array of ids). List of cycles found in the client-side tree. * - orphans (array of {id: string, parent: string}): List of nodes with * either no parentid, or where the parent could not be found. * - missingChildren (array of {parent: id, child: id}): @@ -61,6 +62,7 @@ class BookmarkProblemData { this.duplicates = []; this.parentChildMismatches = []; this.cycles = []; + this.clientCycles = []; this.orphans = []; this.missingChildren = []; this.deletedChildren = []; @@ -102,6 +104,7 @@ class BookmarkProblemData { { name: "duplicates", count: this.duplicates.length }, { name: "parentChildMismatches", count: this.parentChildMismatches.length }, { name: "cycles", count: this.cycles.length }, + { name: "clientCycles", count: this.clientCycles.length }, { name: "orphans", count: this.orphans.length }, { name: "missingChildren", count: this.missingChildren.length }, { name: "deletedChildren", count: this.deletedChildren.length }, @@ -117,10 +120,60 @@ class BookmarkProblemData { class BookmarkValidator { + _followQueries(recordMap) { + for (let [guid, entry] of recordMap) { + if (entry.type !== "query" && (!entry.bmkUri || !entry.bmkUri.startsWith("place:"))) { + continue; + } + // Might be worth trying to parse the place: query instead so that this + // works "automatically" with things like aboutsync. + let queryNodeParent = PlacesUtils.getFolderContents(entry, false, true); + if (!queryNodeParent || !queryNodeParent.root.hasChildren) { + continue; + } + queryNodeParent = queryNodeParent.root; + let queryNode = null; + let numSiblings = 0; + let containerWasOpen = queryNodeParent.containerOpen; + queryNodeParent.containerOpen = true; + try { + try { + numSiblings = queryNodeParent.childCount; + } catch (e) { + // This throws when we can't actually get the children. This is the + // case for history containers, tag queries, ... + continue; + } + for (let i = 0; i < numSiblings && !queryNode; ++i) { + let child = queryNodeParent.getChild(i); + if (child && child.bookmarkGuid && child.bookmarkGuid === guid) { + queryNode = child; + } + } + } finally { + queryNodeParent.containerOpen = containerWasOpen; + } + if (!queryNode) { + continue; + } + + let concreteId = PlacesUtils.getConcreteItemGuid(queryNode); + if (!concreteId) { + continue; + } + let concreteItem = recordMap.get(concreteId); + if (!concreteItem) { + continue; + } + entry.concrete = concreteItem; + } + } + createClientRecordsFromTree(clientTree) { // Iterate over the treeNode, converting it to something more similar to what // the server stores. let records = []; + let recordsByGuid = new Map(); function traverse(treeNode) { let guid = BookmarkSpecialIds.specialGUIDForId(treeNode.id) || treeNode.guid; let itemType = 'item'; @@ -168,6 +221,8 @@ class BookmarkValidator { treeNode.pos = treeNode.index; treeNode.bmkUri = treeNode.uri; records.push(treeNode); + // We want to use the "real" guid here. + recordsByGuid.set(treeNode.guid, treeNode); if (treeNode.type === 'folder') { treeNode.childGUIDs = []; if (!treeNode.children) { @@ -184,6 +239,7 @@ class BookmarkValidator { } traverse(clientTree); clientTree.id = 'places'; + this._followQueries(recordsByGuid); return records; } @@ -473,15 +529,19 @@ class BookmarkValidator { cycles.push(cyclePath); return; } else if (seenEver.has(node)) { - // This is a problem, but we catch it earlier (multipleParents) + // If we're checking the server, this is a problem, but it should already be reported. + // On the client, this could happen due to including `node.concrete` in the child list. return; } seenEver.add(node); - - if (node.children) { + let children = node.children || []; + if (node.concrete) { + children.push(node.concrete); + } + if (children) { pathLookup.add(node); currentPath.push(node); - for (let child of node.children) { + for (let child of children) { traverse(child); } currentPath.pop(); @@ -517,6 +577,8 @@ class BookmarkValidator { serverRecords = inspectionInfo.records; let problemData = inspectionInfo.problemData; + problemData.clientCycles = this._detectCycles(clientRecords); + let matches = []; let allRecords = new Map(); diff --git a/taskcluster/ci/android-test/tests.yml b/taskcluster/ci/android-test/tests.yml index eb9af31155ba..5aa2de3474da 100644 --- a/taskcluster/ci/android-test/tests.yml +++ b/taskcluster/ci/android-test/tests.yml @@ -16,12 +16,12 @@ cppunit: e10s: false loopback-video: true mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=cppunittest @@ -37,12 +37,12 @@ crashtest: loopback-video: true e10s: false mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=crashtest @@ -59,12 +59,12 @@ jsreftest: max-run-time: 7200 e10s: false mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=jsreftest @@ -79,12 +79,12 @@ marionette: tier: 3 max-run-time: 3600 mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=marionette @@ -101,12 +101,12 @@ mochitest: android-4.3-arm7-api-15/debug: 10800 default: 3600 mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=mochitest @@ -123,12 +123,12 @@ mochitest-chrome: e10s: false max-run-time: 5400 mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=mochitest-chrome @@ -140,12 +140,12 @@ mochitest-clipboard: loopback-video: true e10s: false mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=mochitest-plain-clipboard @@ -156,12 +156,12 @@ mochitest-gpu: loopback-video: true e10s: false mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=mochitest-plain-gpu @@ -175,12 +175,12 @@ mochitest-media: e10s: false max-run-time: 5400 mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=mochitest-media @@ -194,12 +194,12 @@ mochitest-webgl: max-run-time: 7200 instance-size: xlarge mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=mochitest-gl @@ -216,12 +216,12 @@ reftest: loopback-video: true e10s: false mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=reftest @@ -238,12 +238,12 @@ robocop: loopback-video: true e10s: false mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true config: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py extra-options: - --test-suite=robocop @@ -260,15 +260,15 @@ xpcshell: loopback-video: true e10s: false mozharness: - script: mozharness/scripts/android_emulator_unittest.py + script: android_emulator_unittest.py no-read-buildbot-config: true extra-options: - --test-suite=xpcshell config: by-test-platform: default: - - mozharness/configs/android/androidarm_4_3.py - - mozharness/configs/remove_executables.py - - mozharness/configs/android/androidarm_4_3-tc.py + - android/androidarm_4_3.py + - remove_executables.py + - android/androidarm_4_3-tc.py android-4.2-x86/opt: - - mozharness/configs/android/androidx86-tc.py + - android/androidx86-tc.py diff --git a/taskcluster/ci/desktop-test/tests.yml b/taskcluster/ci/desktop-test/tests.yml index fb7693110a01..e5f9f014bf56 100644 --- a/taskcluster/ci/desktop-test/tests.yml +++ b/taskcluster/ci/desktop-test/tests.yml @@ -11,18 +11,18 @@ cppunit: treeherder-symbol: tc(Cpp) e10s: false mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true config: by-test-platform: # Coming soon: # win.*: - # - mozharness/configs/unittests/win_unittest.py - # - mozharness/configs/remove_executables.py + # - unittests/win_unittest.py + # - remove_executables.py # ... default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --cppunittest-suite=cppunittest @@ -31,14 +31,14 @@ crashtest: suite: reftest/crashtest treeherder-symbol: tc-R(C) mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py chunked: true no-read-buildbot-config: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --reftest-suite=crashtest @@ -50,11 +50,11 @@ external-media-tests: tier: 2 max-run-time: 5400 mozharness: - script: mozharness/scripts/firefox_media_tests_buildbot.py + script: firefox_media_tests_buildbot.py no-read-buildbot-config: true config: - - mozharness/configs/mediatests/buildbot_posix_config.py - - mozharness/configs/remove_executables.py + - mediatests/buildbot_posix_config.py + - remove_executables.py firefox-ui-functional-local: description: "Firefox-ui-tests functional run" @@ -64,10 +64,10 @@ firefox-ui-functional-local: tier: 1 docker-image: {"in-tree": "desktop1604-test"} mozharness: - script: mozharness/scripts/firefox_ui_tests/functional.py + script: firefox_ui_tests/functional.py config: - - mozharness/configs/firefox_ui_tests/taskcluster.py - - mozharness/configs/remove_executables.py + - firefox_ui_tests/taskcluster.py + - remove_executables.py extra-options: - "--tag local" @@ -79,10 +79,10 @@ firefox-ui-functional-remote: tier: 2 docker-image: {"in-tree": "desktop1604-test"} mozharness: - script: mozharness/scripts/firefox_ui_tests/functional.py + script: firefox_ui_tests/functional.py config: - - mozharness/configs/firefox_ui_tests/taskcluster.py - - mozharness/configs/remove_executables.py + - firefox_ui_tests/taskcluster.py + - remove_executables.py extra-options: - "--tag remote" @@ -93,13 +93,13 @@ gtest: e10s: false instance-size: xlarge mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --gtest-suite=gtest @@ -110,13 +110,13 @@ jittests: e10s: false chunks: 6 mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --jittest-suite=jittest-chunked @@ -126,13 +126,13 @@ jsreftest: treeherder-symbol: tc-R(J) chunks: 2 mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --reftest-suite=jsreftest @@ -142,11 +142,11 @@ marionette: treeherder-symbol: tc(Mn) max-run-time: 5400 mozharness: - script: mozharness/scripts/marionette.py + script: marionette.py no-read-buildbot-config: true config: - - mozharness/configs/marionette/prod_config.py - - mozharness/configs/remove_executables.py + - marionette/prod_config.py + - remove_executables.py mochitest: description: "Mochitest plain run" @@ -156,14 +156,14 @@ mochitest: chunks: 10 max-run-time: 5400 mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true chunked: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --mochitest-suite=plain-chunked # Bug 1281241: migrating to m3.large instances @@ -177,14 +177,14 @@ mochitest-a11y: loopback-video: true e10s: false mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true chunked: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --mochitest-suite=a11y @@ -199,13 +199,13 @@ mochitest-browser-chrome: linux64/debug: 5400 default: 3600 mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --mochitest-suite=browser-chrome-chunked # Bug 1281241: migrating to m3.large instances @@ -220,13 +220,13 @@ mochitest-chrome: chunks: 3 e10s: false mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --mochitest-suite=chrome @@ -237,14 +237,14 @@ mochitest-clipboard: loopback-video: true instance-size: xlarge mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true chunked: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --mochitest-suite=plain-clipboard,chrome-clipboard,browser-chrome-clipboard,jetpack-package-clipboard @@ -261,13 +261,13 @@ mochitest-devtools-chrome: linux64/debug: false default: both mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --mochitest-suite=mochitest-devtools-chrome-chunked instance-size: @@ -284,14 +284,14 @@ mochitest-gpu: treeherder-symbol: tc-M(gpu) loopback-video: true mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true chunked: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --mochitest-suite=plain-gpu,chrome-gpu,browser-chrome-gpu @@ -303,14 +303,14 @@ mochitest-jetpack: e10s: false max-run-time: 5400 mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true chunked: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --mochitest-suite=jetpack-package @@ -323,14 +323,14 @@ mochitest-media: instance-size: large docker-image: {"in-tree": "desktop1604-test"} mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true chunked: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --mochitest-suite=mochitest-media @@ -341,14 +341,14 @@ mochitest-webgl: chunks: 3 loopback-video: true mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true chunked: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --mochitest-suite=mochitest-gl # Bug 1296733: llvmpipe with mesa 9.2.1 lacks thread safety @@ -360,13 +360,13 @@ reftest: treeherder-symbol: tc-R(R) chunks: 8 mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --reftest-suite=reftest @@ -376,13 +376,13 @@ reftest-no-accel: treeherder-symbol: tc-R(Ru) chunks: 8 mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --reftest-suite=reftest-no-accel @@ -396,11 +396,11 @@ web-platform-tests: docker-image: {"in-tree": "desktop1604-test"} checkout: true mozharness: - script: mozharness/scripts/web_platform_tests.py + script: web_platform_tests.py no-read-buildbot-config: true config: - - mozharness/configs/web_platform_tests/prod_config.py - - mozharness/configs/remove_executables.py + - web_platform_tests/prod_config.py + - remove_executables.py extra-options: - --test-type=testharness @@ -413,11 +413,11 @@ web-platform-tests-reftests: docker-image: {"in-tree": "desktop1604-test"} checkout: true mozharness: - script: mozharness/scripts/web_platform_tests.py + script: web_platform_tests.py no-read-buildbot-config: true config: - - mozharness/configs/web_platform_tests/prod_config.py - - mozharness/configs/remove_executables.py + - web_platform_tests/prod_config.py + - remove_executables.py extra-options: - --test-type=reftest @@ -432,13 +432,13 @@ xpcshell: max-run-time: 5400 e10s: false mozharness: - script: mozharness/scripts/desktop_unittest.py + script: desktop_unittest.py no-read-buildbot-config: true config: by-test-platform: default: - - mozharness/configs/unittests/linux_unittest.py - - mozharness/configs/remove_executables.py + - unittests/linux_unittest.py + - remove_executables.py extra-options: - --xpcshell-suite=xpcshell # Bug 1281241: migrating to m3.large instances diff --git a/taskcluster/ci/toolchain/kind.yml b/taskcluster/ci/toolchain/kind.yml index e8da344248ba..760bdff7e88d 100644 --- a/taskcluster/ci/toolchain/kind.yml +++ b/taskcluster/ci/toolchain/kind.yml @@ -43,3 +43,14 @@ jobs: files-changed: - 'build/unix/build-gcc/**' - 'taskcluster/scripts/misc/build-gcc-linux.sh' + + linux64-binutils/opt: + treeherder: + symbol: Cc(binutils) + run: + using: toolchain-script + script: build-binutils-linux.sh + when: + files-changed: + - 'build/unix/build-binutils/**' + - 'taskcluster/scripts/misc/build-binutils-linux.sh' diff --git a/taskcluster/scripts/misc/build-binutils-linux.sh b/taskcluster/scripts/misc/build-binutils-linux.sh new file mode 100755 index 000000000000..da0eb27243fe --- /dev/null +++ b/taskcluster/scripts/misc/build-binutils-linux.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -x -e -v + +# This script is for building binutils for Linux. + +WORKSPACE=$HOME/workspace +HOME_DIR=$WORKSPACE/build +UPLOAD_DIR=$WORKSPACE/artifacts + +cd $HOME_DIR/src + +build/unix/build-binutils/build-binutils.sh $HOME_DIR + +# Put a tarball in the artifacts dir +mkdir -p $UPLOAD_DIR +cp $HOME_DIR/binutils.tar.* $UPLOAD_DIR diff --git a/taskcluster/scripts/tester/test-ubuntu1604.sh b/taskcluster/scripts/tester/test-ubuntu.sh similarity index 70% rename from taskcluster/scripts/tester/test-ubuntu1604.sh rename to taskcluster/scripts/tester/test-ubuntu.sh index bdf22df35aa1..cfde06372179 100644 --- a/taskcluster/scripts/tester/test-ubuntu1604.sh +++ b/taskcluster/scripts/tester/test-ubuntu.sh @@ -4,6 +4,14 @@ set -x -e echo "running as" $(id) +# Detect release version. +. /etc/lsb-release +if [ "${DISTRIB_RELEASE}" == "12.04" ]; then + UBUNTU_1204=1 +elif [ "${DISTRIB_RELEASE}" == "16.04" ]; then + UBUNTU_1604=1 +fi + . /home/worker/scripts/xvfb.sh #### @@ -12,6 +20,7 @@ echo "running as" $(id) # Inputs, with defaults +: MOZHARNESS_PATH ${MOZHARNESS_PATH} : MOZHARNESS_URL ${MOZHARNESS_URL} : MOZHARNESS_SCRIPT ${MOZHARNESS_SCRIPT} : MOZHARNESS_CONFIG ${MOZHARNESS_CONFIG} @@ -32,8 +41,18 @@ fail() { exit 1 } +maybe_start_pulse() { + if $NEED_PULSEAUDIO; then + pulseaudio --fail --daemonize --start + pactl load-module module-null-sink + fi +} + # test required parameters are supplied -if [[ -z ${MOZHARNESS_URL} ]]; then fail "MOZHARNESS_URL is not set"; fi +if [ -z "${MOZHARNESS_PATH}" -a -z "${MOZHARNESS_URL}" ]; then + fail "MOZHARNESS_PATH or MOZHARNESS_URL must be defined"; +fi + if [[ -z ${MOZHARNESS_SCRIPT} ]]; then fail "MOZHARNESS_SCRIPT is not set"; fi if [[ -z ${MOZHARNESS_CONFIG} ]]; then fail "MOZHARNESS_CONFIG is not set"; fi @@ -50,16 +69,25 @@ cleanup() { } trap cleanup EXIT INT -# Unzip the mozharness ZIP file created by the build task -if ! curl --fail -o mozharness.zip --retry 10 -L $MOZHARNESS_URL; then - fail "failed to download mozharness zip" -fi -rm -rf mozharness -unzip -q mozharness.zip -rm mozharness.zip +# Download mozharness if we're told to. +if [ ${MOZHARNESS_URL} ]; then + if ! curl --fail -o mozharness.zip --retry 10 -L $MOZHARNESS_URL; then + fail "failed to download mozharness zip" + fi + rm -rf mozharness + unzip -q mozharness.zip + rm mozharness.zip -if ! [ -d mozharness ]; then - fail "mozharness zip did not contain mozharness/" + if ! [ -d mozharness ]; then + fail "mozharness zip did not contain mozharness/" + fi + + MOZHARNESS_PATH=`pwd`/mozharness +fi + +# pulseaudio daemon must be started before xvfb on Ubuntu 12.04. +if [ "${UBUNTU_1204}" ]; then + maybe_start_pulse fi # run XVfb in the background, if necessary @@ -90,17 +118,15 @@ if $NEED_WINDOW_MANAGER; then # Disable the screen saver xset s off s reset - # start compiz for our window manager - compiz 2>&1 & - - #TODO: how to determine if compiz starts correctly? + if [ "${UBUNTU_1604}" ]; then + # start compiz for our window manager + compiz 2>&1 & + #TODO: how to determine if compiz starts correctly? + fi fi -# start up the pulseaudio daemon. Note that it's important this occur -# before the Xvfb startup for ubuntu 12.04, not for 16.04 -if $NEED_PULSEAUDIO; then - pulseaudio --fail --daemonize --start - pactl load-module module-null-sink +if [ "${UBUNTU_1604}" ]; then + maybe_start_pulse fi # For telemetry purposes, the build process wants information about the @@ -112,7 +138,7 @@ export MOZ_SOURCE_CHANGESET="${GECKO_HEAD_REV}" # support multiple, space delimited, config files config_cmds="" for cfg in $MOZHARNESS_CONFIG; do - config_cmds="${config_cmds} --config-file $WORKSPACE/${cfg}" + config_cmds="${config_cmds} --config-file ${MOZHARNESS_PATH}/configs/${cfg}" done mozharness_bin="/home/worker/bin/run-mozharness" @@ -123,7 +149,7 @@ echo -e "#!/usr/bin/env bash # Some mozharness scripts assume base_work_dir is in # the current working directory, see bug 1279237 cd $WORKSPACE -cmd=\"python2.7 $WORKSPACE/${MOZHARNESS_SCRIPT} ${config_cmds} ${@} \${@}\" +cmd=\"python2.7 ${MOZHARNESS_PATH}/scripts/${MOZHARNESS_SCRIPT} ${config_cmds} ${@} \${@}\" echo \"Running: \${cmd}\" exec \${cmd}" > ${mozharness_bin} chmod +x ${mozharness_bin} diff --git a/taskcluster/scripts/tester/test-ubuntu1204.sh b/taskcluster/scripts/tester/test-ubuntu1204.sh deleted file mode 100644 index bc1f9ed43959..000000000000 --- a/taskcluster/scripts/tester/test-ubuntu1204.sh +++ /dev/null @@ -1,131 +0,0 @@ -#! /bin/bash -xe - -set -x -e - -echo "running as" $(id) - -. /home/worker/scripts/xvfb.sh - -#### -# Taskcluster friendly wrapper for performing fx desktop tests via mozharness. -#### - -# Inputs, with defaults - -: MOZHARNESS_URL ${MOZHARNESS_URL} -: MOZHARNESS_SCRIPT ${MOZHARNESS_SCRIPT} -: MOZHARNESS_CONFIG ${MOZHARNESS_CONFIG} -: NEED_XVFB ${NEED_XVFB:=true} -: NEED_WINDOW_MANAGER ${NEED_WINDOW_MANAGER:=false} -: NEED_PULSEAUDIO ${NEED_PULSEAUDIO:=false} -: START_VNC ${START_VNC:=false} -: TASKCLUSTER_INTERACTIVE ${TASKCLUSTER_INTERACTIVE:=false} -: WORKSPACE ${WORKSPACE:=/home/worker/workspace} -: mozharness args "${@}" - -set -v -cd $WORKSPACE - -fail() { - echo # make sure error message is on a new line - echo "[test-linux.sh:error]" "${@}" - exit 1 -} - -# test required parameters are supplied -if [[ -z ${MOZHARNESS_URL} ]]; then fail "MOZHARNESS_URL is not set"; fi -if [[ -z ${MOZHARNESS_SCRIPT} ]]; then fail "MOZHARNESS_SCRIPT is not set"; fi -if [[ -z ${MOZHARNESS_CONFIG} ]]; then fail "MOZHARNESS_CONFIG is not set"; fi - -mkdir -p ~/artifacts/public - -cleanup() { - local rv=$? - if [[ -s /home/worker/.xsession-errors ]]; then - # To share X issues - cp /home/worker/.xsession-errors ~/artifacts/public/xsession-errors.log - fi - cleanup_xvfb - exit $rv -} -trap cleanup EXIT INT - -# Unzip the mozharness ZIP file created by the build task -if ! curl --fail -o mozharness.zip --retry 10 -L $MOZHARNESS_URL; then - fail "failed to download mozharness zip" -fi -rm -rf mozharness -unzip -q mozharness.zip -rm mozharness.zip - -if ! [ -d mozharness ]; then - fail "mozharness zip did not contain mozharness/" -fi - -# start up the pulseaudio daemon. Note that it's important this occur -# before the Xvfb startup for ubuntu 12.04, not for 16.04 -if $NEED_PULSEAUDIO; then - pulseaudio --fail --daemonize --start - pactl load-module module-null-sink -fi - -# run XVfb in the background, if necessary -if $NEED_XVFB; then - start_xvfb '1600x1200x24' 0 -fi - -if $START_VNC; then - x11vnc > ~/artifacts/public/x11vnc.log 2>&1 & -fi - -if $NEED_WINDOW_MANAGER; then - # This is read by xsession to select the window manager - echo DESKTOP_SESSION=ubuntu > /home/worker/.xsessionrc - - # note that doing anything with this display before running Xsession will cause sadness (like, - # crashes in compiz). Make sure that X has enough time to start - sleep 15 - # DISPLAY has already been set above - # XXX: it would be ideal to add a semaphore logic to make sure that the - # window manager is ready - /etc/X11/Xsession 2>&1 & - - # Turn off the screen saver and screen locking - gsettings set org.gnome.desktop.screensaver idle-activation-enabled false - gsettings set org.gnome.desktop.screensaver lock-enabled false - gsettings set org.gnome.desktop.screensaver lock-delay 3600 - # Disable the screen saver - xset s off s reset -fi - -# For telemetry purposes, the build process wants information about the -# source it is running; tc-vcs obscures this a little, but we can provide -# it directly. -export MOZ_SOURCE_REPO="${GECKO_HEAD_REPOSITORY}" -export MOZ_SOURCE_CHANGESET="${GECKO_HEAD_REV}" - -# support multiple, space delimited, config files -config_cmds="" -for cfg in $MOZHARNESS_CONFIG; do - config_cmds="${config_cmds} --config-file $WORKSPACE/${cfg}" -done - -mozharness_bin="/home/worker/bin/run-mozharness" - -# Save the computed mozharness command to a binary which is useful -# for interactive mode. -echo -e "#!/usr/bin/env bash -# Some mozharness scripts assume base_work_dir is in -# the current working directory, see bug 1279237 -cd $WORKSPACE -cmd=\"python2.7 $WORKSPACE/${MOZHARNESS_SCRIPT} ${config_cmds} ${@} \${@}\" -echo \"Running: \${cmd}\" -exec \${cmd}" > ${mozharness_bin} -chmod +x ${mozharness_bin} - -# In interactive mode, the user will be prompted with options for what to do. -if ! $TASKCLUSTER_INTERACTIVE; then - # run the given mozharness script and configs, but pass the rest of the - # arguments in from our own invocation - ${mozharness_bin}; -fi diff --git a/taskcluster/taskgraph/transforms/tests/make_task_description.py b/taskcluster/taskgraph/transforms/tests/make_task_description.py index a1bb6ec9abc0..37fb442dc88c 100644 --- a/taskcluster/taskgraph/transforms/tests/make_task_description.py +++ b/taskcluster/taskgraph/transforms/tests/make_task_description.py @@ -162,7 +162,6 @@ def docker_worker_setup(config, test, taskdesc): env = worker['env'] = { 'MOZHARNESS_CONFIG': ' '.join(mozharness['config']), 'MOZHARNESS_SCRIPT': mozharness['script'], - 'MOZHARNESS_URL': {'task-reference': mozharness_url}, 'MOZILLA_BUILD_URL': {'task-reference': installer_url}, 'NEED_PULSEAUDIO': 'true', 'NEED_WINDOW_MANAGER': 'true', @@ -198,9 +197,14 @@ def docker_worker_setup(config, test, taskdesc): '--chown', '/home/worker/workspace', ] + # If we have a source checkout, run mozharness from it instead of + # downloading a zip file with the same content. if test['checkout']: docker_worker_support_vcs_checkout(config, test, taskdesc) command.extend(['--vcs-checkout', '/home/worker/checkouts/gecko']) + env['MOZHARNESS_PATH'] = '/home/worker/checkouts/gecko/testing/mozharness' + else: + env['MOZHARNESS_URL'] = {'task-reference': mozharness_url} command.extend([ '--', diff --git a/testing/docker/desktop-build/Dockerfile b/testing/docker/desktop-build/Dockerfile index a4917bdd55aa..68f6b2df43b6 100644 --- a/testing/docker/desktop-build/Dockerfile +++ b/testing/docker/desktop-build/Dockerfile @@ -39,7 +39,8 @@ RUN chmod +x /builds/tooltool.py # Move installation to base centos6-build image once Bug 1272629 is fixed # Install the screen package here to use with xvfb. -RUN yum install -y screen +# Install bison to build binutils. +RUN yum install -y bison screen # Set a default command useful for debugging CMD ["/bin/bash", "--login"] diff --git a/testing/docker/desktop-test/Dockerfile b/testing/docker/desktop-test/Dockerfile index caa697a39d1b..963674cac6ed 100644 --- a/testing/docker/desktop-test/Dockerfile +++ b/testing/docker/desktop-test/Dockerfile @@ -21,8 +21,8 @@ RUN bash /setup/system-setup.sh # %include testing/docker/recipes/run-task ADD topsrcdir/testing/docker/recipes/run-task /home/worker/bin/run-task -# %include taskcluster/scripts/tester/test-ubuntu1204.sh -ADD topsrcdir/taskcluster/scripts/tester/test-ubuntu1204.sh /home/worker/bin/test-linux.sh +# %include taskcluster/scripts/tester/test-ubuntu.sh +ADD topsrcdir/taskcluster/scripts/tester/test-ubuntu.sh /home/worker/bin/test-linux.sh # This will create a host mounted filesystem when the cache is stripped # on Try. This cancels out some of the performance losses of aufs. See diff --git a/testing/docker/desktop1604-test/Dockerfile b/testing/docker/desktop1604-test/Dockerfile index 7ebc88f73cb3..62409e7dfcb2 100644 --- a/testing/docker/desktop1604-test/Dockerfile +++ b/testing/docker/desktop1604-test/Dockerfile @@ -21,8 +21,8 @@ ADD topsrcdir/testing/docker/recipes/xvfb.sh /home/worker/scripts/xvfb.sh # %include testing/docker/recipes/run-task ADD topsrcdir/testing/docker/recipes/run-task /home/worker/bin/run-task -# %include taskcluster/scripts/tester/test-ubuntu1604.sh -ADD topsrcdir/taskcluster/scripts/tester/test-ubuntu1604.sh /home/worker/bin/test-linux.sh +# %include taskcluster/scripts/tester/test-ubuntu.sh +ADD topsrcdir/taskcluster/scripts/tester/test-ubuntu.sh /home/worker/bin/test-linux.sh # This will create a host mounted filesystem when the cache is stripped # on Try. This cancels out some of the performance losses of aufs. See diff --git a/testing/docker/recipes/install-mercurial.sh b/testing/docker/recipes/install-mercurial.sh index f771f832341c..46bd47a48e8a 100644 --- a/testing/docker/recipes/install-mercurial.sh +++ b/testing/docker/recipes/install-mercurial.sh @@ -57,7 +57,6 @@ else fi mkdir -p /usr/local/mercurial -cd /usr/local/mercurial tooltool_fetch <<'EOF' [ { @@ -68,6 +67,7 @@ tooltool_fetch <<'EOF' } ] EOF +mv robustcheckout.py /usr/local/mercurial/robustcheckout.py chmod 644 /usr/local/mercurial/robustcheckout.py mkdir -p /etc/mercurial diff --git a/testing/mochitest/tests/SimpleTest/NativeKeyCodes.js b/testing/mochitest/tests/SimpleTest/NativeKeyCodes.js index 4a5045e417e3..8130f3e18d50 100644 --- a/testing/mochitest/tests/SimpleTest/NativeKeyCodes.js +++ b/testing/mochitest/tests/SimpleTest/NativeKeyCodes.js @@ -5,214 +5,238 @@ */ // Windows +// Windows' native key code values may include scan code value which can be +// retrieved with |((code & 0xFFFF0000 >> 16)|. If the value is 0, it will +// be computed with active keyboard layout automatically. +// FYI: Don't define scan code here for printable keys, numeric keys and +// IME keys because they depend on active keyboard layout. +// XXX: Although, ABNT C1 key depends on keyboard layout in strictly speaking. +// However, computing its scan code from the virtual keycode, +// WIN_VK_ABNT_C1, doesn't work fine (computed as 0x0073, "IntlRo"). +// Therefore, we should specify it here explicitly (it should be 0x0056, +// "IntlBackslash"). Fortunately, the key always generates 0x0056 with +// any keyboard layouts as far as I've tested. So, this must be safe to +// test new regressions. -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_ABNT_C1 = 0xC1; -const WIN_VK_ABNT_C2 = 0xC2; -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; +const WIN_VK_LBUTTON = 0x00000001; +const WIN_VK_RBUTTON = 0x00000002; +const WIN_VK_CANCEL = 0xE0460003; +const WIN_VK_MBUTTON = 0x00000004; +const WIN_VK_XBUTTON1 = 0x00000005; +const WIN_VK_XBUTTON2 = 0x00000006; +const WIN_VK_BACK = 0x000E0008; +const WIN_VK_TAB = 0x000F0009; +const WIN_VK_CLEAR = 0x004C000C; +const WIN_VK_RETURN = 0x001C000D; +const WIN_VK_SHIFT = 0x002A0010; +const WIN_VK_CONTROL = 0x001D0011; +const WIN_VK_MENU = 0x00380012; +const WIN_VK_PAUSE = 0x00450013; +const WIN_VK_CAPITAL = 0x003A0014; +const WIN_VK_KANA = 0x00000015; +const WIN_VK_HANGUEL = 0x00000015; +const WIN_VK_HANGUL = 0x00000015; +const WIN_VK_JUNJA = 0x00000017; +const WIN_VK_FINAL = 0x00000018; +const WIN_VK_HANJA = 0x00000019; +const WIN_VK_KANJI = 0x00000019; +const WIN_VK_ESCAPE = 0x0001001B; +const WIN_VK_CONVERT = 0x0000001C; +const WIN_VK_NONCONVERT = 0x0000001D; +const WIN_VK_ACCEPT = 0x0000001E; +const WIN_VK_MODECHANGE = 0x0000001F; +const WIN_VK_SPACE = 0x00390020; +const WIN_VK_PRIOR = 0xE0490021; +const WIN_VK_NEXT = 0xE0510022; +const WIN_VK_END = 0xE04F0023; +const WIN_VK_HOME = 0xE0470024; +const WIN_VK_LEFT = 0xE04B0025; +const WIN_VK_UP = 0xE0480026; +const WIN_VK_RIGHT = 0xE04D0027; +const WIN_VK_DOWN = 0xE0500028; +const WIN_VK_SELECT = 0x00000029; +const WIN_VK_PRINT = 0x0000002A; +const WIN_VK_EXECUTE = 0x0000002B; +const WIN_VK_SNAPSHOT = 0xE037002C; +const WIN_VK_INSERT = 0xE052002D; +const WIN_VK_DELETE = 0xE053002E; +const WIN_VK_HELP = 0x0000002F; +const WIN_VK_0 = 0x00000030; +const WIN_VK_1 = 0x00000031; +const WIN_VK_2 = 0x00000032; +const WIN_VK_3 = 0x00000033; +const WIN_VK_4 = 0x00000034; +const WIN_VK_5 = 0x00000035; +const WIN_VK_6 = 0x00000036; +const WIN_VK_7 = 0x00000037; +const WIN_VK_8 = 0x00000038; +const WIN_VK_9 = 0x00000039; +const WIN_VK_A = 0x00000041; +const WIN_VK_B = 0x00000042; +const WIN_VK_C = 0x00000043; +const WIN_VK_D = 0x00000044; +const WIN_VK_E = 0x00000045; +const WIN_VK_F = 0x00000046; +const WIN_VK_G = 0x00000047; +const WIN_VK_H = 0x00000048; +const WIN_VK_I = 0x00000049; +const WIN_VK_J = 0x0000004A; +const WIN_VK_K = 0x0000004B; +const WIN_VK_L = 0x0000004C; +const WIN_VK_M = 0x0000004D; +const WIN_VK_N = 0x0000004E; +const WIN_VK_O = 0x0000004F; +const WIN_VK_P = 0x00000050; +const WIN_VK_Q = 0x00000051; +const WIN_VK_R = 0x00000052; +const WIN_VK_S = 0x00000053; +const WIN_VK_T = 0x00000054; +const WIN_VK_U = 0x00000055; +const WIN_VK_V = 0x00000056; +const WIN_VK_W = 0x00000057; +const WIN_VK_X = 0x00000058; +const WIN_VK_Y = 0x00000059; +const WIN_VK_Z = 0x0000005A; +const WIN_VK_LWIN = 0xE05B005B; +const WIN_VK_RWIN = 0xE05C005C; +const WIN_VK_APPS = 0xE05D005D; +const WIN_VK_SLEEP = 0x0000005F; +const WIN_VK_NUMPAD0 = 0x00520060; +const WIN_VK_NUMPAD1 = 0x004F0061; +const WIN_VK_NUMPAD2 = 0x00500062; +const WIN_VK_NUMPAD3 = 0x00510063; +const WIN_VK_NUMPAD4 = 0x004B0064; +const WIN_VK_NUMPAD5 = 0x004C0065; +const WIN_VK_NUMPAD6 = 0x004D0066; +const WIN_VK_NUMPAD7 = 0x00470067; +const WIN_VK_NUMPAD8 = 0x00480068; +const WIN_VK_NUMPAD9 = 0x00490069; +const WIN_VK_MULTIPLY = 0x0037006A; +const WIN_VK_ADD = 0x004E006B; +const WIN_VK_SEPARATOR = 0x0000006C; +const WIN_VK_OEM_NEC_SEPARATE = 0x0000006C; +const WIN_VK_SUBTRACT = 0x004A006D; +const WIN_VK_DECIMAL = 0x0053006E; +const WIN_VK_DIVIDE = 0xE035006F; +const WIN_VK_F1 = 0x003B0070; +const WIN_VK_F2 = 0x003C0071; +const WIN_VK_F3 = 0x003D0072; +const WIN_VK_F4 = 0x003E0073; +const WIN_VK_F5 = 0x003F0074; +const WIN_VK_F6 = 0x00400075; +const WIN_VK_F7 = 0x00410076; +const WIN_VK_F8 = 0x00420077; +const WIN_VK_F9 = 0x00430078; +const WIN_VK_F10 = 0x00440079; +const WIN_VK_F11 = 0x0057007A; +const WIN_VK_F12 = 0x0058007B; +const WIN_VK_F13 = 0x0064007C; +const WIN_VK_F14 = 0x0065007D; +const WIN_VK_F15 = 0x0066007E; +const WIN_VK_F16 = 0x0067007F; +const WIN_VK_F17 = 0x00680080; +const WIN_VK_F18 = 0x00690081; +const WIN_VK_F19 = 0x006A0082; +const WIN_VK_F20 = 0x006B0083; +const WIN_VK_F21 = 0x006C0084; +const WIN_VK_F22 = 0x006D0085; +const WIN_VK_F23 = 0x006E0086; +const WIN_VK_F24 = 0x00760087; +const WIN_VK_NUMLOCK = 0xE0450090; +const WIN_VK_SCROLL = 0x00460091; +const WIN_VK_OEM_FJ_JISHO = 0x00000092; +const WIN_VK_OEM_NEC_EQUAL = 0x00000092; +const WIN_VK_OEM_FJ_MASSHOU = 0x00000093; +const WIN_VK_OEM_FJ_TOUROKU = 0x00000094; +const WIN_VK_OEM_FJ_LOYA = 0x00000095; +const WIN_VK_OEM_FJ_ROYA = 0x00000096; +const WIN_VK_LSHIFT = 0x002A00A0; +const WIN_VK_RSHIFT = 0x003600A1; +const WIN_VK_LCONTROL = 0x001D00A2; +const WIN_VK_RCONTROL = 0xE01D00A3; +const WIN_VK_LMENU = 0x003800A4; +const WIN_VK_RMENU = 0xE03800A5; +const WIN_VK_BROWSER_BACK = 0xE06A00A6; +const WIN_VK_BROWSER_FORWARD = 0xE06900A7; +const WIN_VK_BROWSER_REFRESH = 0xE06700A8; +const WIN_VK_BROWSER_STOP = 0xE06800A9; +const WIN_VK_BROWSER_SEARCH = 0x000000AA; +const WIN_VK_BROWSER_FAVORITES = 0xE06600AB; +const WIN_VK_BROWSER_HOME = 0xE03200AC; +const WIN_VK_VOLUME_MUTE = 0xE02000AD; +const WIN_VK_VOLUME_DOWN = 0xE02E00AE; +const WIN_VK_VOLUME_UP = 0xE03000AF; +const WIN_VK_MEDIA_NEXT_TRACK = 0xE01900B0; +const WIN_VK_OEM_FJ_000 = 0x000000B0; +const WIN_VK_MEDIA_PREV_TRACK = 0xE01000B1; +const WIN_VK_OEM_FJ_EUQAL = 0x000000B1; +const WIN_VK_MEDIA_STOP = 0xE02400B2; +const WIN_VK_MEDIA_PLAY_PAUSE = 0xE02200B3; +const WIN_VK_OEM_FJ_00 = 0x000000B3; +const WIN_VK_LAUNCH_MAIL = 0xE06C00B4; +const WIN_VK_LAUNCH_MEDIA_SELECT = 0xE06D00B5; +const WIN_VK_LAUNCH_APP1 = 0xE06B00B6; +const WIN_VK_LAUNCH_APP2 = 0xE02100B7; +const WIN_VK_OEM_1 = 0x000000BA; +const WIN_VK_OEM_PLUS = 0x000000BB; +const WIN_VK_OEM_COMMA = 0x000000BC; +const WIN_VK_OEM_MINUS = 0x000000BD; +const WIN_VK_OEM_PERIOD = 0x000000BE; +const WIN_VK_OEM_2 = 0x000000BF; +const WIN_VK_OEM_3 = 0x000000C0; +const WIN_VK_ABNT_C1 = 0x005600C1; +const WIN_VK_ABNT_C2 = 0x000000C2; +const WIN_VK_OEM_4 = 0x000000DB; +const WIN_VK_OEM_5 = 0x000000DC; +const WIN_VK_OEM_6 = 0x000000DD; +const WIN_VK_OEM_7 = 0x000000DE; +const WIN_VK_OEM_8 = 0x000000DF; +const WIN_VK_OEM_NEC_DP1 = 0x000000E0; +const WIN_VK_OEM_AX = 0x000000E1; +const WIN_VK_OEM_NEC_DP2 = 0x000000E1; +const WIN_VK_OEM_102 = 0x000000E2; +const WIN_VK_OEM_NEC_DP3 = 0x000000E2; +const WIN_VK_ICO_HELP = 0x000000E3; +const WIN_VK_OEM_NEC_DP4 = 0x000000E3; +const WIN_VK_ICO_00 = 0x000000E4; +const WIN_VK_PROCESSKEY = 0x000000E5; +const WIN_VK_ICO_CLEAR = 0x000000E6; +const WIN_VK_PACKET = 0x000000E7; +const WIN_VK_ERICSSON_BASE = 0x000000E8; +const WIN_VK_OEM_RESET = 0x000000E9; +const WIN_VK_OEM_JUMP = 0x000000EA; +const WIN_VK_OEM_PA1 = 0x000000EB; +const WIN_VK_OEM_PA2 = 0x000000EC; +const WIN_VK_OEM_PA3 = 0x000000ED; +const WIN_VK_OEM_WSCTRL = 0x000000EE; +const WIN_VK_OEM_CUSEL = 0x000000EF; +const WIN_VK_OEM_ATTN = 0x000000F0; +const WIN_VK_OEM_FINISH = 0x000000F1; +const WIN_VK_OEM_COPY = 0x000000F2; +const WIN_VK_OEM_AUTO = 0x000000F3; +const WIN_VK_OEM_ENLW = 0x000000F4; +const WIN_VK_OEM_BACKTAB = 0x000000F5; +const WIN_VK_ATTN = 0x000000F6; +const WIN_VK_CRSEL = 0x000000F7; +const WIN_VK_EXSEL = 0x000000F8; +const WIN_VK_EREOF = 0x000000F9; +const WIN_VK_PLAY = 0x000000FA; +const WIN_VK_ZOOM = 0x000000FB; +const WIN_VK_NONAME = 0x000000FC; +const WIN_VK_PA1 = 0x000000FD; +const WIN_VK_OEM_CLEAR = 0x000000FE; + +const WIN_VK_NUMPAD_RETURN = 0xE01C000D; +const WIN_VK_NUMPAD_PRIOR = 0x00490021; +const WIN_VK_NUMPAD_NEXT = 0x00510022; +const WIN_VK_NUMPAD_END = 0x004F0023; +const WIN_VK_NUMPAD_HOME = 0x00470024; +const WIN_VK_NUMPAD_LEFT = 0x004B0025; +const WIN_VK_NUMPAD_UP = 0x00480026; +const WIN_VK_NUMPAD_RIGHT = 0x004D0027; +const WIN_VK_NUMPAD_DOWN = 0x00500028; +const WIN_VK_NUMPAD_INSERT = 0x0052002D; +const WIN_VK_NUMPAD_DELETE = 0x0053002E; // Mac @@ -321,13 +345,13 @@ 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_PC_ScrollLock = 0x6B; const MAC_VK_F10 = 0x6D; const MAC_VK_PC_ContextMenu = 0x6E; const MAC_VK_F12 = 0x6F; const MAC_VK_F15 = 0x71; +const MAC_VK_PC_Pause = 0x71; const MAC_VK_Help = 0x72; const MAC_VK_PC_Insert = 0x72; const MAC_VK_Home = 0x73; diff --git a/toolkit/components/extensions/ext-webNavigation.js b/toolkit/components/extensions/ext-webNavigation.js index d1a6ae820b93..4136a7f460f4 100644 --- a/toolkit/components/extensions/ext-webNavigation.js +++ b/toolkit/components/extensions/ext-webNavigation.js @@ -161,6 +161,7 @@ function convertGetFrameResult(tabId, data) { extensions.registerSchemaAPI("webNavigation", "addon_parent", context => { return { webNavigation: { + onTabReplaced: ignoreEvent(context, "webNavigation.onTabReplaced"), onBeforeNavigate: new WebNavigationEventManager(context, "onBeforeNavigate").api(), onCommitted: new WebNavigationEventManager(context, "onCommitted").api(), onDOMContentLoaded: new WebNavigationEventManager(context, "onDOMContentLoaded").api(), diff --git a/toolkit/components/extensions/schemas/web_navigation.json b/toolkit/components/extensions/schemas/web_navigation.json index 3bf7adeb39d0..1e13b181ace6 100644 --- a/toolkit/components/extensions/schemas/web_navigation.json +++ b/toolkit/components/extensions/schemas/web_navigation.json @@ -340,7 +340,6 @@ }, { "name": "onTabReplaced", - "unsupported": true, "type": "function", "description": "Fired when the contents of the tab is replaced by a different (usually previously pre-rendered) tab.", "parameters": [ diff --git a/toolkit/components/extensions/test/mochitest/test_ext_webnavigation.html b/toolkit/components/extensions/test/mochitest/test_ext_webnavigation.html index 32c55f295417..2287fd9b153a 100644 --- a/toolkit/components/extensions/test/mochitest/test_ext_webnavigation.html +++ b/toolkit/components/extensions/test/mochitest/test_ext_webnavigation.html @@ -21,6 +21,7 @@ function backgroundScript() { const URL = BASE + "/file_WebNavigation_page1.html"; const EVENTS = [ + "onTabReplaced", "onBeforeNavigate", "onCommitted", "onDOMContentLoaded", diff --git a/toolkit/components/osfile/modules/osfile_win_front.jsm b/toolkit/components/osfile/modules/osfile_win_front.jsm index 6908b8765996..e24bffb2623b 100644 --- a/toolkit/components/osfile/modules/osfile_win_front.jsm +++ b/toolkit/components/osfile/modules/osfile_win_front.jsm @@ -426,7 +426,8 @@ return; } - if (ctypes.winLastError == Const.ERROR_FILE_NOT_FOUND) { + if (ctypes.winLastError == Const.ERROR_FILE_NOT_FOUND || + ctypes.winLastError == Const.ERROR_PATH_NOT_FOUND) { if ((!("ignoreAbsent" in options) || options.ignoreAbsent)) { return; } diff --git a/toolkit/components/osfile/tests/xpcshell/test_remove.js b/toolkit/components/osfile/tests/xpcshell/test_remove.js index 6cda29cf44f1..c8dc3305457b 100644 --- a/toolkit/components/osfile/tests/xpcshell/test_remove.js +++ b/toolkit/components/osfile/tests/xpcshell/test_remove.js @@ -35,3 +35,22 @@ add_task(function* test_ignoreAbsent() { } Assert.ok(!exception, "OS.File.remove should not throw when not requested."); }); + +add_task(function* test_ignoreAbsent_directory_missing() { + let absent_file_name = OS.Path.join("absent_parent", "test.tmp"); + + // Removing absent files should throw if "ignoreAbsent" is true. + yield Assert.rejects(OS.File.remove(absent_file_name, {ignoreAbsent: false}), + "OS.File.remove throws if there is no such file."); + + // Removing files from absent directories should not throw if "ignoreAbsent" + // is true or not defined. + let exception = null; + try { + yield OS.File.remove(absent_file_name, {ignoreAbsent: true}); + yield OS.File.remove(absent_file_name); + } catch (ex) { + exception = ex; + } + Assert.ok(!exception, "OS.File.remove should not throw when not requested."); +}); diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 9dc410c04633..133eecead7d6 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -4505,17 +4505,19 @@ "description": "Firefox: Time in ms spent updating UI in response to a tab switch" }, "FX_TAB_SWITCH_TOTAL_MS": { - "expires_in_version": "default", + "expires_in_version": "56", "kind": "exponential", "high": 1000, "n_buckets": 20, + "releaseChannelCollection": "opt-out", "description": "Firefox: Time in ms till a tab switch is complete including the first paint" }, "FX_TAB_SWITCH_TOTAL_E10S_MS": { - "expires_in_version": "default", + "expires_in_version": "56", "kind": "exponential", "high": 1000, "n_buckets": 20, + "releaseChannelCollection": "opt-out", "description": "Firefox: Time in ms between tab selection and tab content paint." }, "FX_TAB_SWITCH_SPINNER_VISIBLE_MS": { diff --git a/toolkit/content/widgets/browser.xml b/toolkit/content/widgets/browser.xml index 6c2c4e2c1b18..99f490ad6248 100644 --- a/toolkit/content/widgets/browser.xml +++ b/toolkit/content/widgets/browser.xml @@ -1312,7 +1312,7 @@ diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 08521f879953..0fc73318ee56 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -168,6 +168,11 @@ #ifdef MOZ_ENABLE_XREMOTE #include "XRemoteClient.h" #include "nsIRemoteService.h" +#include "nsProfileLock.h" +#include "SpecialSystemDirectory.h" +#include +// Time to wait for the remoting service to start +#define MOZ_XREMOTE_START_TIMEOUT_SEC 5 #endif #if defined(DEBUG) && defined(XP_WIN32) @@ -1679,17 +1684,13 @@ DumpVersion() #ifdef MOZ_ENABLE_XREMOTE static RemoteResult -RemoteCommandLine(const char* aDesktopStartupID) +ParseRemoteCommandLine(nsCString& program, + const char** profile, + const char** username) { - nsresult rv; ArgResult ar; - const char *profile = 0; - nsAutoCString program(gAppData->remotingName); - ToLowerCase(program); - const char *username = getenv("LOGNAME"); - - ar = CheckArg("p", false, &profile, false); + ar = CheckArg("p", false, profile, false); if (ar == ARG_BAD) { // Leave it to the normal command line handling to handle this situation. return REMOTE_NOT_FOUND; @@ -1704,14 +1705,23 @@ RemoteCommandLine(const char* aDesktopStartupID) program.Assign(temp); } - ar = CheckArg("u", true, &username); + ar = CheckArg("u", true, username); if (ar == ARG_BAD) { PR_fprintf(PR_STDERR, "Error: argument -u requires a username\n"); return REMOTE_ARG_BAD; } + return REMOTE_FOUND; +} + +static RemoteResult +StartRemoteClient(const char* aDesktopStartupID, + nsCString& program, + const char* profile, + const char* username) +{ XRemoteClient client; - rv = client.Init(); + nsresult rv = client.Init(); if (NS_FAILED(rv)) return REMOTE_NOT_FOUND; @@ -3018,6 +3028,8 @@ public: nsCOMPtr mProfileLock; #ifdef MOZ_ENABLE_XREMOTE nsCOMPtr mRemoteService; + nsProfileLock mRemoteLock; + nsCOMPtr mRemoteLockDir; #endif UniquePtr mScopedXPCOM; @@ -3755,17 +3767,58 @@ XREMain::XRE_mainStartup(bool* aExitFlag) } if (!newInstance) { + nsAutoCString program(gAppData->remotingName); + ToLowerCase(program); + + const char* username = getenv("LOGNAME"); + const char* profile = nullptr; + + RemoteResult rr = ParseRemoteCommandLine(program, &profile, &username); + if (rr == REMOTE_ARG_BAD) { + return 1; + } + + nsCOMPtr mutexDir; + rv = GetSpecialSystemDirectory(OS_TemporaryDirectory, getter_AddRefs(mutexDir)); + if (NS_SUCCEEDED(rv)) { + nsAutoCString mutexPath = + program + NS_LITERAL_CSTRING("_") + nsDependentCString(username); + if (profile) { + mutexPath.Append(NS_LITERAL_CSTRING("_") + nsDependentCString(profile)); + } + mutexDir->AppendNative(mutexPath); + + rv = mutexDir->Create(nsIFile::DIRECTORY_TYPE, 0700); + if (NS_SUCCEEDED(rv) || rv == NS_ERROR_FILE_ALREADY_EXISTS) { + mRemoteLockDir = mutexDir; + } + } + + if (mRemoteLockDir) { + const TimeStamp epoch = mozilla::TimeStamp::Now(); + do { + rv = mRemoteLock.Lock(mRemoteLockDir, nullptr); + if (NS_SUCCEEDED(rv)) + break; + sched_yield(); + } while ((TimeStamp::Now() - epoch) + < TimeDuration::FromSeconds(MOZ_XREMOTE_START_TIMEOUT_SEC)); + if (NS_FAILED(rv)) { + NS_WARNING("Cannot lock XRemote start mutex"); + } + } + // Try to remote the entire command line. If this fails, start up normally. const char* desktopStartupIDPtr = mDesktopStartupID.IsEmpty() ? nullptr : mDesktopStartupID.get(); - RemoteResult rr = RemoteCommandLine(desktopStartupIDPtr); + rr = StartRemoteClient(desktopStartupIDPtr, program, profile, username); if (rr == REMOTE_FOUND) { *aExitFlag = true; return 0; - } - else if (rr == REMOTE_ARG_BAD) + } else if (rr == REMOTE_ARG_BAD) { return 1; + } } #endif #if defined(MOZ_WIDGET_GTK) @@ -4331,6 +4384,10 @@ XREMain::XRE_mainRun() mRemoteService = do_GetService("@mozilla.org/toolkit/remote-service;1"); if (mRemoteService) mRemoteService->Startup(mAppData->remotingName, mProfileName.get()); + if (mRemoteLockDir) { + mRemoteLock.Unlock(); + mRemoteLockDir->Remove(false); + } #endif /* MOZ_ENABLE_XREMOTE */ mNativeApp->Enable(); diff --git a/tools/lint/eslint.lint b/tools/lint/eslint.lint index 5deb1fcc5f52..13db185475ee 100644 --- a/tools/lint/eslint.lint +++ b/tools/lint/eslint.lint @@ -18,6 +18,11 @@ from mozprocess import ProcessHandler from mozlint import result +ESLINT_ERROR_MESSAGE = """ +An error occurred running eslint. Please check the following error messages: + +{} +""".strip() ESLINT_NOT_FOUND_MESSAGE = """ Could not find eslint! We looked at the --binary option, at the ESLINT @@ -325,8 +330,14 @@ def lint(paths, binary=None, fix=None, setup=None, **lintargs): proc.kill() return [] + try: + jsonresult = json.loads(proc.output[0] or '[]') + except ValueError: + print(ESLINT_ERROR_MESSAGE.format("\n".join(proc.output))) + return 1 + results = [] - for obj in json.loads(proc.output[0] or '[]'): + for obj in jsonresult: errors = obj['messages'] for err in errors: diff --git a/widget/gtk/IMContextWrapper.cpp b/widget/gtk/IMContextWrapper.cpp index 34dbbbd1cc02..58d7a3681c2f 100644 --- a/widget/gtk/IMContextWrapper.cpp +++ b/widget/gtk/IMContextWrapper.cpp @@ -1006,7 +1006,8 @@ IMContextWrapper::OnSelectionChange(nsWindow* aCaller, } bool occurredBeforeComposition = - IsComposing() && !selectionChangeData.mOccurredDuringComposition; + IsComposing() && !selectionChangeData.mOccurredDuringComposition && + !selectionChangeData.mCausedByComposition; if (occurredBeforeComposition) { mPendingResettingIMContext = true; } diff --git a/widget/tests/test_keycodes.xul b/widget/tests/test_keycodes.xul index 48fbcdbf6ff2..285043415850 100644 --- a/widget/tests/test_keycodes.xul +++ b/widget/tests/test_keycodes.xul @@ -287,7 +287,12 @@ function* runKeyEventTests() // The first parameter is the complete input event. The second parameter is // what to test against. The third parameter is which key events should be // delived for the event. - function testKey(aEvent, aExpectedGeckoKeyCode, aExpectGeckoChar, + // @param aExpectedKeyValues Can be string or array of string. + // If all keyboard events have same key value, + // specify it as string. Otherwise, specify + // each key value in array. + function testKey(aEvent, aExpectedKeyValues, aExpectedCodeValue, + aExpectedGeckoKeyCode, aExpectGeckoChar, aShouldDelivedEvent, aExpectLocation) { ok(aExpectedGeckoKeyCode != undefined, "keycode is undefined"); @@ -349,7 +354,7 @@ function* runKeyEventTests() var firedEventType = i < eventList.length ? eventList[i].type : ""; var expectEventType = i < expectEventTypeList.length ? expectEventTypeList[i] : ""; if (firedEventType != "") - is(firedEventType, expectEventType, name + ", wrong type event fired"); + is(firedEventType, expectEventType, name + ", " + expectEventType + " should be fired"); else is(firedEventType, expectEventType, name + ", a needed event is not fired"); @@ -370,6 +375,13 @@ function* runKeyEventTests() is(e.shiftKey, !!(aEvent.modifiers.shiftKey || aEvent.modifiers.shiftRightKey), name + ", Shift mismatch"); } + var expectedKeyValue = + typeof aExpectedKeyValues === "string" ? aExpectedKeyValues : + i < aExpectedKeyValues.length ? aExpectedKeyValues[i] : + undefined; + is(e.key, expectedKeyValue, name + ", wrong key value"); + is(e.code, aExpectedCodeValue, name + ", wrong code value"); + if (aExpectGeckoChar.length > 0 && e.type == "keypress") { is(e.charCode, aExpectGeckoChar.charCodeAt(keypressCount++), name + ", charcode"); if (aExpectedGeckoKeyCode >= 0) { @@ -400,7 +412,16 @@ function* runKeyEventTests() // Prevent almost all shortcut key handlers. SpecialPowers.addSystemEventListener(document, "keypress", consumer, true); - if (IS_MAC) { + function cleanup() + { + document.removeEventListener("keydown", onKeyEvent, false); + document.removeEventListener("keypress", onKeyEvent, false); + document.removeEventListener("keyup", onKeyEvent, false); + SpecialPowers.removeSystemEventListener(document, "keypress", consumer, true); + } + + function testKeysOnMac() + { // On Mac, you can produce event records for any desired keyboard input // by running with NSPR_LOG_MODULES=TextInputHandlerWidgets:5 and typing // into the browser. We will dump the key event fields to the console @@ -416,1474 +437,1478 @@ function* runKeyEventTests() // Ctrl keys yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{ctrlKey:1}, chars:"\u0001", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{ctrlKey:1, shiftKey:1}, chars:"\u0001", unmodifiedChars:"A"}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "A", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Alt keys yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{altKey:1}, chars:"\u00e5", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00e5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00e5", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00e5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{altKey:1, shiftKey:1}, chars:"\u00c5", unmodifiedChars:"A"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00c5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00c5", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00c5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Command keys yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1}, chars:"a", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Shift-cmd gives us the shifted character yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1, shiftKey:1}, chars:"a", unmodifiedChars:"A"}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Ctrl-cmd gives us the unshifted character yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1, ctrlKey:1}, chars:"\u0001", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Alt-cmd gives us the shifted character yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1, altKey:1}, chars:"\u00e5", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00e5", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00e5", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00e5", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1, altKey:1, shiftKey:1}, chars:"\u00c5", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00c5", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00c5", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00c5", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Greek ctrl keys produce Latin charcodes yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:MAC_VK_ANSI_A, modifiers:{ctrlKey:1}, chars:"\u0001", unmodifiedChars:"\u03b1"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u03b1", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:MAC_VK_ANSI_A, modifiers:{ctrlKey:1, shiftKey:1}, chars:"\u0001", unmodifiedChars:"\u0391"}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0391", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Greek command keys yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1}, chars:"a", unmodifiedChars:"\u03b1"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Shift-cmd gives us the shifted character yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1, shiftKey:1}, chars:"a", unmodifiedChars:"\u0391"}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Ctrl-cmd gives us the unshifted character yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1, ctrlKey:1}, chars:"\u0001", unmodifiedChars:"\u03b1"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u03b1", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Alt-cmd gives us the shifted character yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1, altKey:1}, chars:"\u00a8", unmodifiedChars:"\u03b1"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00a8", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00a8", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00a8", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1, altKey:1, shiftKey:1}, chars:"\u00b9", unmodifiedChars:"\u0391"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00b9", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00b9", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00b9", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // German yield testKey({layout:KEYBOARD_LAYOUT_GERMAN, keyCode:MAC_VK_ANSI_A, modifiers: {}, chars:"a", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_GERMAN, keyCode:MAC_VK_ANSI_LeftBracket, modifiers: {}, chars:"\u00fc", unmodifiedChars:"\u00fc"}, - 0, "\u00fc", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00fc", "BracketLeft", 0, "\u00fc", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_GERMAN, keyCode:MAC_VK_ANSI_Minus, modifiers: {}, chars:"\u00df", unmodifiedChars:"\u00df"}, - nsIDOMKeyEvent.DOM_VK_QUESTION_MARK, "\u00df", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00df", "Minus", nsIDOMKeyEvent.DOM_VK_QUESTION_MARK, "\u00df", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_GERMAN, keyCode:MAC_VK_ANSI_Minus, modifiers:{shiftKey:1}, chars:"?", unmodifiedChars:"?"}, - nsIDOMKeyEvent.DOM_VK_QUESTION_MARK, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "?", "Minus", nsIDOMKeyEvent.DOM_VK_QUESTION_MARK, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // 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. yield testKey({layout:KEYBOARD_LAYOUT_GERMAN, keyCode:MAC_VK_ANSI_Minus, modifiers:{metaKey:1}, chars:"\u00df", unmodifiedChars:"\u00df"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "\u00df", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00df", "Minus", nsIDOMKeyEvent.DOM_VK_SLASH, "\u00df", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_GERMAN, keyCode:MAC_VK_ANSI_Minus, modifiers:{metaKey:1, shiftKey:1}, chars:"/", unmodifiedChars:"?"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "/", "Minus", nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Caps Lock key event // XXX keyup event of Caps Lock key is not fired. yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_CapsLock, modifiers:{capsLockKey:1}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "CapsLock", "CapsLock", nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_CapsLock, modifiers:{capsLockKey:0}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "CapsLock", "CapsLock", nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Shift/RightShift key event yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Shift, modifiers:{shiftKey:1}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Shift", "ShiftLeft", nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Shift, modifiers:{shiftKey:0}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Shift", "ShiftLeft", nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_RightShift, modifiers:{shiftRightKey:1}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Shift", "ShiftRight", nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_RightShift, modifiers:{shiftRightKey:0}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Shift", "ShiftRight", nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); // Control/RightControl key event yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Control, modifiers:{ctrlKey:1}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Control", "ControlLeft", nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Control, modifiers:{ctrlKey:0}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Control", "ControlLeft", nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_RightControl, modifiers:{ctrlRightKey:1}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Control", "ControlRight", nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_RightControl, modifiers:{ctrlRightKey:0}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Control", "ControlRight", nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); // Option/RightOption key event yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Option, modifiers:{altKey:1}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Alt", "AltLeft", nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Option, modifiers:{altKey:0}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Alt", "AltLeft", nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_RightOption, modifiers:{altRightKey:1}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Alt", "AltRight", nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_RightOption, modifiers:{altRightKey:0}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Alt", "AltRight", nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); // Command/RightCommand key event yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Command, modifiers:{metaKey:1}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Meta", "OSLeft", nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Command, modifiers:{metaKey:0}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Meta", "OSLeft", nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_RightCommand, modifiers:{metaRightKey:1}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Meta", "OSRight", nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYDOWN, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_RightCommand, modifiers:{metaRightKey:0}, chars:"", unmodifiedChars:""}, - nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Meta", "OSRight", nsIDOMKeyEvent.DOM_VK_META, "", SHOULD_DELIVER_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); // all keys on keyboard (keyCode test) yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Tab, modifiers: {}, chars:"\t", unmodifiedChars:"\t"}, - nsIDOMKeyEvent.DOM_VK_TAB, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Tab", "Tab", nsIDOMKeyEvent.DOM_VK_TAB, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadClear, modifiers: {}, chars:"\uF739", unmodifiedChars:"\uF739"}, - nsIDOMKeyEvent.DOM_VK_CLEAR, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Clear", "NumLock", nsIDOMKeyEvent.DOM_VK_CLEAR, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Return, modifiers: {}, chars:"\u000D", unmodifiedChars:"\u000D"}, - nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F15, + "Enter", "Enter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_PC_Pause, modifiers: {}, chars:"\uF712", unmodifiedChars:"\uF712"}, - nsIDOMKeyEvent.DOM_VK_PAUSE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F15", "F15", nsIDOMKeyEvent.DOM_VK_PAUSE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Escape, modifiers: {}, chars:"\u001B", unmodifiedChars:"\u001B"}, - nsIDOMKeyEvent.DOM_VK_ESCAPE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Escape", "Escape", nsIDOMKeyEvent.DOM_VK_ESCAPE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Space, modifiers: {}, chars:" ", unmodifiedChars:" "}, - nsIDOMKeyEvent.DOM_VK_SPACE, " ", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + " ", "Space", nsIDOMKeyEvent.DOM_VK_SPACE, " ", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_PageUp, modifiers: {}, chars:"\uF72C", unmodifiedChars:"\uF72C"}, - nsIDOMKeyEvent.DOM_VK_PAGE_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "PageUp", "PageUp", nsIDOMKeyEvent.DOM_VK_PAGE_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_PageDown, modifiers: {}, chars:"\uF72D", unmodifiedChars:"\uF72D"}, - nsIDOMKeyEvent.DOM_VK_PAGE_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "PageDown", "PageDown", nsIDOMKeyEvent.DOM_VK_PAGE_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_End, modifiers: {}, chars:"\uF72B", unmodifiedChars:"\uF72B"}, - nsIDOMKeyEvent.DOM_VK_END, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "End", "End", nsIDOMKeyEvent.DOM_VK_END, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_Home, modifiers: {}, chars:"\uF729", unmodifiedChars:"\uF729"}, - nsIDOMKeyEvent.DOM_VK_HOME, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Home", "Home", nsIDOMKeyEvent.DOM_VK_HOME, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_LeftArrow, modifiers: {}, chars:"\uF702", unmodifiedChars:"\uF702"}, - nsIDOMKeyEvent.DOM_VK_LEFT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "ArrowLeft", "ArrowLeft", nsIDOMKeyEvent.DOM_VK_LEFT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_UpArrow, modifiers: {}, chars:"\uF700", unmodifiedChars:"\uF700"}, - nsIDOMKeyEvent.DOM_VK_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "ArrowUp", "ArrowUp", nsIDOMKeyEvent.DOM_VK_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_RightArrow, modifiers: {}, chars:"\uF703", unmodifiedChars:"\uF703"}, - nsIDOMKeyEvent.DOM_VK_RIGHT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "ArrowRight", "ArrowRight", nsIDOMKeyEvent.DOM_VK_RIGHT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_DownArrow, modifiers: {}, chars:"\uF701", unmodifiedChars:"\uF701"}, - nsIDOMKeyEvent.DOM_VK_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "ArrowDown", "ArrowDown", nsIDOMKeyEvent.DOM_VK_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_PC_PrintScreen, modifiers: {}, chars:"\uF710", unmodifiedChars:"\uF710"}, - nsIDOMKeyEvent.DOM_VK_PRINTSCREEN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F13", "F13", nsIDOMKeyEvent.DOM_VK_PRINTSCREEN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_PC_Delete, modifiers: {}, chars:"\uF728", unmodifiedChars:"\uF728"}, - nsIDOMKeyEvent.DOM_VK_DELETE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_PC_Pause, + "Delete", "Delete", nsIDOMKeyEvent.DOM_VK_DELETE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_PC_ScrollLock, modifiers: {}, chars:"\uF711", unmodifiedChars:"\uF711"}, - nsIDOMKeyEvent.DOM_VK_SCROLL_LOCK, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F14", "F14", nsIDOMKeyEvent.DOM_VK_SCROLL_LOCK, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_PC_ContextMenu, modifiers: {}, chars:"\u0010", unmodifiedChars:"\u0010"}, - nsIDOMKeyEvent.DOM_VK_CONTEXT_MENU, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "ContextMenu", "ContextMenu", nsIDOMKeyEvent.DOM_VK_CONTEXT_MENU, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F1, modifiers:{fnKey:1}, chars:"\uF704", unmodifiedChars:"\uF704"}, - nsIDOMKeyEvent.DOM_VK_F1, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F1", "F1", nsIDOMKeyEvent.DOM_VK_F1, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F2, modifiers:{fnKey:1}, chars:"\uF705", unmodifiedChars:"\uF705"}, - nsIDOMKeyEvent.DOM_VK_F2, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F2", "F2", nsIDOMKeyEvent.DOM_VK_F2, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F3, modifiers:{fnKey:1}, chars:"\uF706", unmodifiedChars:"\uF706"}, - nsIDOMKeyEvent.DOM_VK_F3, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F3", "F3", nsIDOMKeyEvent.DOM_VK_F3, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F4, modifiers:{fnKey:1}, chars:"\uF707", unmodifiedChars:"\uF707"}, - nsIDOMKeyEvent.DOM_VK_F4, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F4", "F4", nsIDOMKeyEvent.DOM_VK_F4, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F5, modifiers:{fnKey:1}, chars:"\uF708", unmodifiedChars:"\uF708"}, - nsIDOMKeyEvent.DOM_VK_F5, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F5", "F5", nsIDOMKeyEvent.DOM_VK_F5, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F6, modifiers:{fnKey:1}, chars:"\uF709", unmodifiedChars:"\uF709"}, - nsIDOMKeyEvent.DOM_VK_F6, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F6", "F6", nsIDOMKeyEvent.DOM_VK_F6, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F7, modifiers:{fnKey:1}, chars:"\uF70A", unmodifiedChars:"\uF70A"}, - nsIDOMKeyEvent.DOM_VK_F7, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F7", "F7", nsIDOMKeyEvent.DOM_VK_F7, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F8, modifiers:{fnKey:1}, chars:"\uF70B", unmodifiedChars:"\uF70B"}, - nsIDOMKeyEvent.DOM_VK_F8, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F8", "F8", nsIDOMKeyEvent.DOM_VK_F8, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F9, modifiers:{fnKey:1}, chars:"\uF70C", unmodifiedChars:"\uF70C"}, - nsIDOMKeyEvent.DOM_VK_F9, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F9", "F9", nsIDOMKeyEvent.DOM_VK_F9, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F10, modifiers:{fnKey:1}, chars:"\uF70D", unmodifiedChars:"\uF70D"}, - nsIDOMKeyEvent.DOM_VK_F10, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F10", "F10", nsIDOMKeyEvent.DOM_VK_F10, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F11, modifiers:{fnKey:1}, chars:"\uF70E", unmodifiedChars:"\uF70E"}, - nsIDOMKeyEvent.DOM_VK_F11, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F11", "F11", nsIDOMKeyEvent.DOM_VK_F11, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F12, modifiers:{fnKey:1}, chars:"\uF70F", unmodifiedChars:"\uF70F"}, - nsIDOMKeyEvent.DOM_VK_F12, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F12", "F12", nsIDOMKeyEvent.DOM_VK_F12, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F16, modifiers:{fnKey:1}, chars:"\uF713", unmodifiedChars:"\uF713"}, - nsIDOMKeyEvent.DOM_VK_F16, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F16", "F16", nsIDOMKeyEvent.DOM_VK_F16, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F17, modifiers:{fnKey:1}, chars:"\uF714", unmodifiedChars:"\uF714"}, - nsIDOMKeyEvent.DOM_VK_F17, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F17", "F17", nsIDOMKeyEvent.DOM_VK_F17, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F18, modifiers:{fnKey:1}, chars:"\uF715", unmodifiedChars:"\uF715"}, - nsIDOMKeyEvent.DOM_VK_F18, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F18", "F18", nsIDOMKeyEvent.DOM_VK_F18, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_F19, modifiers:{fnKey:1}, chars:"\uF716", unmodifiedChars:"\uF716"}, - nsIDOMKeyEvent.DOM_VK_F19, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F19", "F19", nsIDOMKeyEvent.DOM_VK_F19, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // US // Alphabet yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers: {}, chars:"a", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{shiftKey:1}, chars:"A", unmodifiedChars:"A"}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "A", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{ctrlKey:1}, chars:"\u0001", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{altKey:1}, chars:"\u00E5", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00E5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E5", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00E5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_A, modifiers:{metaKey:1}, chars:"a", unmodifiedChars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_B, modifiers:{}, chars:"b", unmodifiedChars:"b"}, - nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "b", "KeyB", nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_B, modifiers:{shiftKey:1}, chars:"B", unmodifiedChars:"B"}, - nsIDOMKeyEvent.DOM_VK_B, "B", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "B", "KeyB", nsIDOMKeyEvent.DOM_VK_B, "B", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_B, modifiers:{ctrlKey:1}, chars:"\u0002", unmodifiedChars:"b"}, - nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "b", "KeyB", nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_B, modifiers:{altKey:1}, chars:"\u222B", unmodifiedChars:"b"}, - nsIDOMKeyEvent.DOM_VK_B, "\u222B", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u222B", "KeyB", nsIDOMKeyEvent.DOM_VK_B, "\u222B", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_B, modifiers:{metaKey:1}, chars:"b", unmodifiedChars:"b"}, - nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "b", "KeyB", nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_C, modifiers:{}, chars:"c", unmodifiedChars:"c"}, - nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "c", "KeyC", nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_C, modifiers:{shiftKey:1}, chars:"C", unmodifiedChars:"C"}, - nsIDOMKeyEvent.DOM_VK_C, "C", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "C", "KeyC", nsIDOMKeyEvent.DOM_VK_C, "C", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_C, modifiers:{ctrlKey:1}, chars:"\u0003", unmodifiedChars:"c"}, - nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "c", "KeyC", nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_C, modifiers:{altKey:1}, chars:"\u00E7", unmodifiedChars:"c"}, - nsIDOMKeyEvent.DOM_VK_C, "\u00E7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E7", "KeyC", nsIDOMKeyEvent.DOM_VK_C, "\u00E7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_C, modifiers:{metaKey:1}, chars:"c", unmodifiedChars:"c"}, - nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "c", "KeyC", nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_D, modifiers:{}, chars:"d", unmodifiedChars:"d"}, - nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "d", "KeyD", nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_D, modifiers:{shiftKey:1}, chars:"D", unmodifiedChars:"D"}, - nsIDOMKeyEvent.DOM_VK_D, "D", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "D", "KeyD", nsIDOMKeyEvent.DOM_VK_D, "D", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_D, modifiers:{ctrlKey:1}, chars:"\u0004", unmodifiedChars:"d"}, - nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "d", "KeyD", nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_D, modifiers:{altKey:1}, chars:"\u2202", unmodifiedChars:"d"}, - nsIDOMKeyEvent.DOM_VK_D, "\u2202", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2202", "KeyD", nsIDOMKeyEvent.DOM_VK_D, "\u2202", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_D, modifiers:{metaKey:1}, chars:"d", unmodifiedChars:"d"}, - nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "d", "KeyD", nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_E, modifiers:{}, chars:"e", unmodifiedChars:"e"}, - nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "e", "KeyE", nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_E, modifiers:{shiftKey:1}, chars:"E", unmodifiedChars:"E"}, - nsIDOMKeyEvent.DOM_VK_E, "E", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "E", "KeyE", nsIDOMKeyEvent.DOM_VK_E, "E", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_E, modifiers:{ctrlKey:1}, chars:"\u0005", unmodifiedChars:"e"}, - nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "e", "KeyE", nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_E, modifiers:{altKey:1}, chars:"", unmodifiedChars:"e"}, - nsIDOMKeyEvent.DOM_VK_E, "\u00B4", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key + "Dead", "KeyE", nsIDOMKeyEvent.DOM_VK_E, "\u00B4", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_E, modifiers:{metaKey:1}, chars:"e", unmodifiedChars:"e"}, - nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "e", "KeyE", nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_F, modifiers:{}, chars:"f", unmodifiedChars:"f"}, - nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "f", "KeyF", nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_F, modifiers:{shiftKey:1}, chars:"F", unmodifiedChars:"F"}, - nsIDOMKeyEvent.DOM_VK_F, "F", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F", "KeyF", nsIDOMKeyEvent.DOM_VK_F, "F", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_F, modifiers:{ctrlKey:1}, chars:"\u0006", unmodifiedChars:"f"}, - nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "f", "KeyF", nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_F, modifiers:{altKey:1}, chars:"\u0192", unmodifiedChars:"f"}, - nsIDOMKeyEvent.DOM_VK_F, "\u0192", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0192", "KeyF", nsIDOMKeyEvent.DOM_VK_F, "\u0192", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // XXX This test starts fullscreen mode. // yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_F, // modifiers:{metaKey:1}, chars:"f", unmodifiedChars:"f"}, - // nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "f", "KeyF", nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_G, modifiers:{}, chars:"g", unmodifiedChars:"g"}, - nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "g", "KeyG", nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_G, modifiers:{shiftKey:1}, chars:"G", unmodifiedChars:"G"}, - nsIDOMKeyEvent.DOM_VK_G, "G", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "G", "KeyG", nsIDOMKeyEvent.DOM_VK_G, "G", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_G, modifiers:{ctrlKey:1}, chars:"\u0007", unmodifiedChars:"g"}, - nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "g", "KeyG", nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_G, modifiers:{altKey:1}, chars:"\u00A9", unmodifiedChars:"g"}, - nsIDOMKeyEvent.DOM_VK_G, "\u00A9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A9", "KeyG", nsIDOMKeyEvent.DOM_VK_G, "\u00A9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_G, modifiers:{metaKey:1}, chars:"g", unmodifiedChars:"g"}, - nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "g", "KeyG", nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_H, modifiers:{}, chars:"h", unmodifiedChars:"h"}, - nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "h", "KeyH", nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_H, modifiers:{shiftKey:1}, chars:"H", unmodifiedChars:"H"}, - nsIDOMKeyEvent.DOM_VK_H, "H", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "H", "KeyH", nsIDOMKeyEvent.DOM_VK_H, "H", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_H, modifiers:{ctrlKey:1}, chars:"\u0008", unmodifiedChars:"h"}, - nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "h", "KeyH", nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_H, modifiers:{altKey:1}, chars:"\u02D9", unmodifiedChars:"h"}, - nsIDOMKeyEvent.DOM_VK_H, "\u02D9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u02D9", "KeyH", nsIDOMKeyEvent.DOM_VK_H, "\u02D9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_H, modifiers:{metaKey:1}, chars:"h", unmodifiedChars:"h"}, - nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "h", "KeyH", nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_I, modifiers:{}, chars:"i", unmodifiedChars:"i"}, - nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "i", "KeyI", nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_I, modifiers:{shiftKey:1}, chars:"I", unmodifiedChars:"I"}, - nsIDOMKeyEvent.DOM_VK_I, "I", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "I", "KeyI", nsIDOMKeyEvent.DOM_VK_I, "I", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_I, modifiers:{ctrlKey:1}, chars:"\u0009", unmodifiedChars:"i"}, - nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "i", "KeyI", nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_I, modifiers:{altKey:1}, chars:"", unmodifiedChars:"i"}, - nsIDOMKeyEvent.DOM_VK_I, "\u02C6", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key + "Dead", "KeyI", nsIDOMKeyEvent.DOM_VK_I, "\u02C6", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key // XXX This test causes memory leak. // yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_I, // modifiers:{metaKey:1}, chars:"i", unmodifiedChars:"i"}, - // nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "i", "KeyI", nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_J, modifiers:{}, chars:"j", unmodifiedChars:"j"}, - nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "j", "KeyJ", nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_J, modifiers:{shiftKey:1}, chars:"J", unmodifiedChars:"J"}, - nsIDOMKeyEvent.DOM_VK_J, "J", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "J", "KeyJ", nsIDOMKeyEvent.DOM_VK_J, "J", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_J, modifiers:{ctrlKey:1}, chars:"\u000A", unmodifiedChars:"j"}, - nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "j", "KeyJ", nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_J, modifiers:{altKey:1}, chars:"\u2206", unmodifiedChars:"j"}, - nsIDOMKeyEvent.DOM_VK_J, "\u2206", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2206", "KeyJ", nsIDOMKeyEvent.DOM_VK_J, "\u2206", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_J, modifiers:{metaKey:1}, chars:"j", unmodifiedChars:"j"}, - nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "j", "KeyJ", nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_K, modifiers:{}, chars:"k", unmodifiedChars:"k"}, - nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "k", "KeyK", nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_K, modifiers:{shiftKey:1}, chars:"K", unmodifiedChars:"K"}, - nsIDOMKeyEvent.DOM_VK_K, "K", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "K", "KeyK", nsIDOMKeyEvent.DOM_VK_K, "K", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_K, modifiers:{ctrlKey:1}, chars:"\u000B", unmodifiedChars:"k"}, - nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "k", "KeyK", nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_K, modifiers:{altKey:1}, chars:"\u02DA", unmodifiedChars:"k"}, - nsIDOMKeyEvent.DOM_VK_K, "\u02DA", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u02DA", "KeyK", nsIDOMKeyEvent.DOM_VK_K, "\u02DA", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_K, modifiers:{metaKey:1}, chars:"k", unmodifiedChars:"k"}, - nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "k", "KeyK", nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_L, modifiers:{}, chars:"l", unmodifiedChars:"l"}, - nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "l", "KeyL", nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_L, modifiers:{shiftKey:1}, chars:"L", unmodifiedChars:"L"}, - nsIDOMKeyEvent.DOM_VK_L, "L", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "L", "KeyL", nsIDOMKeyEvent.DOM_VK_L, "L", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_L, modifiers:{ctrlKey:1}, chars:"\u000C", unmodifiedChars:"l"}, - nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "l", "KeyL", nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_L, modifiers:{altKey:1}, chars:"\u00AC", unmodifiedChars:"l"}, - nsIDOMKeyEvent.DOM_VK_L, "\u00AC", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00AC", "KeyL", nsIDOMKeyEvent.DOM_VK_L, "\u00AC", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_L, modifiers:{metaKey:1}, chars:"l", unmodifiedChars:"l"}, - nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "l", "KeyL", nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_M, modifiers:{}, chars:"m", unmodifiedChars:"m"}, - nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "m", "KeyM", nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_M, modifiers:{shiftKey:1}, chars:"M", unmodifiedChars:"M"}, - nsIDOMKeyEvent.DOM_VK_M, "M", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "M", "KeyM", nsIDOMKeyEvent.DOM_VK_M, "M", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_M, modifiers:{ctrlKey:1}, chars:"\u000D", unmodifiedChars:"m"}, - nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "m", "KeyM", nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_M, modifiers:{altKey:1}, chars:"\u00B5", unmodifiedChars:"m"}, - nsIDOMKeyEvent.DOM_VK_M, "\u00B5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00B5", "KeyM", nsIDOMKeyEvent.DOM_VK_M, "\u00B5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_M, modifiers:{metaKey:1}, chars:"m", unmodifiedChars:"m"}, - nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "m", "KeyM", nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_N, modifiers:{}, chars:"n", unmodifiedChars:"n"}, - nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "n", "KeyN", nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_N, modifiers:{shiftKey:1}, chars:"N", unmodifiedChars:"N"}, - nsIDOMKeyEvent.DOM_VK_N, "N", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "N", "KeyN", nsIDOMKeyEvent.DOM_VK_N, "N", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_N, modifiers:{ctrlKey:1}, chars:"\u000E", unmodifiedChars:"n"}, - nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "n", "KeyN", nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_N, modifiers:{altKey:1}, chars:"", unmodifiedChars:"n"}, - nsIDOMKeyEvent.DOM_VK_N, "\u02DC", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key + "Dead", "KeyN", nsIDOMKeyEvent.DOM_VK_N, "\u02DC", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_N, modifiers:{metaKey:1}, chars:"n", unmodifiedChars:"n"}, - nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "n", "KeyN", nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_O, modifiers:{}, chars:"o", unmodifiedChars:"o"}, - nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "o", "KeyO", nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_O, modifiers:{shiftKey:1}, chars:"O", unmodifiedChars:"O"}, - nsIDOMKeyEvent.DOM_VK_O, "O", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "O", "KeyO", nsIDOMKeyEvent.DOM_VK_O, "O", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_O, modifiers:{ctrlKey:1}, chars:"\u000F", unmodifiedChars:"o"}, - nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "o", "KeyO", nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_O, modifiers:{altKey:1}, chars:"\u00F8", unmodifiedChars:"o"}, - nsIDOMKeyEvent.DOM_VK_O, "\u00F8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00F8", "KeyO", nsIDOMKeyEvent.DOM_VK_O, "\u00F8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_O, modifiers:{metaKey:1}, chars:"o", unmodifiedChars:"o"}, - nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "o", "KeyO", nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_P, modifiers:{}, chars:"p", unmodifiedChars:"p"}, - nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "p", "KeyP", nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_P, modifiers:{shiftKey:1}, chars:"P", unmodifiedChars:"P"}, - nsIDOMKeyEvent.DOM_VK_P, "P", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "P", "KeyP", nsIDOMKeyEvent.DOM_VK_P, "P", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_P, modifiers:{ctrlKey:1}, chars:"\u0010", unmodifiedChars:"p"}, - nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "p", "KeyP", nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_P, modifiers:{altKey:1}, chars:"\u03C0", unmodifiedChars:"p"}, - nsIDOMKeyEvent.DOM_VK_P, "\u03C0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u03C0", "KeyP", nsIDOMKeyEvent.DOM_VK_P, "\u03C0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // XXX This test starts private browsing mode (stopped at the confirmation dialog) // yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_P, // modifiers:{metaKey:1}, chars:"p", unmodifiedChars:"p"}, - // nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "p", "KeyP", nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Q, modifiers:{}, chars:"q", unmodifiedChars:"q"}, - nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "q", "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Q, modifiers:{shiftKey:1}, chars:"Q", unmodifiedChars:"Q"}, - nsIDOMKeyEvent.DOM_VK_Q, "Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Q", "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Q, modifiers:{ctrlKey:1}, chars:"\u0011", unmodifiedChars:"q"}, - nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "q", "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Q, modifiers:{altKey:1}, chars:"\u0153", unmodifiedChars:"q"}, - nsIDOMKeyEvent.DOM_VK_Q, "\u0153", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0153", "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "\u0153", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Q, modifiers:{metaKey:1}, chars:"q", unmodifiedChars:"q"}, - nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "q", "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_R, modifiers:{}, chars:"r", unmodifiedChars:"r"}, - nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "r", "KeyR", nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_R, modifiers:{shiftKey:1}, chars:"R", unmodifiedChars:"R"}, - nsIDOMKeyEvent.DOM_VK_R, "R", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "R", "KeyR", nsIDOMKeyEvent.DOM_VK_R, "R", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_R, modifiers:{ctrlKey:1}, chars:"\u0012", unmodifiedChars:"r"}, - nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "r", "KeyR", nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_R, modifiers:{altKey:1}, chars:"\u00AE", unmodifiedChars:"r"}, - nsIDOMKeyEvent.DOM_VK_R, "\u00AE", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00AE", "KeyR", nsIDOMKeyEvent.DOM_VK_R, "\u00AE", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // XXX This test makes some tabs and dialogs. // yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_R, // modifiers:{metaKey:1}, chars:"r", unmodifiedChars:"r"}, - // nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "r", "KeyR", nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_S, modifiers:{}, chars:"s", unmodifiedChars:"s"}, - nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "s", "KeyS", nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_S, modifiers:{shiftKey:1}, chars:"S", unmodifiedChars:"S"}, - nsIDOMKeyEvent.DOM_VK_S, "S", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "S", "KeyS", nsIDOMKeyEvent.DOM_VK_S, "S", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_S, modifiers:{ctrlKey:1}, chars:"\u0013", unmodifiedChars:"s"}, - nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "s", "KeyS", nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_S, modifiers:{altKey:1}, chars:"\u00DF", unmodifiedChars:"s"}, - nsIDOMKeyEvent.DOM_VK_S, "\u00DF", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00DF", "KeyS", nsIDOMKeyEvent.DOM_VK_S, "\u00DF", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_S, modifiers:{metaKey:1}, chars:"s", unmodifiedChars:"s"}, - nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "s", "KeyS", nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_T, modifiers:{}, chars:"t", unmodifiedChars:"t"}, - nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "t", "KeyT", nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_T, modifiers:{shiftKey:1}, chars:"T", unmodifiedChars:"T"}, - nsIDOMKeyEvent.DOM_VK_T, "T", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "T", "KeyT", nsIDOMKeyEvent.DOM_VK_T, "T", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_T, modifiers:{ctrlKey:1}, chars:"\u0014", unmodifiedChars:"t"}, - nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "t", "KeyT", nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_T, modifiers:{altKey:1}, chars:"\u2020", unmodifiedChars:"t"}, - nsIDOMKeyEvent.DOM_VK_T, "\u2020", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2020", "KeyT", nsIDOMKeyEvent.DOM_VK_T, "\u2020", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_T, modifiers:{metaKey:1}, chars:"t", unmodifiedChars:"t"}, - nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "t", "KeyT", nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_U, modifiers:{}, chars:"u", unmodifiedChars:"u"}, - nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "u", "KeyU", nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_U, modifiers:{shiftKey:1}, chars:"U", unmodifiedChars:"U"}, - nsIDOMKeyEvent.DOM_VK_U, "U", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "U", "KeyU", nsIDOMKeyEvent.DOM_VK_U, "U", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_U, modifiers:{ctrlKey:1}, chars:"\u0015", unmodifiedChars:"u"}, - nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "u", "KeyU", nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_U, modifiers:{altKey:1}, chars:"", unmodifiedChars:"u"}, - nsIDOMKeyEvent.DOM_VK_U, "\u00A8", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key + "Dead", "KeyU", nsIDOMKeyEvent.DOM_VK_U, "\u00A8", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_U, modifiers:{metaKey:1}, chars:"u", unmodifiedChars:"u"}, - nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "u", "KeyU", nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_V, modifiers:{}, chars:"v", unmodifiedChars:"v"}, - nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "v", "KeyV", nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_V, modifiers:{shiftKey:1}, chars:"V", unmodifiedChars:"V"}, - nsIDOMKeyEvent.DOM_VK_V, "V", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "V", "KeyV", nsIDOMKeyEvent.DOM_VK_V, "V", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_V, modifiers:{ctrlKey:1}, chars:"\u0016", unmodifiedChars:"v"}, - nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "v", "KeyV", nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_V, modifiers:{altKey:1}, chars:"\u221A", unmodifiedChars:"v"}, - nsIDOMKeyEvent.DOM_VK_V, "\u221A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u221A", "KeyV", nsIDOMKeyEvent.DOM_VK_V, "\u221A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_V, modifiers:{metaKey:1}, chars:"v", unmodifiedChars:"v"}, - nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "v", "KeyV", nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_W, modifiers:{}, chars:"w", unmodifiedChars:"w"}, - nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "w", "KeyW", nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_W, modifiers:{shiftKey:1}, chars:"W", unmodifiedChars:"W"}, - nsIDOMKeyEvent.DOM_VK_W, "W", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "W", "KeyW", nsIDOMKeyEvent.DOM_VK_W, "W", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_W, modifiers:{ctrlKey:1}, chars:"\u0017", unmodifiedChars:"w"}, - nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "w", "KeyW", nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_W, modifiers:{altKey:1}, chars:"\u2211", unmodifiedChars:"w"}, - nsIDOMKeyEvent.DOM_VK_W, "\u2211", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2211", "KeyW", nsIDOMKeyEvent.DOM_VK_W, "\u2211", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_W, modifiers:{metaKey:1}, chars:"w", unmodifiedChars:"w"}, - nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "w", "KeyW", nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_X, modifiers:{}, chars:"x", unmodifiedChars:"x"}, - nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "x", "KeyX", nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_X, modifiers:{shiftKey:1}, chars:"X", unmodifiedChars:"X"}, - nsIDOMKeyEvent.DOM_VK_X, "X", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "X", "KeyX", nsIDOMKeyEvent.DOM_VK_X, "X", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_X, modifiers:{ctrlKey:1}, chars:"\u0018", unmodifiedChars:"x"}, - nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "x", "KeyX", nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_X, modifiers:{altKey:1}, chars:"\u2248", unmodifiedChars:"x"}, - nsIDOMKeyEvent.DOM_VK_X, "\u2248", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2248", "KeyX", nsIDOMKeyEvent.DOM_VK_X, "\u2248", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_X, modifiers:{metaKey:1}, chars:"x", unmodifiedChars:"x"}, - nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "x", "KeyX", nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Y, modifiers:{}, chars:"y", unmodifiedChars:"y"}, - nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "y", "KeyY", nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Y, modifiers:{shiftKey:1}, chars:"Y", unmodifiedChars:"Y"}, - nsIDOMKeyEvent.DOM_VK_Y, "Y", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Y", "KeyY", nsIDOMKeyEvent.DOM_VK_Y, "Y", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Y, modifiers:{ctrlKey:1}, chars:"\u0019", unmodifiedChars:"y"}, - nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "y", "KeyY", nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Y, modifiers:{altKey:1}, chars:"\u00A5", unmodifiedChars:"y"}, - nsIDOMKeyEvent.DOM_VK_Y, "\u00A5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A5", "KeyY", nsIDOMKeyEvent.DOM_VK_Y, "\u00A5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Y, modifiers:{metaKey:1}, chars:"y", unmodifiedChars:"y"}, - nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "y", "KeyY", nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Z, modifiers:{}, chars:"z", unmodifiedChars:"z"}, - nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "z", "KeyZ", nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Z, modifiers:{shiftKey:1}, chars:"Z", unmodifiedChars:"Z"}, - nsIDOMKeyEvent.DOM_VK_Z, "Z", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Z", "KeyZ", nsIDOMKeyEvent.DOM_VK_Z, "Z", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Z, modifiers:{ctrlKey:1}, chars:"\u001A", unmodifiedChars:"z"}, - nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "z", "KeyZ", nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Z, modifiers:{altKey:1}, chars:"\u03A9", unmodifiedChars:"z"}, - nsIDOMKeyEvent.DOM_VK_Z, "\u03A9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u03A9", "KeyZ", nsIDOMKeyEvent.DOM_VK_Z, "\u03A9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Z, modifiers:{metaKey:1}, chars:"z", unmodifiedChars:"z"}, - nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "z", "KeyZ", nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // numeric yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_1, modifiers:{}, chars:"1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "1", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_1, modifiers:{shiftKey:1}, chars:"!", unmodifiedChars:"!"}, - nsIDOMKeyEvent.DOM_VK_1, "!", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "!", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "!", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_1, modifiers:{ctrlKey:1}, chars:"1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "1", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_1, modifiers:{altKey:1}, chars:"\u00A1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_1, "\u00A1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A1", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "\u00A1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_1, modifiers:{metaKey:1}, chars:"1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "1", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_2, modifiers:{}, chars:"2", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "2", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_2, modifiers:{shiftKey:1}, chars:"@", unmodifiedChars:"@"}, - nsIDOMKeyEvent.DOM_VK_2, "@", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "@", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "@", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_2, modifiers:{ctrlKey:1}, chars:"2", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "2", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_2, modifiers:{altKey:1}, chars:"\u00A1", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_2, "\u00A1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A1", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "\u00A1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_2, modifiers:{metaKey:1}, chars:"2", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "2", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_3, modifiers:{}, chars:"3", unmodifiedChars:"3"}, - nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "3", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_3, modifiers:{shiftKey:1}, chars:"#", unmodifiedChars:"#"}, - nsIDOMKeyEvent.DOM_VK_3, "#", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "#", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "#", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_3, modifiers:{ctrlKey:1}, chars:"3", unmodifiedChars:"3"}, - nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "3", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_3, modifiers:{altKey:1}, chars:"\u00A3", unmodifiedChars:"3"}, - nsIDOMKeyEvent.DOM_VK_3, "\u00A3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A3", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "\u00A3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_3, modifiers:{metaKey:1}, chars:"3", unmodifiedChars:"3"}, - nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "3", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_4, modifiers:{}, chars:"4", unmodifiedChars:"4"}, - nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "4", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_4, modifiers:{shiftKey:1}, chars:"$", unmodifiedChars:"$"}, - nsIDOMKeyEvent.DOM_VK_4, "$", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "$", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "$", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_4, modifiers:{ctrlKey:1}, chars:"4", unmodifiedChars:"4"}, - nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "4", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_4, modifiers:{altKey:1}, chars:"\u00A2", unmodifiedChars:"4"}, - nsIDOMKeyEvent.DOM_VK_4, "\u00A2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A2", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "\u00A2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_4, modifiers:{metaKey:1}, chars:"4", unmodifiedChars:"4"}, - nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "4", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_5, modifiers:{}, chars:"5", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "5", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_5, modifiers:{shiftKey:1}, chars:"%", unmodifiedChars:"%"}, - nsIDOMKeyEvent.DOM_VK_5, "%", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "%", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "%", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_5, modifiers:{ctrlKey:1}, chars:"5", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "5", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_5, modifiers:{altKey:1}, chars:"\u221E", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_5, "\u221E", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u221E", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "\u221E", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_5, modifiers:{metaKey:1}, chars:"5", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "5", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_6, modifiers:{}, chars:"6", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "6", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_6, modifiers:{shiftKey:1}, chars:"^", unmodifiedChars:"^"}, - nsIDOMKeyEvent.DOM_VK_6, "^", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "^", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "^", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_6, modifiers:{ctrlKey:1}, chars:"6", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "6", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_6, modifiers:{altKey:1}, chars:"\u00A7", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_6, "\u00A7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A7", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "\u00A7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_6, modifiers:{metaKey:1}, chars:"6", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "6", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_7, modifiers:{}, chars:"7", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "7", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_7, - modifiers:{shiftKey:1}, chars:"\u0026", unmodifiedChars:"\u0026"}, - nsIDOMKeyEvent.DOM_VK_7, "\u0026", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + modifiers:{shiftKey:1}, chars:"&", unmodifiedChars:"&"}, + "&", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "&", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_7, modifiers:{ctrlKey:1}, chars:"7", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "7", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_7, modifiers:{altKey:1}, chars:"\u00B6", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_7, "\u00B6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00B6", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "\u00B6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_7, modifiers:{metaKey:1}, chars:"7", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "7", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_8, modifiers:{}, chars:"8", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "8", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_8, modifiers:{shiftKey:1}, chars:"*", unmodifiedChars:"*"}, - nsIDOMKeyEvent.DOM_VK_8, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "*", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_8, modifiers:{ctrlKey:1}, chars:"8", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "8", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_8, modifiers:{altKey:1}, chars:"\u2022", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_8, "\u2022", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2022", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "\u2022", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_8, modifiers:{metaKey:1}, chars:"8", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "8", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_9, modifiers:{}, chars:"9", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "9", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_9, modifiers:{shiftKey:1}, chars:"(", unmodifiedChars:"("}, - nsIDOMKeyEvent.DOM_VK_9, "(", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "(", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "(", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_9, modifiers:{ctrlKey:1}, chars:"9", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "9", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_9, modifiers:{altKey:1}, chars:"\u00AA", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_9, "\u00AA", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00AA", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "\u00AA", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_9, modifiers:{metaKey:1}, chars:"9", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "9", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_0, modifiers:{}, chars:"0", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_0, modifiers:{shiftKey:1}, chars:")", unmodifiedChars:")"}, - nsIDOMKeyEvent.DOM_VK_0, ")", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ")", "Digit0", nsIDOMKeyEvent.DOM_VK_0, ")", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_0, modifiers:{ctrlKey:1}, chars:"0", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_0, modifiers:{altKey:1}, chars:"\u00BA", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_0, "\u00BA", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00BA", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "\u00BA", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_0, modifiers:{metaKey:1}, chars:"0", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // other chracters yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Grave, modifiers:{}, chars:"`", unmodifiedChars:"`"}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "`", "Backquote", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Grave, modifiers:{shiftKey:1}, chars:"~", unmodifiedChars:"~"}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "~", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "~", "Backquote", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "~", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Grave, modifiers:{ctrlKey:1}, chars:"`", unmodifiedChars:"`"}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "`", "Backquote", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Grave, modifiers:{altKey:1}, chars:"", unmodifiedChars:"`"}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key + "Dead", "Backquote", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Grave, modifiers:{metaKey:1}, chars:"`", unmodifiedChars:"`"}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "`", "Backquote", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Minus, modifiers:{}, chars:"-", unmodifiedChars:"-"}, - nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "-", "Minus", nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Minus, modifiers:{shiftKey:1}, chars:"_", unmodifiedChars:"_"}, - nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "_", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "_", "Minus", nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "_", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // TODO: // yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Minus, // modifiers:{ctrlKey:1}, chars:"\u001F", unmodifiedChars:"-"}, - // nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "-", "Minus", nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Minus, modifiers:{altKey:1}, chars:"\u2013", unmodifiedChars:"-"}, - nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "\u2013", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2013", "Minus", nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "\u2013", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Minus, modifiers:{metaKey:1}, chars:"-", unmodifiedChars:"-"}, - nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "-", "Minus", nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Equal, modifiers:{}, chars:"=", unmodifiedChars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "=", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Equal, modifiers:{shiftKey:1}, chars:"+", unmodifiedChars:"+"}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "+", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Equal, modifiers:{ctrlKey:1}, chars:"=", unmodifiedChars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "=", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Equal, modifiers:{altKey:1}, chars:"\u2260", unmodifiedChars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "\u2260", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2260", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "\u2260", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Equal, modifiers:{metaKey:1}, chars:"=", unmodifiedChars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "=", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_LeftBracket, modifiers:{}, chars:"[", unmodifiedChars:"["}, - nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "[", "BracketLeft", nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_LeftBracket, modifiers:{shiftKey:1}, chars:"{", unmodifiedChars:"{"}, - nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "{", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "{", "BracketLeft", nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "{", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // TODO: // yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_LeftBracket, // modifiers:{ctrlKey:1}, chars:"\u001B", unmodifiedChars:"["}, - // nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "[", "LeftBracket", nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_LeftBracket, modifiers:{altKey:1}, chars:"\u201C", unmodifiedChars:"["}, - nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "\u201C", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u201C", "BracketLeft", nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "\u201C", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_LeftBracket, modifiers:{metaKey:1}, chars:"[", unmodifiedChars:"["}, - nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "[", "BracketLeft", nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_RightBracket, modifiers:{}, chars:"]", unmodifiedChars:"]"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "]", "BracketRight", nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_RightBracket, modifiers:{shiftKey:1}, chars:"}", unmodifiedChars:"}"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "}", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "}", "BracketRight", nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "}", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // TODO: // yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_RightBracket, // modifiers:{ctrlKey:1}, chars:"\u001D", unmodifiedChars:"]"}, - // nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "]", "BracketRight", nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_RightBracket, modifiers:{altKey:1}, chars:"\u2018", unmodifiedChars:"]"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "\u2018", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2018", "BracketRight", nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "\u2018", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_RightBracket, modifiers:{metaKey:1}, chars:"]", unmodifiedChars:"]"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "]", "BracketRight", nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Backslash, modifiers:{}, chars:"\\", unmodifiedChars:"\\"}, - nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\\", "Backslash", nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Backslash, modifiers:{shiftKey:1}, chars:"|", unmodifiedChars:"|"}, - nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "|", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "|", "Backslash", nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "|", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // TODO: // yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Backslash, // modifiers:{ctrlKey:1}, chars:"\u001C", unmodifiedChars:"\\"}, - // nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "\\", "Backslash", nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Backslash, modifiers:{altKey:1}, chars:"\u00AB", unmodifiedChars:"\\"}, - nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\u00AB", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00AB", "Backslash", nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\u00AB", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Backslash, modifiers:{metaKey:1}, chars:"\\", unmodifiedChars:"\\"}, - nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\\", "Backslash", nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Semicolon, modifiers:{}, chars:";", unmodifiedChars:";"}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ";", "Semicolon", nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Semicolon, modifiers:{shiftKey:1}, chars:":", unmodifiedChars:":"}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, ":", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ":", "Semicolon", nsIDOMKeyEvent.DOM_VK_SEMICOLON, ":", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Semicolon, modifiers:{ctrlKey:1}, chars:";", unmodifiedChars:";"}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ";", "Semicolon", nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Semicolon, modifiers:{altKey:1}, chars:"\u2026", unmodifiedChars:";"}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, "\u2026", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2026", "Semicolon", nsIDOMKeyEvent.DOM_VK_SEMICOLON, "\u2026", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Semicolon, modifiers:{metaKey:1}, chars:";", unmodifiedChars:";"}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ";", "Semicolon", nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Quote, modifiers:{}, chars:"'", unmodifiedChars:"'"}, - nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "'", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Quote, modifiers:{shiftKey:1}, chars:"\"", unmodifiedChars:"\""}, - nsIDOMKeyEvent.DOM_VK_QUOTE, "\"", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\"", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "\"", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Quote, modifiers:{ctrlKey:1}, chars:"'", unmodifiedChars:"'"}, - nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "'", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Quote, modifiers:{altKey:1}, chars:"\u00E6", unmodifiedChars:"'"}, - nsIDOMKeyEvent.DOM_VK_QUOTE, "\u00E6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E6", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "\u00E6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Quote, modifiers:{metaKey:1}, chars:"'", unmodifiedChars:"'"}, - nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "'", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Comma, modifiers:{}, chars:",", unmodifiedChars:","}, - nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ",", "Comma", nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Comma, - modifiers:{shiftKey:1}, chars:"\u003C", unmodifiedChars:"\u003C"}, - nsIDOMKeyEvent.DOM_VK_COMMA, "\u003C", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + modifiers:{shiftKey:1}, chars:"<", unmodifiedChars:"<"}, + "<", "Comma", nsIDOMKeyEvent.DOM_VK_COMMA, "<", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Comma, modifiers:{ctrlKey:1}, chars:",", unmodifiedChars:","}, - nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ",", "Comma", nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Comma, modifiers:{altKey:1}, chars:"\u2264", unmodifiedChars:","}, - nsIDOMKeyEvent.DOM_VK_COMMA, "\u2264", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2264", "Comma", nsIDOMKeyEvent.DOM_VK_COMMA, "\u2264", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Comma, modifiers:{metaKey:1}, chars:",", unmodifiedChars:","}, - nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ",", "Comma", nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Period, modifiers:{}, chars:".", unmodifiedChars:"."}, - nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ".", "Period", nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Period, - modifiers:{shiftKey:1}, chars:"\u003E", unmodifiedChars:"\u003E"}, - nsIDOMKeyEvent.DOM_VK_PERIOD, "\u003E", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + modifiers:{shiftKey:1}, chars:">", unmodifiedChars:">"}, + ">", "Period", nsIDOMKeyEvent.DOM_VK_PERIOD, ">", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Period, modifiers:{ctrlKey:1}, chars:".", unmodifiedChars:"."}, - nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ".", "Period", nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Period, modifiers:{altKey:1}, chars:"\u2265", unmodifiedChars:"."}, - nsIDOMKeyEvent.DOM_VK_PERIOD, "\u2265", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u2265", "Period", nsIDOMKeyEvent.DOM_VK_PERIOD, "\u2265", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Period, modifiers:{metaKey:1}, chars:".", unmodifiedChars:"."}, - nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ".", "Period", nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Slash, modifiers:{}, chars:"/", unmodifiedChars:"/"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "/", "Slash", nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Slash, modifiers:{shiftKey:1}, chars:"?", unmodifiedChars:"?"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "?", "Slash", nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Slash, modifiers:{ctrlKey:1}, chars:"/", unmodifiedChars:"/"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "/", "Slash", nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Slash, modifiers:{altKey:1}, chars:"\u00F7", unmodifiedChars:"/"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "\u00F7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00F7", "Slash", nsIDOMKeyEvent.DOM_VK_SLASH, "\u00F7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Slash, modifiers:{metaKey:1}, chars:"/", unmodifiedChars:"/"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "/", "Slash", nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // numpad yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad1, modifiers:{numericKeyPadKey:1}, chars:"1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "1", "Numpad1", nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad1, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "1", "Numpad1", nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad1, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "1", "Numpad1", nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad1, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "1", "Numpad1", nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad1, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "1", "Numpad1", nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad2, modifiers:{numericKeyPadKey:1}, chars:"2", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "2", "Numpad2", nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad2, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"2", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "2", "Numpad2", nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad2, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"2", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "2", "Numpad2", nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad2, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"2", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "2", "Numpad2", nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad2, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"2", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "2", "Numpad2", nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad3, modifiers:{numericKeyPadKey:1}, chars:"3", unmodifiedChars:"3"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "3", "Numpad3", nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad3, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"3", unmodifiedChars:"3"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "3", "Numpad3", nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad3, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"3", unmodifiedChars:"3"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "3", "Numpad3", nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad3, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"3", unmodifiedChars:"3"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "3", "Numpad3", nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad3, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"3", unmodifiedChars:"3"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "3", "Numpad3", nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad4, modifiers:{numericKeyPadKey:1}, chars:"4", unmodifiedChars:"4"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "4", "Numpad4", nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad4, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"4", unmodifiedChars:"4"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "4", "Numpad4", nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad4, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"4", unmodifiedChars:"4"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "4", "Numpad4", nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad4, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"4", unmodifiedChars:"4"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "4", "Numpad4", nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad4, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"4", unmodifiedChars:"4"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "4", "Numpad4", nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad5, modifiers:{numericKeyPadKey:1}, chars:"5", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "5", "Numpad5", nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad5, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"5", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "5", "Numpad5", nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad5, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"5", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "5", "Numpad5", nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad5, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"5", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "5", "Numpad5", nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad5, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"5", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "5", "Numpad5", nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad6, modifiers:{numericKeyPadKey:1}, chars:"6", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "6", "Numpad6", nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad6, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"6", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "6", "Numpad6", nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad6, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"6", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "6", "Numpad6", nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad6, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"6", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "6", "Numpad6", nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad6, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"6", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "6", "Numpad6", nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad7, modifiers:{numericKeyPadKey:1}, chars:"7", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "7", "Numpad7", nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad7, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"7", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "7", "Numpad7", nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad7, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"7", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "7", "Numpad7", nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad7, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"7", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "7", "Numpad7", nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad7, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"7", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "7", "Numpad7", nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad8, modifiers:{numericKeyPadKey:1}, chars:"8", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "8", "Numpad8", nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad8, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"8", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "8", "Numpad8", nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad8, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"8", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "8", "Numpad8", nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad8, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"8", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "8", "Numpad8", nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad8, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"8", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "8", "Numpad8", nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad9, modifiers:{numericKeyPadKey:1}, chars:"9", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "9", "Numpad9", nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad9, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"9", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "9", "Numpad9", nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad9, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"9", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "9", "Numpad9", nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad9, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"9", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "9", "Numpad9", nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad9, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"9", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "9", "Numpad9", nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad0, modifiers:{numericKeyPadKey:1}, chars:"0", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "0", "Numpad0", nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad0, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"0", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "0", "Numpad0", nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad0, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"0", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "0", "Numpad0", nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad0, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"0", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "0", "Numpad0", nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_Keypad0, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"0", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "0", "Numpad0", nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadEquals, modifiers:{numericKeyPadKey:1}, chars:"=", unmodifiedChars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "=", "NumpadEqual", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadEquals, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"=", unmodifiedChars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "=", "NumpadEqual", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadEquals, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"=", unmodifiedChars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "=", "NumpadEqual", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadEquals, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"=", unmodifiedChars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "=", "NumpadEqual", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadEquals, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"=", unmodifiedChars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "=", "NumpadEqual", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadDivide, modifiers:{numericKeyPadKey:1}, chars:"/", unmodifiedChars:"/"}, - nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "/", "NumpadDivide", nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadDivide, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"/", unmodifiedChars:"/"}, - nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "/", "NumpadDivide", nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadDivide, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"/", unmodifiedChars:"/"}, - nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "/", "NumpadDivide", nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadDivide, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"/", unmodifiedChars:"/"}, - nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "/", "NumpadDivide", nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadDivide, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"/", unmodifiedChars:"/"}, - nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "/", "NumpadDivide", nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadMultiply, modifiers:{numericKeyPadKey:1}, chars:"*", unmodifiedChars:"*"}, - nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "*", "NumpadMultiply", nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadMultiply, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"*", unmodifiedChars:"*"}, - nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "*", "NumpadMultiply", nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadMultiply, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"*", unmodifiedChars:"*"}, - nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "*", "NumpadMultiply", nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadMultiply, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"*", unmodifiedChars:"*"}, - nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "*", "NumpadMultiply", nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadMultiply, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"*", unmodifiedChars:"*"}, - nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "*", "NumpadMultiply", nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadMinus, modifiers:{numericKeyPadKey:1}, chars:"-", unmodifiedChars:"-"}, - nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "-", "NumpadSubtract", nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadMinus, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"-", unmodifiedChars:"-"}, - nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "-", "NumpadSubtract", nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadMinus, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"-", unmodifiedChars:"-"}, - nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "-", "NumpadSubtract", nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadMinus, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"-", unmodifiedChars:"-"}, - nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "-", "NumpadSubtract", nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadMinus, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"-", unmodifiedChars:"-"}, - nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "-", "NumpadSubtract", nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadPlus, modifiers:{numericKeyPadKey:1}, chars:"+", unmodifiedChars:"+"}, - nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "+", "NumpadAdd", nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadPlus, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"+", unmodifiedChars:"+"}, - nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "+", "NumpadAdd", nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadPlus, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"+", unmodifiedChars:"+"}, - nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "+", "NumpadAdd", nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadPlus, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"+", unmodifiedChars:"+"}, - nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "+", "NumpadAdd", nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadPlus, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"+", unmodifiedChars:"+"}, - nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "+", "NumpadAdd", nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadEnter, modifiers:{numericKeyPadKey:1}, chars:"\u0003", unmodifiedChars:"\u0003"}, - nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "Enter", "NumpadEnter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadEnter, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:"\u0003", unmodifiedChars:"\u0003"}, - nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "Enter", "NumpadEnter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadEnter, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:"\u0003", unmodifiedChars:"\u0003"}, - nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "Enter", "NumpadEnter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadEnter, modifiers:{numericKeyPadKey:1, altKey:1}, chars:"\u0003", unmodifiedChars:"\u0003"}, - nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "Enter", "NumpadEnter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_ANSI_KeypadEnter, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:"\u0003", unmodifiedChars:"\u0003"}, - nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "Enter", "NumpadEnter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_JIS_KeypadComma, modifiers:{numericKeyPadKey:1, shiftKey:1}, chars:",", unmodifiedChars:","}, - nsIDOMKeyEvent.DOM_VK_SEPARATOR, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + ",", "NumpadComma", nsIDOMKeyEvent.DOM_VK_SEPARATOR, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_JIS_KeypadComma, modifiers:{numericKeyPadKey:1, ctrlKey:1}, chars:",", unmodifiedChars:","}, - nsIDOMKeyEvent.DOM_VK_SEPARATOR, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + ",", "NumpadComma", nsIDOMKeyEvent.DOM_VK_SEPARATOR, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_JIS_KeypadComma, modifiers:{numericKeyPadKey:1, altKey:1}, chars:",", unmodifiedChars:","}, - nsIDOMKeyEvent.DOM_VK_SEPARATOR, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + ",", "NumpadComma", nsIDOMKeyEvent.DOM_VK_SEPARATOR, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:MAC_VK_JIS_KeypadComma, modifiers:{numericKeyPadKey:1, metaKey:1}, chars:",", unmodifiedChars:","}, - nsIDOMKeyEvent.DOM_VK_SEPARATOR, ",", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + ",", "NumpadComma", nsIDOMKeyEvent.DOM_VK_SEPARATOR, ",", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); // French, numeric yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_1, - modifiers:{}, chars:"\u0026", unmodifiedChars:"\u0026"}, - nsIDOMKeyEvent.DOM_VK_1, "\u0026", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + modifiers:{}, chars:"&", unmodifiedChars:"&"}, + "&", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_1, modifiers:{shiftKey:1}, chars:"1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "1", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_1, - modifiers:{ctrlKey:1}, chars:"1", unmodifiedChars:"\u0026"}, - nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + modifiers:{ctrlKey:1}, chars:"1", unmodifiedChars:"&"}, + "1", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_1, - modifiers:{metaKey:1}, chars:"\u0026", unmodifiedChars:"\u0026"}, - nsIDOMKeyEvent.DOM_VK_1, "\u0026", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + modifiers:{metaKey:1}, chars:"&", unmodifiedChars:"&"}, + "&", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_1, modifiers:{metaKey:1, shiftKey:1}, chars:"1", unmodifiedChars:"1"}, - nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "1", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_2, modifiers:{}, chars:"\u00E9", unmodifiedChars:"\u00E9"}, - nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E9", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_2, modifiers:{shiftKey:1}, chars:"2", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "2", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_2, modifiers:{ctrlKey:1}, chars:"2", unmodifiedChars:"\u00E9"}, - nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "2", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_2, modifiers:{metaKey:1}, chars:"\u00E9", unmodifiedChars:"\u00E9"}, - nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E9", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_2, modifiers:{metaKey:1, shiftKey:1}, chars:"2", unmodifiedChars:"2"}, - nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "2", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_3, modifiers:{}, chars:"\"", unmodifiedChars:"\""}, - nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\"", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_3, modifiers:{shiftKey:1}, chars:"3", unmodifiedChars:"3"}, - nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "3", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_3, modifiers:{ctrlKey:1}, chars:"3", unmodifiedChars:"\""}, - nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "3", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_3, modifiers:{metaKey:1}, chars:"\"", unmodifiedChars:"\""}, - nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\"", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Cmd+Shift+3 is a shortcut key of taking a snapshot // yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_3, // modifiers:{metaKey:1, shiftKey:1}, chars:"\"", unmodifiedChars:"\""}, - // nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "3", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_4, modifiers:{}, chars:"'", unmodifiedChars:"'"}, - nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "'", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_4, modifiers:{shiftKey:1}, chars:"4", unmodifiedChars:"4"}, - nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "4", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_4, modifiers:{ctrlKey:1}, chars:"4", unmodifiedChars:"'"}, - nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "4", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_4, modifiers:{metaKey:1}, chars:"'", unmodifiedChars:"'"}, - nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "'", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Cmd+Shift+4 is a shortcut key of taking a snapshot in specific range // yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_4, // modifiers:{metaKey:1, shiftKey:1}, chars:"4", unmodifiedChars:"4"}, - // nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "4", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_5, modifiers:{}, chars:"(", unmodifiedChars:"("}, - nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "(", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_5, modifiers:{shiftKey:1}, chars:"5", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "5", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_5, modifiers:{ctrlKey:1}, chars:"5", unmodifiedChars:"("}, - nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "5", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_5, modifiers:{metaKey:1}, chars:"(", unmodifiedChars:"("}, - nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "(", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_5, modifiers:{metaKey:1, shiftKey:1}, chars:"5", unmodifiedChars:"5"}, - nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "5", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_6, modifiers:{}, chars:"\u00A7", unmodifiedChars:"\u00A7"}, - nsIDOMKeyEvent.DOM_VK_6, "\u00A7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A7", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "\u00A7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_6, modifiers:{shiftKey:1}, chars:"6", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "6", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // TODO: // yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_6, // modifiers:{ctrlKey:1}, chars:"\u001D", unmodifiedChars:"\u00A7"}, - // nsIDOMKeyEvent.DOM_VK_6, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Ctrl+6 sets strange char + // "6", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Ctrl+6 sets strange char yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_6, modifiers:{metaKey:1}, chars:"\u00A7", unmodifiedChars:"\u00A7"}, - nsIDOMKeyEvent.DOM_VK_6, "\u00A7", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A7", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "\u00A7", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_6, modifiers:{metaKey:1, shiftKey:1}, chars:"6", unmodifiedChars:"6"}, - nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "6", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_7, modifiers:{}, chars:"\u00E8", unmodifiedChars:"\u00E8"}, - nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E8", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_7, modifiers:{shiftKey:1}, chars:"7", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "7", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_7, modifiers:{ctrlKey:1}, chars:"7", unmodifiedChars:"\u00E8"}, - nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "7", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_7, modifiers:{metaKey:1}, chars:"\u00E8", unmodifiedChars:"\u00E8"}, - nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E8", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_7, modifiers:{metaKey:1, shiftKey:1}, chars:"7", unmodifiedChars:"7"}, - nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "7", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_8, modifiers:{}, chars:"!", unmodifiedChars:"!"}, - nsIDOMKeyEvent.DOM_VK_8, "!", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "!", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "!", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_8, modifiers:{shiftKey:1}, chars:"8", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "8", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_8, modifiers:{ctrlKey:1}, chars:"8", unmodifiedChars:"!"}, - nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "8", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_8, modifiers:{metaKey:1}, chars:"!", unmodifiedChars:"!"}, - nsIDOMKeyEvent.DOM_VK_8, "!", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "!", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "!", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_8, modifiers:{metaKey:1, shiftKey:1}, chars:"8", unmodifiedChars:"8"}, - nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "8", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_9, modifiers:{}, chars:"\u00E7", unmodifiedChars:"\u00E7"}, - nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E7", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_9, modifiers:{shiftKey:1}, chars:"9", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "9", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // TODO: // yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_9, // modifiers:{ctrlKey:1}, chars:"\u001C", unmodifiedChars:"\u00E7"}, - // nsIDOMKeyEvent.DOM_VK_9, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Ctrl+9 sets strange char + // "9", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Ctrl+9 sets strange char yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_9, modifiers:{metaKey:1}, chars:"\u00E7", unmodifiedChars:"\u00E7"}, - nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E7", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_9, modifiers:{metaKey:1, shiftKey:1}, chars:"9", unmodifiedChars:"9"}, - nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "9", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_0, modifiers:{}, chars:"\u00E0", unmodifiedChars:"\u00E0"}, - nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_0, modifiers:{shiftKey:1}, chars:"0", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // XXX No events fired, not sure the reason. // yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_0, // modifiers:{ctrlKey:1}, chars:"", unmodifiedChars:"\u00E0"}, - // nsIDOMKeyEvent.DOM_VK_0, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + // "0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_0, modifiers:{metaKey:1}, chars:"\u00E0", unmodifiedChars:"\u00E0"}, - nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:MAC_VK_ANSI_0, modifiers:{metaKey:1, shiftKey:1}, chars:"0", unmodifiedChars:"0"}, - nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Thai // keycode should be DOM_VK_[A-Z] of the key on the latest ASCII capable keyboard layout is for alphabet yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_A, modifiers:{}, chars:"\u0E1F", unmodifiedChars:"\u0E1F"}, - nsIDOMKeyEvent.DOM_VK_A, "\u0E1F", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E1F", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u0E1F", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // keycode should be shifted character if unshifted character isn't an ASCII character yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_Quote, modifiers:{}, chars:"\u0E07", unmodifiedChars:"\u0E07"}, - nsIDOMKeyEvent.DOM_VK_PERIOD, "\u0E07", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E07", "Quote", nsIDOMKeyEvent.DOM_VK_PERIOD, "\u0E07", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // keycode should be zero if the character of the key on the latest ASCII capable keyboard layout isn't for alphabet yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_Period, modifiers:{}, chars:"\u0E43", unmodifiedChars:"\u0E43"}, - 0, "\u0E43", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E43", "Period", 0, "\u0E43", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // keycode should be DOM_VK_[0-9] if the key on the latest ASCII capable keyboard layout is for numeric yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_1, modifiers:{}, chars:"\u0E45", unmodifiedChars:"\u0E45"}, - nsIDOMKeyEvent.DOM_VK_1, "\u0E45", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E45", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "\u0E45", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_2, modifiers:{}, chars:"/", unmodifiedChars:"/"}, - nsIDOMKeyEvent.DOM_VK_2, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "/", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_3, modifiers:{}, chars:"_", unmodifiedChars:"_"}, - nsIDOMKeyEvent.DOM_VK_3, "_", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "_", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "_", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_4, modifiers:{}, chars:"\u0E20", unmodifiedChars:"\u0E20"}, - nsIDOMKeyEvent.DOM_VK_4, "\u0E20", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E20", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "\u0E20", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_5, modifiers:{}, chars:"\u0E16", unmodifiedChars:"\u0E16"}, - nsIDOMKeyEvent.DOM_VK_5, "\u0E16", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E16", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "\u0E16", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_6, modifiers:{}, chars:"\u0E38", unmodifiedChars:"\u0E38"}, - nsIDOMKeyEvent.DOM_VK_6, "\u0E38", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E38", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "\u0E38", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_7, modifiers:{}, chars:"\u0E36", unmodifiedChars:"\u0E36"}, - nsIDOMKeyEvent.DOM_VK_7, "\u0E36", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E36", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "\u0E36", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_8, modifiers:{}, chars:"\u0E04", unmodifiedChars:"\u0E04"}, - nsIDOMKeyEvent.DOM_VK_8, "\u0E04", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E04", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "\u0E04", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_9, modifiers:{}, chars:"\u0E15", unmodifiedChars:"\u0E15"}, - nsIDOMKeyEvent.DOM_VK_9, "\u0E15", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E15", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "\u0E15", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_0, modifiers:{}, chars:"\u0E08", unmodifiedChars:"\u0E08"}, - nsIDOMKeyEvent.DOM_VK_0, "\u0E08", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0E08", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "\u0E08", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dvorak-Qwerty, layout should be changed when Command key is pressed. yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_S, modifiers:{}, chars:"o", unmodifiedChars:"o"}, - nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "o", "KeyS", nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_S, modifiers:{shiftKey:1}, chars:"O", unmodifiedChars:"O"}, - nsIDOMKeyEvent.DOM_VK_O, "O", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "O", "KeyS", nsIDOMKeyEvent.DOM_VK_O, "O", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_S, modifiers:{ctrlKey:1}, chars:"\u000F", unmodifiedChars:"o"}, - nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "o", "KeyS", nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_S, modifiers:{altKey:1}, chars:"\u00F8", unmodifiedChars:"o"}, - nsIDOMKeyEvent.DOM_VK_O, "\u00F8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00F8", "KeyS", nsIDOMKeyEvent.DOM_VK_O, "\u00F8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_S, modifiers:{metaKey:1}, chars:"s", unmodifiedChars:"o"}, - nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "s", "KeyS", nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_D, modifiers:{}, chars:"e", unmodifiedChars:"e"}, - nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "e", "KeyD", nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_D, modifiers:{shiftKey:1}, chars:"E", unmodifiedChars:"E"}, - nsIDOMKeyEvent.DOM_VK_E, "E", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "E", "KeyD", nsIDOMKeyEvent.DOM_VK_E, "E", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_D, modifiers:{ctrlKey:1}, chars:"\u0005", unmodifiedChars:"e"}, - nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "e", "KeyD", nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_D, modifiers:{altKey:1}, chars:"", unmodifiedChars:"e"}, - nsIDOMKeyEvent.DOM_VK_E, "\u00B4", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key + "Dead", "KeyD", nsIDOMKeyEvent.DOM_VK_E, "\u00B4", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // dead key yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_D, modifiers:{metaKey:1}, chars:"d", unmodifiedChars:"e"}, - nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "d", "KeyD", nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_I, modifiers:{metaKey:1, altKey:1}, chars:"^", unmodifiedChars:"c"}, - nsIDOMKeyEvent.DOM_VK_I, "^", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "^", "KeyI", nsIDOMKeyEvent.DOM_VK_I, "^", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_DVORAK_QWERTY, keyCode:MAC_VK_ANSI_I, modifiers:{metaKey:1, altKey:1, shiftKey:1}, chars:"\u02C6", unmodifiedChars:"C"}, - nsIDOMKeyEvent.DOM_VK_I, "\u02C6", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); - } else if (IS_WIN) { + "\u02C6", "KeyI", nsIDOMKeyEvent.DOM_VK_I, "\u02C6", SHOULD_DELIVER_KEYDOWN_KEYPRESS, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + cleanup(); + } + + function testKeysOnWindows() + { // 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 @@ -1892,1095 +1917,1135 @@ function* runKeyEventTests() // Plain text input yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_A, modifiers:{}, chars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_B, modifiers:{}, chars:"b"}, - nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "b", "KeyB", nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_A, modifiers:{shiftKey:1}, chars:"A"}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "A", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Ctrl keys yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_A, modifiers:{ctrlKey:1}, chars:"\u0001"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_A, modifiers:{ctrlKey:1, shiftKey:1}, chars:"\u0001"}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "A", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Alt keys yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_A, modifiers:{altKey:1}, chars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_A, modifiers:{altKey:1, shiftKey:1}, chars:"A"}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "A", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Shift-ctrl-alt generates no WM_CHAR, but we still get a keypress yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_A, modifiers:{altKey:1, ctrlKey:1, shiftKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "A", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Greek plain text yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:WIN_VK_A, modifiers:{}, chars:"\u03b1"}, - nsIDOMKeyEvent.DOM_VK_A, "\u03b1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u03b1", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u03b1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:WIN_VK_A, modifiers:{shiftKey:1}, chars:"\u0391"}, - nsIDOMKeyEvent.DOM_VK_A, "\u0391", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0391", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u0391", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Greek ctrl keys produce Latin charcodes yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:WIN_VK_A, modifiers:{ctrlKey:1}, chars:"\u0001"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u03b1", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_GREEK, keyCode:WIN_VK_A, modifiers:{ctrlKey:1, shiftKey:1}, chars:"\u0001"}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u0391", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Caps Lock key event yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_CAPITAL, modifiers:{capsLockKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "CapsLock", "CapsLock", nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_CAPITAL, modifiers:{capsLockKey:0}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "CapsLock", "CapsLock", nsIDOMKeyEvent.DOM_VK_CAPS_LOCK, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Shift keys yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_LSHIFT, modifiers:{shiftKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Shift", "ShiftLeft", nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RSHIFT, modifiers:{shiftRightKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Shift", "ShiftRight", nsIDOMKeyEvent.DOM_VK_SHIFT, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); // Ctrl keys yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_LCONTROL, modifiers:{ctrlKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Control", "ControlLeft", nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RCONTROL, modifiers:{ctrlRightKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Control", "ControlRight", nsIDOMKeyEvent.DOM_VK_CONTROL, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); // Alt keys yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_LMENU, modifiers:{altKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "Alt", "AltLeft", nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RMENU, modifiers:{altRightKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "Alt", "AltRight", nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); // Win keys yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_LWIN, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_WIN, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); + "OS" /* bug 1232918 */, "OSLeft", nsIDOMKeyEvent.DOM_VK_WIN, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RWIN, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_WIN, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); + "OS" /* bug 1232918 */, "OSRight", nsIDOMKeyEvent.DOM_VK_WIN, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT); // all keys on keyboard (keyCode test) yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_BACK, modifiers:{}, chars:"\u0008"}, - nsIDOMKeyEvent.DOM_VK_BACK_SPACE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Backspace", "Backspace", nsIDOMKeyEvent.DOM_VK_BACK_SPACE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_TAB, modifiers:{}, chars:"\t"}, - nsIDOMKeyEvent.DOM_VK_TAB, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Tab", "Tab", nsIDOMKeyEvent.DOM_VK_TAB, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RETURN, modifiers:{}, chars:"\r"}, - nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Enter", "Enter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_PAUSE, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_PAUSE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Pause", "Pause", nsIDOMKeyEvent.DOM_VK_PAUSE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_KANA, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_KANA, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Unidentified", "", nsIDOMKeyEvent.DOM_VK_KANA, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_JUNJA, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_JUNJA, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "JunjaMode", "", nsIDOMKeyEvent.DOM_VK_JUNJA, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_FINAL, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_FINAL, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "FinalMode", "", nsIDOMKeyEvent.DOM_VK_FINAL, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_KANJI, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_KANJI, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Unidentified", "", nsIDOMKeyEvent.DOM_VK_KANJI, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_ESCAPE, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_ESCAPE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Escape", "Escape", nsIDOMKeyEvent.DOM_VK_ESCAPE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_CONVERT, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CONVERT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Convert", "", nsIDOMKeyEvent.DOM_VK_CONVERT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NONCONVERT, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_NONCONVERT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "NonConvert", "", nsIDOMKeyEvent.DOM_VK_NONCONVERT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_ACCEPT, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_ACCEPT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Accept", "", nsIDOMKeyEvent.DOM_VK_ACCEPT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_MODECHANGE, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_MODECHANGE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "ModeChange", "", nsIDOMKeyEvent.DOM_VK_MODECHANGE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_SPACE, modifiers:{}, chars:" "}, - nsIDOMKeyEvent.DOM_VK_SPACE, " ", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + " ", "Space", nsIDOMKeyEvent.DOM_VK_SPACE, " ", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_SELECT, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_SELECT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Select", "", nsIDOMKeyEvent.DOM_VK_SELECT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_PRINT, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_PRINT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Unidentified", "", nsIDOMKeyEvent.DOM_VK_PRINT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_EXECUTE, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_EXECUTE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Execute", "", nsIDOMKeyEvent.DOM_VK_EXECUTE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_SNAPSHOT, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_PRINTSCREEN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "PrintScreen", "PrintScreen", nsIDOMKeyEvent.DOM_VK_PRINTSCREEN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_HELP, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_HELP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Help", "", nsIDOMKeyEvent.DOM_VK_HELP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_SLEEP, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_SLEEP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); - // XXX TODO: we cannot test Home, Up, PageUp, Left, Right, End, Down, PageDown, Ins and Del. + "Standby", "", nsIDOMKeyEvent.DOM_VK_SLEEP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_PRIOR, + modifiers:{}, chars:""}, + "PageUp", "PageUp", nsIDOMKeyEvent.DOM_VK_PAGE_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NEXT, + modifiers:{}, chars:""}, + "PageDown", "PageDown", nsIDOMKeyEvent.DOM_VK_PAGE_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_END, + modifiers:{}, chars:""}, + "End", "End", nsIDOMKeyEvent.DOM_VK_END, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_HOME, + modifiers:{}, chars:""}, + "Home", "Home", nsIDOMKeyEvent.DOM_VK_HOME, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_LEFT, + modifiers:{}, chars:""}, + "ArrowLeft", "ArrowLeft", nsIDOMKeyEvent.DOM_VK_LEFT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_UP, + modifiers:{}, chars:""}, + "ArrowUp", "ArrowUp", nsIDOMKeyEvent.DOM_VK_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RIGHT, + modifiers:{}, chars:""}, + "ArrowRight", "ArrowRight", nsIDOMKeyEvent.DOM_VK_RIGHT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DOWN, + modifiers:{}, chars:""}, + "ArrowDown", "ArrowDown", nsIDOMKeyEvent.DOM_VK_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_INSERT, + modifiers:{}, chars:""}, + "Insert", "Insert", nsIDOMKeyEvent.DOM_VK_INSERT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DELETE, + modifiers:{}, chars:""}, + "Delete", "Delete", nsIDOMKeyEvent.DOM_VK_DELETE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Backspace and Enter are handled with special path in mozilla::widget::NativeKey. So, let's test them with modifiers too. yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_BACK, modifiers:{ctrlKey:1}, chars:"\u007F"}, - nsIDOMKeyEvent.DOM_VK_BACK_SPACE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Backspace", "Backspace", nsIDOMKeyEvent.DOM_VK_BACK_SPACE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_BACK, modifiers:{altKey:1}, chars:"\u0008"}, - nsIDOMKeyEvent.DOM_VK_BACK_SPACE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Backspace", "Backspace", nsIDOMKeyEvent.DOM_VK_BACK_SPACE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RETURN, modifiers:{ctrlKey:1}, chars:"\n"}, - nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Enter", "Enter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RETURN, modifiers:{altKey:1}, chars:"\r"}, - nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Enter", "Enter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // US // Alphabet yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_A, modifiers:{}, chars:"a"}, - nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_A, modifiers:{shiftKey:1}, chars:"A"}, - nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "A", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "A", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_B, modifiers:{}, chars:"b"}, - nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "b", "KeyB", nsIDOMKeyEvent.DOM_VK_B, "b", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_B, modifiers:{shiftKey:1}, chars:"B"}, - nsIDOMKeyEvent.DOM_VK_B, "B", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "B", "KeyB", nsIDOMKeyEvent.DOM_VK_B, "B", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_C, modifiers:{}, chars:"c"}, - nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "c", "KeyC", nsIDOMKeyEvent.DOM_VK_C, "c", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_C, modifiers:{shiftKey:1}, chars:"C"}, - nsIDOMKeyEvent.DOM_VK_C, "C", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "C", "KeyC", nsIDOMKeyEvent.DOM_VK_C, "C", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_D, modifiers:{}, chars:"d"}, - nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "d", "KeyD", nsIDOMKeyEvent.DOM_VK_D, "d", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_D, modifiers:{shiftKey:1}, chars:"D"}, - nsIDOMKeyEvent.DOM_VK_D, "D", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "D", "KeyD", nsIDOMKeyEvent.DOM_VK_D, "D", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_E, modifiers:{}, chars:"e"}, - nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "e", "KeyE", nsIDOMKeyEvent.DOM_VK_E, "e", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_E, modifiers:{shiftKey:1}, chars:"E"}, - nsIDOMKeyEvent.DOM_VK_E, "E", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "E", "KeyE", nsIDOMKeyEvent.DOM_VK_E, "E", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_F, modifiers:{}, chars:"f"}, - nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "f", "KeyF", nsIDOMKeyEvent.DOM_VK_F, "f", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_F, modifiers:{shiftKey:1}, chars:"F"}, - nsIDOMKeyEvent.DOM_VK_F, "F", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "F", "KeyF", nsIDOMKeyEvent.DOM_VK_F, "F", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_G, modifiers:{}, chars:"g"}, - nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "g", "KeyG", nsIDOMKeyEvent.DOM_VK_G, "g", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_G, modifiers:{shiftKey:1}, chars:"G"}, - nsIDOMKeyEvent.DOM_VK_G, "G", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "G", "KeyG", nsIDOMKeyEvent.DOM_VK_G, "G", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_H, modifiers:{}, chars:"h"}, - nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "h", "KeyH", nsIDOMKeyEvent.DOM_VK_H, "h", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_H, modifiers:{shiftKey:1}, chars:"H"}, - nsIDOMKeyEvent.DOM_VK_H, "H", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "H", "KeyH", nsIDOMKeyEvent.DOM_VK_H, "H", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_I, modifiers:{}, chars:"i"}, - nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "i", "KeyI", nsIDOMKeyEvent.DOM_VK_I, "i", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_I, modifiers:{shiftKey:1}, chars:"I"}, - nsIDOMKeyEvent.DOM_VK_I, "I", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "I", "KeyI", nsIDOMKeyEvent.DOM_VK_I, "I", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_J, modifiers:{}, chars:"j"}, - nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "j", "KeyJ", nsIDOMKeyEvent.DOM_VK_J, "j", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_J, modifiers:{shiftKey:1}, chars:"J"}, - nsIDOMKeyEvent.DOM_VK_J, "J", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "J", "KeyJ", nsIDOMKeyEvent.DOM_VK_J, "J", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_K, modifiers:{}, chars:"k"}, - nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "k", "KeyK", nsIDOMKeyEvent.DOM_VK_K, "k", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_K, modifiers:{shiftKey:1}, chars:"K"}, - nsIDOMKeyEvent.DOM_VK_K, "K", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "K", "KeyK", nsIDOMKeyEvent.DOM_VK_K, "K", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_L, modifiers:{}, chars:"l"}, - nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "l", "KeyL", nsIDOMKeyEvent.DOM_VK_L, "l", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_L, modifiers:{shiftKey:1}, chars:"L"}, - nsIDOMKeyEvent.DOM_VK_L, "L", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "L", "KeyL", nsIDOMKeyEvent.DOM_VK_L, "L", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_M, modifiers:{}, chars:"m"}, - nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "m", "KeyM", nsIDOMKeyEvent.DOM_VK_M, "m", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_M, modifiers:{shiftKey:1}, chars:"M"}, - nsIDOMKeyEvent.DOM_VK_M, "M", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "M", "KeyM", nsIDOMKeyEvent.DOM_VK_M, "M", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_N, modifiers:{}, chars:"n"}, - nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "n", "KeyN", nsIDOMKeyEvent.DOM_VK_N, "n", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_N, modifiers:{shiftKey:1}, chars:"N"}, - nsIDOMKeyEvent.DOM_VK_N, "N", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "N", "KeyN", nsIDOMKeyEvent.DOM_VK_N, "N", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_O, modifiers:{}, chars:"o"}, - nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "o", "KeyO", nsIDOMKeyEvent.DOM_VK_O, "o", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_O, modifiers:{shiftKey:1}, chars:"O"}, - nsIDOMKeyEvent.DOM_VK_O, "O", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "O", "KeyO", nsIDOMKeyEvent.DOM_VK_O, "O", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_P, modifiers:{}, chars:"p"}, - nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "p", "KeyP", nsIDOMKeyEvent.DOM_VK_P, "p", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_P, modifiers:{shiftKey:1}, chars:"P"}, - nsIDOMKeyEvent.DOM_VK_P, "P", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "P", "KeyP", nsIDOMKeyEvent.DOM_VK_P, "P", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_Q, modifiers:{}, chars:"q"}, - nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "q", "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_Q, modifiers:{shiftKey:1}, chars:"Q"}, - nsIDOMKeyEvent.DOM_VK_Q, "Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Q", "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_R, modifiers:{}, chars:"r"}, - nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "r", "KeyR", nsIDOMKeyEvent.DOM_VK_R, "r", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_R, modifiers:{shiftKey:1}, chars:"R"}, - nsIDOMKeyEvent.DOM_VK_R, "R", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "R", "KeyR", nsIDOMKeyEvent.DOM_VK_R, "R", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_S, modifiers:{}, chars:"s"}, - nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "s", "KeyS", nsIDOMKeyEvent.DOM_VK_S, "s", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_S, modifiers:{shiftKey:1}, chars:"S"}, - nsIDOMKeyEvent.DOM_VK_S, "S", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "S", "KeyS", nsIDOMKeyEvent.DOM_VK_S, "S", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_T, modifiers:{}, chars:"t"}, - nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "t", "KeyT", nsIDOMKeyEvent.DOM_VK_T, "t", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_T, modifiers:{shiftKey:1}, chars:"T"}, - nsIDOMKeyEvent.DOM_VK_T, "T", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "T", "KeyT", nsIDOMKeyEvent.DOM_VK_T, "T", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_U, modifiers:{}, chars:"u"}, - nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "u", "KeyU", nsIDOMKeyEvent.DOM_VK_U, "u", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_U, modifiers:{shiftKey:1}, chars:"U"}, - nsIDOMKeyEvent.DOM_VK_U, "U", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "U", "KeyU", nsIDOMKeyEvent.DOM_VK_U, "U", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_V, modifiers:{}, chars:"v"}, - nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "v", "KeyV", nsIDOMKeyEvent.DOM_VK_V, "v", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_V, modifiers:{shiftKey:1}, chars:"V"}, - nsIDOMKeyEvent.DOM_VK_V, "V", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "V", "KeyV", nsIDOMKeyEvent.DOM_VK_V, "V", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_W, modifiers:{}, chars:"w"}, - nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "w", "KeyW", nsIDOMKeyEvent.DOM_VK_W, "w", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_W, modifiers:{shiftKey:1}, chars:"W"}, - nsIDOMKeyEvent.DOM_VK_W, "W", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "W", "KeyW", nsIDOMKeyEvent.DOM_VK_W, "W", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_X, modifiers:{}, chars:"x"}, - nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "x", "KeyX", nsIDOMKeyEvent.DOM_VK_X, "x", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_X, modifiers:{shiftKey:1}, chars:"X"}, - nsIDOMKeyEvent.DOM_VK_X, "X", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "X", "KeyX", nsIDOMKeyEvent.DOM_VK_X, "X", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_Y, modifiers:{}, chars:"y"}, - nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "y", "KeyY", nsIDOMKeyEvent.DOM_VK_Y, "y", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_Y, modifiers:{shiftKey:1}, chars:"Y"}, - nsIDOMKeyEvent.DOM_VK_Y, "Y", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Y", "KeyY", nsIDOMKeyEvent.DOM_VK_Y, "Y", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_Z, modifiers:{}, chars:"z"}, - nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "z", "KeyZ", nsIDOMKeyEvent.DOM_VK_Z, "z", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_Z, modifiers:{shiftKey:1}, chars:"Z"}, - nsIDOMKeyEvent.DOM_VK_Z, "Z", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Z", "KeyZ", nsIDOMKeyEvent.DOM_VK_Z, "Z", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Numeric yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_0, modifiers:{}, chars:"0"}, - nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_0, modifiers:{shiftKey:1}, chars:")"}, - nsIDOMKeyEvent.DOM_VK_0, ")", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ")", "Digit0", nsIDOMKeyEvent.DOM_VK_0, ")", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_1, modifiers:{}, chars:"1"}, - nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "1", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_1, modifiers:{shiftKey:1}, chars:"!"}, - nsIDOMKeyEvent.DOM_VK_1, "!", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "!", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "!", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_2, modifiers:{}, chars:"2"}, - nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "2", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_2, modifiers:{shiftKey:1}, chars:"@"}, - nsIDOMKeyEvent.DOM_VK_2, "@", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "@", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "@", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_3, modifiers:{}, chars:"3"}, - nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "3", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_3, modifiers:{shiftKey:1}, chars:"#"}, - nsIDOMKeyEvent.DOM_VK_3, "#", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "#", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "#", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_4, modifiers:{}, chars:"4"}, - nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "4", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_4, modifiers:{shiftKey:1}, chars:"$"}, - nsIDOMKeyEvent.DOM_VK_4, "$", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "$", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "$", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_5, modifiers:{}, chars:"5"}, - nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "5", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_5, modifiers:{shiftKey:1}, chars:"%"}, - nsIDOMKeyEvent.DOM_VK_5, "%", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "%", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "%", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_6, modifiers:{}, chars:"6"}, - nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "6", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_6, modifiers:{shiftKey:1}, chars:"^"}, - nsIDOMKeyEvent.DOM_VK_6, "^", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "^", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "^", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_7, modifiers:{}, chars:"7"}, - nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "7", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_7, modifiers:{shiftKey:1}, chars:"&"}, - nsIDOMKeyEvent.DOM_VK_7, "&", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "&", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "&", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_8, modifiers:{}, chars:"8"}, - nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "8", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_8, modifiers:{shiftKey:1}, chars:"*"}, - nsIDOMKeyEvent.DOM_VK_8, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "*", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_9, modifiers:{}, chars:"9"}, - nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "9", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_9, modifiers:{shiftKey:1}, chars:"("}, - nsIDOMKeyEvent.DOM_VK_9, "(", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "(", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "(", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // OEM keys yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_MINUS, modifiers:{}, chars:"-"}, - nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "-", "Minus", nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_MINUS, modifiers:{shiftKey:1}, chars:"_"}, - nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "_", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "_", "Minus", nsIDOMKeyEvent.DOM_VK_HYPHEN_MINUS, "_", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_PLUS, modifiers:{}, chars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "=", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_PLUS, modifiers:{shiftKey:1}, chars:"+"}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "+", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_4, modifiers:{}, chars:"["}, - nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "[", "BracketLeft", nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "[", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_4, modifiers:{shiftKey:1}, chars:"{"}, - nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "{", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "{", "BracketLeft", nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "{", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_6, modifiers:{}, chars:"]"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "]", "BracketRight", nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "]", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_6, modifiers:{shiftKey:1}, chars:"}"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "}", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "}", "BracketRight", nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "}", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_1, modifiers:{}, chars:";"}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ";", "Semicolon", nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_1, modifiers:{shiftKey:1}, chars:":"}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, ":", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ":", "Semicolon", nsIDOMKeyEvent.DOM_VK_SEMICOLON, ":", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_7, modifiers:{}, chars:"'"}, - nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "'", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_7, modifiers:{shiftKey:1}, chars:"\""}, - nsIDOMKeyEvent.DOM_VK_QUOTE, "\"", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\"", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "\"", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_5, modifiers:{}, chars:"\\"}, - nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\\", "Backslash", nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "\\", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_5, modifiers:{shiftKey:1}, chars:"|"}, - nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "|", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "|", "Backslash", nsIDOMKeyEvent.DOM_VK_BACK_SLASH, "|", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_COMMA, modifiers:{}, chars:","}, - nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ",", "Comma", nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_COMMA, modifiers:{shiftKey:1}, chars:"<"}, - nsIDOMKeyEvent.DOM_VK_COMMA, "<", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "<", "Comma", nsIDOMKeyEvent.DOM_VK_COMMA, "<", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_PERIOD, modifiers:{}, chars:"."}, - nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ".", "Period", nsIDOMKeyEvent.DOM_VK_PERIOD, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_PERIOD, modifiers:{shiftKey:1}, chars:">"}, - nsIDOMKeyEvent.DOM_VK_PERIOD, ">", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ">", "Period", nsIDOMKeyEvent.DOM_VK_PERIOD, ">", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_2, modifiers:{}, chars:"/"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "/", "Slash", nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_2, modifiers:{shiftKey:1}, chars:"?"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "?", "Slash", nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_3, modifiers:{}, chars:"`"}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "`", "Backquote", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "`", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_OEM_3, modifiers:{shiftKey:1}, chars:"~"}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "~", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "~", "Backquote", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "~", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Numpad yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD0, modifiers:{numLockKey:1}, chars:"0"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "0", "Numpad0", nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD1, modifiers:{numLockKey:1}, chars:"1"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "1", "Numpad1", nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD2, modifiers:{numLockKey:1}, chars:"2"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "2", "Numpad2", nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD3, modifiers:{numLockKey:1}, chars:"3"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "3", "Numpad3", nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD4, modifiers:{numLockKey:1}, chars:"4"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "4", "Numpad4", nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD5, modifiers:{numLockKey:1}, chars:"5"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "5", "Numpad5", nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD6, modifiers:{numLockKey:1}, chars:"6"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "6", "Numpad6", nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD7, modifiers:{numLockKey:1}, chars:"7"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "7", "Numpad7", nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD8, modifiers:{numLockKey:1}, chars:"8"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "8", "Numpad8", nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD9, modifiers:{numLockKey:1}, chars:"9"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "9", "Numpad9", nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_MULTIPLY, modifiers:{numLockKey:1}, chars:"*"}, - nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "*", "NumpadMultiply", nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_MULTIPLY, modifiers:{numLockKey:1, shiftKey:1}, chars:"*"}, - nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "*", "NumpadMultiply", nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_ADD, modifiers:{numLockKey:1}, chars:"+"}, - nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "+", "NumpadAdd", nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_ADD, modifiers:{numLockKey:1, shiftKey:1}, chars:"+"}, - nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "+", "NumpadAdd", nsIDOMKeyEvent.DOM_VK_ADD, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); // 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. //yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_SEPARATOR, // modifiers:{numLockKey:1}, chars:""}, - // nsIDOMKeyEvent.DOM_VK_SEPARATOR, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + // "", "", nsIDOMKeyEvent.DOM_VK_SEPARATOR, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); //yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_SEPARATOR, // modifiers:{numLockKey:1, shiftKey:1}, chars:""}, - // nsIDOMKeyEvent.DOM_VK_SEPARATOR, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + // "", "", nsIDOMKeyEvent.DOM_VK_SEPARATOR, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_SUBTRACT, modifiers:{numLockKey:1}, chars:"-"}, - nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "-", "NumpadSubtract", nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_SUBTRACT, modifiers:{numLockKey:1, shiftKey:1}, chars:"-"}, - nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "-", "NumpadSubtract", nsIDOMKeyEvent.DOM_VK_SUBTRACT, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DECIMAL, modifiers:{numLockKey:1}, chars:"."}, - nsIDOMKeyEvent.DOM_VK_DECIMAL, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + ".", "NumpadDecimal", nsIDOMKeyEvent.DOM_VK_DECIMAL, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DECIMAL, modifiers:{numLockKey:1, shiftKey:1}, chars:"."}, - nsIDOMKeyEvent.DOM_VK_DECIMAL, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + ".", "NumpadDecimal", nsIDOMKeyEvent.DOM_VK_DECIMAL, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DIVIDE, modifiers:{numLockKey:1}, chars:"/"}, - nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "/", "NumpadDivide", nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DIVIDE, modifiers:{numLockKey:1, shiftKey:1}, chars:"/"}, - nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "/", "NumpadDivide", nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_RETURN, + modifiers:{numLockKey:1}, chars:"\r"}, + "Enter", "NumpadEnter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_RETURN, + modifiers:{numLockKey:1, shiftKey:1}, chars:"\r"}, + "Enter", "NumpadEnter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); // Numpad without NumLock - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_PRIOR, + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_PRIOR, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_PAGE_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NEXT, + "PageUp", "Numpad9", nsIDOMKeyEvent.DOM_VK_PAGE_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_NEXT, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_PAGE_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_END, + "PageDown", "Numpad3", nsIDOMKeyEvent.DOM_VK_PAGE_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_END, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_END, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_HOME, + "End", "Numpad1", nsIDOMKeyEvent.DOM_VK_END, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_HOME, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_HOME, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_LEFT, + "Home", "Numpad7", nsIDOMKeyEvent.DOM_VK_HOME, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_LEFT, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_LEFT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_UP, + "ArrowLeft", "Numpad4", nsIDOMKeyEvent.DOM_VK_LEFT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_UP, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RIGHT, + "ArrowUp", "Numpad8", nsIDOMKeyEvent.DOM_VK_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_RIGHT, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_RIGHT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DOWN, + "ArrowRight", "Numpad6", nsIDOMKeyEvent.DOM_VK_RIGHT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_DOWN, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_INSERT, + "ArrowDown", "Numpad2", nsIDOMKeyEvent.DOM_VK_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_INSERT, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_INSERT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); - yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DELETE, + "Insert", "Numpad0", nsIDOMKeyEvent.DOM_VK_INSERT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_DELETE, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_DELETE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "Delete", "NumpadDecimal", nsIDOMKeyEvent.DOM_VK_DELETE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_CLEAR, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CLEAR, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "Clear", "Numpad5", nsIDOMKeyEvent.DOM_VK_CLEAR, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); // Even if widget receives unknown keycode, it should dispatch key events // whose keycode is 0 rather than native keycode. yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:0x3A, modifiers:{numLockKey:1}, chars:""}, - 0, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Unidentified", "", 0, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // French // Numeric yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_0, modifiers:{}, chars:"\u00E0"}, - nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_0, modifiers:{shiftKey:1}, chars:"0"}, - nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_1, modifiers:{}, chars:"&"}, - nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "&", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_1, modifiers:{shiftKey:1}, chars:"1"}, - nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "1", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_2, modifiers:{}, chars:"\u00E9"}, - nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E9", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_2, modifiers:{shiftKey:1}, chars:"2"}, - nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "2", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_3, modifiers:{}, chars:"\""}, - nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\"", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_3, modifiers:{shiftKey:1}, chars:"3"}, - nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "3", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_4, modifiers:{}, chars:"'"}, - nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "'", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_4, modifiers:{shiftKey:1}, chars:"4"}, - nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "4", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_5, modifiers:{}, chars:"("}, - nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "(", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_5, modifiers:{shiftKey:1}, chars:"5"}, - nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "5", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_6, modifiers:{}, chars:"-"}, - nsIDOMKeyEvent.DOM_VK_6, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "-", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_6, modifiers:{shiftKey:1}, chars:"6"}, - nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "6", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_7, modifiers:{}, chars:"\u00E8"}, - nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E8", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_7, modifiers:{shiftKey:1}, chars:"7"}, - nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "7", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_8, modifiers:{}, chars:"_"}, - nsIDOMKeyEvent.DOM_VK_8, "_", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "_", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "_", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_8, modifiers:{shiftKey:1}, chars:"8"}, - nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "8", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_9, modifiers:{}, chars:"\u00E7"}, - nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E7", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_9, modifiers:{shiftKey:1}, chars:"9"}, - nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "9", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Numeric with ShiftLock yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_0, modifiers:{capsLockKey:1}, chars:"0"}, - nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_0, modifiers:{capsLockKey:1, shiftKey:1}, chars:"\u00E0"}, - nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E0", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "\u00E0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_1, modifiers:{capsLockKey:1}, chars:"1"}, - nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "1", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_1, modifiers:{capsLockKey:1, shiftKey:1}, chars:"&"}, - nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "&", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_2, modifiers:{capsLockKey:1}, chars:"2"}, - nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "2", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_2, modifiers:{capsLockKey:1, shiftKey:1}, chars:"\u00E9"}, - nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E9", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "\u00E9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_3, modifiers:{capsLockKey:1}, chars:"3"}, - nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "3", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_3, modifiers:{capsLockKey:1, shiftKey:1}, chars:"\""}, - nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\"", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "\"", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_4, modifiers:{capsLockKey:1}, chars:"4"}, - nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "4", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_4, modifiers:{capsLockKey:1, shiftKey:1}, chars:"'"}, - nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "'", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_5, modifiers:{capsLockKey:1}, chars:"5"}, - nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "5", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_5, modifiers:{capsLockKey:1, shiftKey:1}, chars:"("}, - nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "(", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "(", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_6, modifiers:{capsLockKey:1}, chars:"6"}, - nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "6", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "6", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_6, modifiers:{capsLockKey:1, shiftKey:1}, chars:"-"}, - nsIDOMKeyEvent.DOM_VK_6, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "-", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "-", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_7, modifiers:{capsLockKey:1}, chars:"7"}, - nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "7", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_7, modifiers:{capsLockKey:1, shiftKey:1}, chars:"\u00E8"}, - nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E8", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "\u00E8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_8, modifiers:{capsLockKey:1}, chars:"8"}, - nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "8", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_8, modifiers:{capsLockKey:1, shiftKey:1}, chars:"_"}, - nsIDOMKeyEvent.DOM_VK_8, "_", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "_", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "_", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_9, modifiers:{capsLockKey:1}, chars:"9"}, - nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "9", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_9, modifiers:{capsLockKey:1, shiftKey:1}, chars:"\u00E7"}, - nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00E7", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // OEM keys yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_7, modifiers:{}, chars:"\u00B2"}, - 0, "\u00B2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00B2", "Backquote", 0, "\u00B2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_7, modifiers:{shiftKey:1}, chars:""}, - 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "", "Backquote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_4, modifiers:{}, chars:")"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, ")", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ")", "Minus", nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, ")", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_4, modifiers:{shiftKey:1}, chars:"\u00B0"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, "\u00B0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00B0", "Minus", nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, "\u00B0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_PLUS, modifiers:{}, chars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "=", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_PLUS, modifiers:{shiftKey:1}, chars:"+"}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "+", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); //yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, // modifiers:{}, chars:""}, - // nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key + // "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key //yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, // modifiers:{shiftKey:1}, chars:""}, - // nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key + // ["^^", "^", "^", "^"], "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_1, modifiers:{}, chars:"$"}, - nsIDOMKeyEvent.DOM_VK_DOLLAR, "$", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "$", "BracketRight", nsIDOMKeyEvent.DOM_VK_DOLLAR, "$", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_1, modifiers:{shiftKey:1}, chars:"\u00A3"}, - nsIDOMKeyEvent.DOM_VK_DOLLAR, "\u00A3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A3", "BracketRight", nsIDOMKeyEvent.DOM_VK_DOLLAR, "\u00A3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_3, modifiers:{}, chars:"\u00F9"}, - nsIDOMKeyEvent.DOM_VK_PERCENT, "\u00F9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00F9", "Quote", nsIDOMKeyEvent.DOM_VK_PERCENT, "\u00F9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_3, modifiers:{shiftKey:1}, chars:"%"}, - nsIDOMKeyEvent.DOM_VK_PERCENT, "%", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "%", "Quote", nsIDOMKeyEvent.DOM_VK_PERCENT, "%", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_5, modifiers:{}, chars:"*"}, - nsIDOMKeyEvent.DOM_VK_ASTERISK, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "*", "Backslash", nsIDOMKeyEvent.DOM_VK_ASTERISK, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_5, modifiers:{shiftKey:1}, chars:"\u00B5"}, - nsIDOMKeyEvent.DOM_VK_ASTERISK, "\u00B5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00B5", "Backslash", nsIDOMKeyEvent.DOM_VK_ASTERISK, "\u00B5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_102, modifiers:{}, chars:"<"}, - nsIDOMKeyEvent.DOM_VK_LESS_THAN, "<", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "<", "IntlBackslash", nsIDOMKeyEvent.DOM_VK_LESS_THAN, "<", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_102, modifiers:{shiftKey:1}, chars:">"}, - nsIDOMKeyEvent.DOM_VK_LESS_THAN, ">", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ">", "IntlBackslash", nsIDOMKeyEvent.DOM_VK_LESS_THAN, ">", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_COMMA, modifiers:{}, chars:","}, - nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ",", "KeyM", nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_COMMA, modifiers:{shiftKey:1}, chars:"?"}, - nsIDOMKeyEvent.DOM_VK_COMMA, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "?", "KeyM", nsIDOMKeyEvent.DOM_VK_COMMA, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_PERIOD, modifiers:{}, chars:";"}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ";", "Comma", nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_PERIOD, modifiers:{shiftKey:1}, chars:"."}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ".", "Comma", nsIDOMKeyEvent.DOM_VK_SEMICOLON, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_2, modifiers:{}, chars:":"}, - nsIDOMKeyEvent.DOM_VK_COLON, ":", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ":", "Period", nsIDOMKeyEvent.DOM_VK_COLON, ":", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_2, modifiers:{shiftKey:1}, chars:"/"}, - nsIDOMKeyEvent.DOM_VK_COLON, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "/", "Period", nsIDOMKeyEvent.DOM_VK_COLON, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_8, modifiers:{}, chars:"!"}, - nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "!", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "!", "Slash", nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "!", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_8, modifiers:{shiftKey:1}, chars:"\u00A7"}, - nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "\u00A7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A7", "Slash", nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "\u00A7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // OEM keys with ShiftLock yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_7, modifiers:{capsLockKey:1}, chars:"\u00B2"}, - 0, "\u00B2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00B2", "Backquote", 0, "\u00B2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_7, modifiers:{capsLockKey:1, shiftKey:1}, chars:""}, - 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "", "Backquote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_4, modifiers:{capsLockKey:1}, chars:"\u00B0"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, "\u00B0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00B0", "Minus", nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, "\u00B0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_4, modifiers:{capsLockKey:1, shiftKey:1}, chars:")"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, ")", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ")", "Minus", nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, ")", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_PLUS, modifiers:{capsLockKey:1}, chars:"+"}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "+", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "+", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_PLUS, modifiers:{capsLockKey:1, shiftKey:1}, chars:"="}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "=", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); //yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, // modifiers:{capsLockKey:1}, chars:""}, - // 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key + // "Dead", "BracketLeft", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key //yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, // modifiers:{capsLockKey:1, shiftKey:1}, chars:""}, - // 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key + // ["\u00A8\u00A8", "\u00A8", "\u00A8", "\u00A8"], "BracketLeft", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_1, modifiers:{capsLockKey:1}, chars:"\u00A3"}, - nsIDOMKeyEvent.DOM_VK_DOLLAR, "\u00A3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A3", "BracketRight", nsIDOMKeyEvent.DOM_VK_DOLLAR, "\u00A3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_1, modifiers:{capsLockKey:1, shiftKey:1}, chars:"$"}, - nsIDOMKeyEvent.DOM_VK_DOLLAR, "$", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "$", "BracketRight", nsIDOMKeyEvent.DOM_VK_DOLLAR, "$", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_3, modifiers:{capsLockKey:1}, chars:"%"}, - nsIDOMKeyEvent.DOM_VK_PERCENT, "%", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "%", "Quote", nsIDOMKeyEvent.DOM_VK_PERCENT, "%", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_3, modifiers:{capsLockKey:1, shiftKey:1}, chars:"\u00F9"}, - nsIDOMKeyEvent.DOM_VK_PERCENT, "\u00F9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00F9", "Quote", nsIDOMKeyEvent.DOM_VK_PERCENT, "\u00F9", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_5, modifiers:{capsLockKey:1}, chars:"\u00B5"}, - nsIDOMKeyEvent.DOM_VK_ASTERISK, "\u00B5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00B5", "Backslash", nsIDOMKeyEvent.DOM_VK_ASTERISK, "\u00B5", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_5, modifiers:{capsLockKey:1, shiftKey:1}, chars:"*"}, - nsIDOMKeyEvent.DOM_VK_ASTERISK, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "*", "Backslash", nsIDOMKeyEvent.DOM_VK_ASTERISK, "*", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_102, modifiers:{capsLockKey:1}, chars:"<"}, - nsIDOMKeyEvent.DOM_VK_LESS_THAN, "<", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "<", "IntlBackslash", nsIDOMKeyEvent.DOM_VK_LESS_THAN, "<", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_102, modifiers:{capsLockKey:1, shiftKey:1}, chars:">"}, - nsIDOMKeyEvent.DOM_VK_LESS_THAN, ">", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ">", "IntlBackslash", nsIDOMKeyEvent.DOM_VK_LESS_THAN, ">", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_COMMA, modifiers:{capsLockKey:1}, chars:"?"}, - nsIDOMKeyEvent.DOM_VK_COMMA, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "?", "KeyM", nsIDOMKeyEvent.DOM_VK_COMMA, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_COMMA, modifiers:{capsLockKey:1, shiftKey:1}, chars:","}, - nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ",", "KeyM", nsIDOMKeyEvent.DOM_VK_COMMA, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_PERIOD, modifiers:{capsLockKey:1}, chars:"."}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ".", "Comma", nsIDOMKeyEvent.DOM_VK_SEMICOLON, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_PERIOD, modifiers:{capsLockKey:1, shiftKey:1}, chars:";"}, - nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ";", "Comma", nsIDOMKeyEvent.DOM_VK_SEMICOLON, ";", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_2, modifiers:{capsLockKey:1}, chars:"/"}, - nsIDOMKeyEvent.DOM_VK_COLON, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "/", "Period", nsIDOMKeyEvent.DOM_VK_COLON, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_2, modifiers:{capsLockKey:1, shiftKey:1}, chars:":"}, - nsIDOMKeyEvent.DOM_VK_COLON, ":", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ":", "Period", nsIDOMKeyEvent.DOM_VK_COLON, ":", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_8, modifiers:{capsLockKey:1}, chars:"\u00A7"}, - nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "\u00A7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A7", "Slash", nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "\u00A7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_8, modifiers:{capsLockKey:1, shiftKey:1}, chars:"!"}, - nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "!", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "!", "Slash", nsIDOMKeyEvent.DOM_VK_EXCLAMATION, "!", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // AltGr yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_0, modifiers:{altGrKey:1}, chars:"@"}, - nsIDOMKeyEvent.DOM_VK_0, "@", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "@", "Digit0", nsIDOMKeyEvent.DOM_VK_0, "@", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_1, modifiers:{altGrKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL_BUT_NOT_CAUSE_INPUT, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "&", "Digit1", nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL_BUT_NOT_CAUSE_INPUT, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); //yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_2, // modifiers:{altGrKey:1}, chars:""}, - // nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key + // "Dead", "Digit2", nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_3, modifiers:{altGrKey:1}, chars:"#"}, - nsIDOMKeyEvent.DOM_VK_3, "#", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "#", "Digit3", nsIDOMKeyEvent.DOM_VK_3, "#", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_4, modifiers:{altGrKey:1}, chars:"{"}, - nsIDOMKeyEvent.DOM_VK_4, "{", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "{", "Digit4", nsIDOMKeyEvent.DOM_VK_4, "{", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_5, modifiers:{altGrKey:1}, chars:"["}, - nsIDOMKeyEvent.DOM_VK_5, "[", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "[", "Digit5", nsIDOMKeyEvent.DOM_VK_5, "[", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_6, modifiers:{altGrKey:1}, chars:"|"}, - nsIDOMKeyEvent.DOM_VK_6, "|", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "|", "Digit6", nsIDOMKeyEvent.DOM_VK_6, "|", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); //yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_7, // modifiers:{altGrKey:1}, chars:""}, - // nsIDOMKeyEvent.DOM_VK_7, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key + // "Dead", "Digit7", nsIDOMKeyEvent.DOM_VK_7, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_8, modifiers:{altGrKey:1}, chars:"\\"}, - nsIDOMKeyEvent.DOM_VK_8, "\\", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\\", "Digit8", nsIDOMKeyEvent.DOM_VK_8, "\\", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_9, modifiers:{altGrKey:1}, chars:"^"}, - nsIDOMKeyEvent.DOM_VK_9, "^", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "^", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "^", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_4, modifiers:{altGrKey:1}, chars:"]"}, - nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, "]", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "]", "Minus", nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, "]", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_PLUS, modifiers:{altGrKey:1}, chars:"}"}, - nsIDOMKeyEvent.DOM_VK_EQUALS, "}", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "}", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "}", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // German yield testKey({layout:KEYBOARD_LAYOUT_GERMAN, keyCode:WIN_VK_OEM_2, modifiers:{}, chars:"#"}, - nsIDOMKeyEvent.DOM_VK_HASH, "#", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "#", "Backslash", nsIDOMKeyEvent.DOM_VK_HASH, "#", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_GERMAN, keyCode:WIN_VK_OEM_2, modifiers:{shiftKey:1}, chars:"'"}, - nsIDOMKeyEvent.DOM_VK_HASH, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "'", "Backslash", nsIDOMKeyEvent.DOM_VK_HASH, "'", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Norwegian yield testKey({layout:KEYBOARD_LAYOUT_NORWEGIAN, keyCode:WIN_VK_OEM_5, modifiers:{}, chars:"|"}, - nsIDOMKeyEvent.DOM_VK_PIPE, "|", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "|", "Backquote", nsIDOMKeyEvent.DOM_VK_PIPE, "|", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_NORWEGIAN, keyCode:WIN_VK_OEM_5, modifiers:{shiftKey:1}, chars:"\u00A7"}, - nsIDOMKeyEvent.DOM_VK_PIPE, "\u00A7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "\u00A7", "Backquote", nsIDOMKeyEvent.DOM_VK_PIPE, "\u00A7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Brazilian ABNT yield testKey({layout:KEYBOARD_LAYOUT_BRAZILIAN_ABNT, keyCode:WIN_VK_ABNT_C1, modifiers:{}, chars:"/"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "/", "IntlBackslash", nsIDOMKeyEvent.DOM_VK_SLASH, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_BRAZILIAN_ABNT, keyCode:WIN_VK_ABNT_C1, modifiers:{shiftKey:1}, chars:"?"}, - nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "?", "IntlBackslash", nsIDOMKeyEvent.DOM_VK_SLASH, "?", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_BRAZILIAN_ABNT, keyCode:WIN_VK_ABNT_C2, modifiers:{numLockKey:1}, chars:"."}, - nsIDOMKeyEvent.DOM_VK_SEPARATOR, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + ".", "NumpadComma", nsIDOMKeyEvent.DOM_VK_SEPARATOR, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_BRAZILIAN_ABNT, keyCode:WIN_VK_DECIMAL, modifiers:{numLockKey:1}, chars:","}, - nsIDOMKeyEvent.DOM_VK_DECIMAL, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + ",", "NumpadDecimal", nsIDOMKeyEvent.DOM_VK_DECIMAL, ",", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); // Mac JIS keyboard // The separator key on JIS keyboard for Mac doesn't cause any character even with Japanese keyboard layout. yield testKey({layout:KEYBOARD_LAYOUT_JAPANESE, keyCode:WIN_VK_ABNT_C2, modifiers:{numLockKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_SEPARATOR, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + "", "NumpadComma", nsIDOMKeyEvent.DOM_VK_SEPARATOR, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); yield testKey({layout:KEYBOARD_LAYOUT_JAPANESE, keyCode:WIN_VK_DECIMAL, modifiers:{numLockKey:1}, chars:"."}, - nsIDOMKeyEvent.DOM_VK_DECIMAL, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); + ".", "NumpadDecimal", nsIDOMKeyEvent.DOM_VK_DECIMAL, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD); // Dead keys on any layouts yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, modifiers:{}, chars:"^^"}, - nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "^^", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["^^", "^", "^", "^"], "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "^^", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_A, modifiers:{}, chars:"\u00E2"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00E2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00E2", "\u00E2", "a"], "KeyQ", nsIDOMKeyEvent.DOM_VK_A, "\u00E2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_A, modifiers:{shiftKey:1}, chars:"\u00C2"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00C2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00C2", "\u00C2", "A"], "KeyQ", nsIDOMKeyEvent.DOM_VK_A, "\u00C2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_Q, modifiers:{}, chars:"^q"}, - nsIDOMKeyEvent.DOM_VK_Q, "^q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["^q", "^", "q", "q"], "KeyA", nsIDOMKeyEvent.DOM_VK_Q, "^q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, modifiers:{shiftKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, modifiers:{shiftKey:1}, chars:"\u00A8\u00A8"}, - nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "\u00A8\u00A8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00A8\u00A8", "\u00A8", "\u00A8", "\u00A8"], "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "\u00A8\u00A8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, modifiers:{shiftKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_A, modifiers:{shiftKey:1}, chars:"\u00C4"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00C4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00C4", "\u00C4", "A"], "KeyQ", nsIDOMKeyEvent.DOM_VK_A, "\u00C4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, modifiers:{shiftKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_A, modifiers:{}, chars:"\u00E4"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00E4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00E4", "\u00E4", "a"], "KeyQ", nsIDOMKeyEvent.DOM_VK_A, "\u00E4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6, modifiers:{shiftKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_CIRCUMFLEX, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_Q, modifiers:{shiftKey:1}, chars:"\u00A8Q"}, - nsIDOMKeyEvent.DOM_VK_Q, "\u00A8Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00A8Q", "\u00A8", "Q", "Q"], "KeyA", nsIDOMKeyEvent.DOM_VK_Q, "\u00A8Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_1, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_1, modifiers:{}, chars:"``"}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "``", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["``", "`", "`", "`"], "BracketLeft", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "``", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_1, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A, modifiers:{}, chars:"\u00E0"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00E0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00E0", "\u00E0", "a"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00E0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_1, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A, modifiers:{shiftKey:1}, chars:"\u00C0"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00C0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00C0", "\u00C0", "A"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00C0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_1, modifiers:{}, chars:""}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_Q, modifiers:{}, chars:"`q"}, - nsIDOMKeyEvent.DOM_VK_Q, "`q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["`q", "`", "q", "q"], "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "`q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_1, modifiers:{shiftKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_1, modifiers:{shiftKey:1}, chars:"^^"}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "^^", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["^^", "^", "^", "^"], "BracketLeft", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "^^", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_1, modifiers:{shiftKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A, modifiers:{shiftKey:1}, chars:"\u00C2"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00C2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00C2", "\u00C2", "A"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00C2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_1, modifiers:{shiftKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A, modifiers:{}, chars:"\u00E2"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00E2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00E2", "\u00E2", "a"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00E2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_1, modifiers:{shiftKey:1}, chars:""}, - nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_BACK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_Q, modifiers:{shiftKey:1}, chars:"^Q"}, - nsIDOMKeyEvent.DOM_VK_Q, "^Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["^Q", "^", "Q", "Q"], "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "^Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7, modifiers:{}, chars:""}, - 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7, modifiers:{}, chars:"\u00B4\u00B4"}, - 0, "\u00B4\u00B4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00B4\u00B4", "\u00B4", "\u00B4", "\u00B4"], "Quote", 0, "\u00B4\u00B4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7, modifiers:{}, chars:""}, - 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A, modifiers:{}, chars:"\u00E1"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00E1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00E1", "\u00E1", "a"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00E1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7, modifiers:{}, chars:""}, - 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A, modifiers:{shiftKey:1}, chars:"\u00C1"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00C1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00C1", "\u00C1", "A"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00C1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7, modifiers:{}, chars:""}, - 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_Q, modifiers:{}, chars:"\u00B4q"}, - nsIDOMKeyEvent.DOM_VK_Q, "\u00B4q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00B4q", "\u00B4", "q", "q"], "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "\u00B4q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7, modifiers:{shiftKey:1}, chars:""}, - 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7, modifiers:{shiftKey:1}, chars:"\u00A8\u00A8"}, - 0, "\u00A8\u00A8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00A8\u00A8", "\u00A8", "\u00A8", "\u00A8"], "Quote", 0, "\u00A8\u00A8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7, modifiers:{shiftKey:1}, chars:""}, - 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A, modifiers:{shiftKey:1}, chars:"\u00C4"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00C4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00C4", "\u00C4", "A"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00C4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7, modifiers:{shiftKey:1}, chars:""}, - 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A, modifiers:{}, chars:"\u00E4"}, - nsIDOMKeyEvent.DOM_VK_A, "\u00E4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00E4", "\u00E4", "a"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00E4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7, modifiers:{shiftKey:1}, chars:""}, - 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_Q, modifiers:{shiftKey:1}, chars:"\u00A8Q"}, - nsIDOMKeyEvent.DOM_VK_Q, "\u00A8Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + ["\u00A8Q", "\u00A8", "Q", "Q"], "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "\u00A8Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); + cleanup(); } - document.removeEventListener("keydown", onKeyEvent, false); - document.removeEventListener("keypress", onKeyEvent, false); - document.removeEventListener("keyup", onKeyEvent, false); - SpecialPowers.removeSystemEventListener(document, "keypress", consumer, true); + + if (IS_WIN) { + yield* testKeysOnWindows(); + } else if (IS_MAC) { + yield* testKeysOnMac(); + } else { + cleanup(); + } } // Test the activation (or not) of an HTML accesskey diff --git a/widget/windows/KeyboardLayout.cpp b/widget/windows/KeyboardLayout.cpp index e39709b0b675..bdb8b532980b 100644 --- a/widget/windows/KeyboardLayout.cpp +++ b/widget/windows/KeyboardLayout.cpp @@ -849,6 +849,7 @@ NativeKey::NativeKey(nsWindowBase* aWidget, : mWidget(aWidget) , mDispatcher(aWidget->GetTextEventDispatcher()) , mMsg(aMessage) + , mFocusedWndBeforeDispatch(::GetFocus()) , mDOMKeyCode(0) , mKeyNameIndex(KEY_NAME_INDEX_Unidentified) , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN) @@ -860,7 +861,6 @@ NativeKey::NativeKey(nsWindowBase* aWidget, , mScanCode(0) , mIsExtended(false) , mIsDeadKey(false) - , mIsFollowedByNonControlCharMessage(false) , mFakeCharMsgs(aFakeCharMsgs && aFakeCharMsgs->Length() ? aFakeCharMsgs : nullptr) { @@ -886,10 +886,23 @@ NativeKey::NativeKey(nsWindowBase* aWidget, mIsExtended = WinUtils::IsExtendedScanCode(mMsg.lParam); switch (mMsg.message) { case WM_KEYDOWN: - case WM_SYSKEYDOWN: - case MOZ_WM_KEYDOWN: + case WM_SYSKEYDOWN: { + // If next message is WM_*CHAR message, let's consume it now. + MSG charMsg; + while (GetFollowingCharMessage(charMsg)) { + // Although, got message shouldn't be WM_NULL in desktop apps, + // we should keep checking this. FYI: This was added for Metrofox. + if (charMsg.message == WM_NULL) { + continue; + } + NS_WARN_IF(charMsg.hwnd != mMsg.hwnd); + mFollowingCharMsgs.AppendElement(charMsg); + } + MOZ_FALLTHROUGH; + } case WM_KEYUP: case WM_SYSKEYUP: + case MOZ_WM_KEYDOWN: case MOZ_WM_KEYUP: { // First, resolve the IME converted virtual keycode to its original // keycode. @@ -966,18 +979,21 @@ NativeKey::NativeKey(nsWindowBase* aWidget, // Therefore, we never get VK_RCONTRL and VK_RMENU for the result of // MapVirtualKeyEx() on WinXP or WinServer2003. // - // If VK_CONTROL or VK_MENU key message is caused by an extended key, - // we should assume that the right key of them is pressed. + // If VK_SHIFT, VK_CONTROL or VK_MENU key message is caused by well + // known scan code, we should decide it as Right key. Otherwise, + // decide it as Left key. switch (mOriginalVirtualKeyCode) { case VK_CONTROL: - mVirtualKeyCode = VK_RCONTROL; + mVirtualKeyCode = + mIsExtended && mScanCode == 0x1D ? VK_RCONTROL : VK_LCONTROL; break; case VK_MENU: - mVirtualKeyCode = VK_RMENU; + mVirtualKeyCode = + mIsExtended && mScanCode == 0x38 ? VK_RMENU : VK_LMENU; break; case VK_SHIFT: - // Neither left shift nor right shift is not an extended key, - // let's use VK_LSHIFT for invalid scan code. + // Neither left shift nor right shift is an extended key, + // let's use VK_LSHIFT for unknown mapping. mVirtualKeyCode = VK_LSHIFT; break; default: @@ -1009,8 +1025,8 @@ NativeKey::NativeKey(nsWindowBase* aWidget, break; case VK_SHIFT: if (mVirtualKeyCode != VK_LSHIFT && mVirtualKeyCode != VK_RSHIFT) { - // Neither left shift nor right shift is not an extended key, - // let's use VK_LSHIFT for invalid scan code. + // Neither left shift nor right shift is an extended key, + // let's use VK_LSHIFT for unknown mapping. mVirtualKeyCode = VK_LSHIFT; } break; @@ -1047,9 +1063,9 @@ NativeKey::NativeKey(nsWindowBase* aWidget, keyboardLayout->ConvertNativeKeyCodeToDOMKeyCode(mOriginalVirtualKeyCode); // Be aware, keyboard utilities can change non-printable keys to printable // keys. In such case, we should make the key value as a printable key. - mIsFollowedByNonControlCharMessage = - IsKeyDownMessage() && IsFollowedByNonControlCharMessage(); - mKeyNameIndex = mIsFollowedByNonControlCharMessage ? + // FYI: IsFollowedByNonControlCharMessage() returns true only when it's + // handling a keydown message. + mKeyNameIndex = IsFollowedByNonControlCharMessage() ? KEY_NAME_INDEX_USE_STRING : keyboardLayout->ConvertNativeKeyCodeToKeyNameIndex(mOriginalVirtualKeyCode); mCodeNameIndex = @@ -1074,8 +1090,8 @@ NativeKey::NativeKey(nsWindowBase* aWidget, ComputeInputtingStringWithKeyboardLayout(); } else { // This message might be sent by SendInput() API to input a Unicode - // character, in such case, we can only know what char will be inputted - // with following WM_CHAR message. + // character, in such case, we can only know what chars will be inputted + // with following WM_CHAR messages. // TODO: We cannot initialize mCommittedCharsAndModifiers for VK_PACKET // if the message is WM_KEYUP because we don't have preceding // WM_CHAR message. Therefore, we should dispatch eKeyUp event at @@ -1086,15 +1102,18 @@ NativeKey::NativeKey(nsWindowBase* aWidget, // keypress event's default is prevented. I guess, we should store // key message information globally and we should wait following // WM_KEYDOWN if following WM_CHAR is a part of a Unicode character. - MSG followingCharMsg; - if (GetFollowingCharMessage(followingCharMsg, false) && - !IsControlChar(static_cast(followingCharMsg.wParam))) { - mCommittedCharsAndModifiers.Clear(); - mCommittedCharsAndModifiers.Append( - static_cast(followingCharMsg.wParam), - mModKeyState.GetModifiers()); + mCommittedCharsAndModifiers.Clear(); + for (size_t i = 0; i < mFollowingCharMsgs.Length(); ++i) { + char16_t ch = static_cast(mFollowingCharMsgs[i].wParam); + // Skip control characters. + if (IsControlChar(ch)) { + continue; + } + mCommittedCharsAndModifiers.Append(ch, mModKeyState.GetModifiers()); } } + // Remove odd char messages if there are. + RemoveFollowingOddCharMessages(); } } @@ -1214,36 +1233,20 @@ NativeKey::IsControlChar(char16_t aChar) bool NativeKey::IsFollowedByDeadCharMessage() const { - MSG nextMsg; - if (mFakeCharMsgs) { - nextMsg = mFakeCharMsgs->ElementAt(0).GetCharMsg(mMsg.hwnd); - } else if (IsKeyMessageOnPlugin()) { + if (mFollowingCharMsgs.IsEmpty()) { return false; - } else { - if (!WinUtils::PeekMessage(&nextMsg, mMsg.hwnd, WM_KEYFIRST, WM_KEYLAST, - PM_NOREMOVE | PM_NOYIELD)) { - return false; - } } - return IsDeadCharMessage(nextMsg); + return IsDeadCharMessage(mFollowingCharMsgs[0]); } bool NativeKey::IsFollowedByNonControlCharMessage() const { - MSG nextMsg; - if (mFakeCharMsgs) { - nextMsg = mFakeCharMsgs->ElementAt(0).GetCharMsg(mMsg.hwnd); - } else if (IsKeyMessageOnPlugin()) { + if (mFollowingCharMsgs.IsEmpty()) { return false; - } else { - if (!WinUtils::PeekMessage(&nextMsg, mMsg.hwnd, WM_KEYFIRST, WM_KEYLAST, - PM_NOREMOVE | PM_NOYIELD)) { - return false; - } } - return nextMsg.message == WM_CHAR && - !IsControlChar(static_cast(nextMsg.wParam)); + return mFollowingCharMsgs[0].message == WM_CHAR && + !IsControlChar(static_cast(mFollowingCharMsgs[0].wParam)); } bool @@ -1280,15 +1283,51 @@ NativeKey::IsIMEDoingKakuteiUndo() const compositionMsg.time <= charMsg.time; } +void +NativeKey::RemoveFollowingOddCharMessages() +{ + MOZ_ASSERT(IsKeyDownMessage()); + + // If the keydown message is synthesized for automated tests, there is + // nothing to do here. + if (mFakeCharMsgs) { + return; + } + + // If there are some following char messages before another key message, + // there is nothing to do here. + if (!mFollowingCharMsgs.IsEmpty()) { + return; + } + + // If the handling key isn't Backspace, there is nothing to do here. + if (mOriginalVirtualKeyCode != VK_BACK) { + return; + } + + // If we don't see the odd message pattern, there is nothing to do here. + if (!IsIMEDoingKakuteiUndo()) { + return; + } + + // Otherwise, we need to remove odd WM_CHAR messages for ATOK or WXG (both + // of them are Japanese IME). + MSG msg; + while (WinUtils::PeekMessage(&msg, mMsg.hwnd, WM_CHAR, WM_CHAR, + PM_REMOVE | PM_NOYIELD)) { + if (msg.message != WM_CHAR) { + MOZ_RELEASE_ASSERT(msg.message == WM_NULL, + "Unexpected message was removed"); + continue; + } + mRemovedOddCharMsgs.AppendElement(msg); + } +} + UINT NativeKey::GetScanCodeWithExtendedFlag() const { - // MapVirtualKeyEx() has been improved for supporting extended keys since - // Vista. When we call it for mapping a scancode of an extended key and - // a virtual keycode, we need to add 0xE000 to the scancode. - // On Win XP and Win Server 2003, this doesn't support. On them, we have - // no way to get virtual keycodes from scancode of extended keys. - if (!mIsExtended || !IsVistaOrLater()) { + if (!mIsExtended) { return mScanCode; } return (0xE000 | mScanCode); @@ -1382,6 +1421,12 @@ NativeKey::ComputeVirtualKeyCodeFromScanCode() const uint8_t NativeKey::ComputeVirtualKeyCodeFromScanCodeEx() const { + // MapVirtualKeyEx() has been improved for supporting extended keys since + // Vista. When we call it for mapping a scancode of an extended key and + // a virtual keycode, we need to add 0xE000 to the scancode. + // On the other hand, neither WinXP nor WinServer2003 doesn't support 0xE000. + // Therefore, we have no way to get virtual keycode from scan code of + // extended keys. if (NS_WARN_IF(!CanComputeVirtualKeyCodeFromScanCode())) { return 0; } @@ -1747,7 +1792,7 @@ NativeKey::HandleKeyDownMessage(bool* aEventDispatched) const return defaultPrevented; } - if (mWidget->Destroyed()) { + if (mWidget->Destroyed() || IsFocusedWindowChanged()) { return true; } @@ -1802,27 +1847,28 @@ NativeKey::HandleKeyDownMessage(bool* aEventDispatched) const } if (defaultPrevented) { - DispatchPluginEventsAndDiscardsCharMessages(); + MaybeDispatchPluginEventsForRemovedCharMessages(); return true; } // If we won't be getting a WM_CHAR, WM_SYSCHAR or WM_DEADCHAR, synthesize a // keypress for almost all keys if (NeedsToHandleWithoutFollowingCharMessages()) { - return (DispatchPluginEventsAndDiscardsCharMessages() || + return (MaybeDispatchPluginEventsForRemovedCharMessages() || DispatchKeyPressEventsWithoutCharMessage()); } - MSG followingCharMsg; - if (GetFollowingCharMessage(followingCharMsg)) { - // Even if there was char message, it might be redirected by different - // window (perhaps, focus move?). Then, we shouldn't continue to handle - // the message since no input should occur on the window. - if (followingCharMsg.message == WM_NULL || - followingCharMsg.hwnd != mMsg.hwnd) { - return false; + if (!mFollowingCharMsgs.IsEmpty()) { + bool consumed = false; + for (size_t i = 0; i < mFollowingCharMsgs.Length(); ++i) { + consumed = + DispatchKeyPressEventForFollowingCharMessage(mFollowingCharMsgs[i]) || + consumed; + if (mWidget->Destroyed() || IsFocusedWindowChanged()) { + return true; + } } - return DispatchKeyPressEventForFollowingCharMessage(followingCharMsg); + return consumed; } // If WM_KEYDOWN of VK_PACKET isn't followed by WM_CHAR, we don't need to @@ -2038,7 +2084,7 @@ NativeKey::NeedsToHandleWithoutFollowingCharMessages() const // If keydown message is followed by WM_CHAR whose wParam isn't a control // character, we should dispatch keypress event with the char message // even with any modifier state. - if (mIsFollowedByNonControlCharMessage) { + if (IsFollowedByNonControlCharMessage()) { return false; } @@ -2130,7 +2176,7 @@ NativeKey::MayBeSameCharMessage(const MSG& aCharMsg1, } bool -NativeKey::GetFollowingCharMessage(MSG& aCharMsg, bool aRemove) const +NativeKey::GetFollowingCharMessage(MSG& aCharMsg) const { MOZ_ASSERT(IsKeyDownMessage()); MOZ_ASSERT(!IsKeyMessageOnPlugin()); @@ -2144,7 +2190,7 @@ NativeKey::GetFollowingCharMessage(MSG& aCharMsg, bool aRemove) const continue; } MSG charMsg = fakeCharMsg.GetCharMsg(mMsg.hwnd); - fakeCharMsg.mConsumed = aRemove; + fakeCharMsg.mConsumed = true; if (!IsCharMessage(charMsg)) { return false; } @@ -2166,11 +2212,6 @@ NativeKey::GetFollowingCharMessage(MSG& aCharMsg, bool aRemove) const return false; } - if (!aRemove) { - aCharMsg = nextKeyMsg; - return true; - } - // On Metrofox, PeekMessage() sometimes returns WM_NULL even if we specify // the message range. So, if it returns WM_NULL, we should retry to get // the following char message it was found above. @@ -2346,51 +2387,33 @@ NativeKey::GetFollowingCharMessage(MSG& aCharMsg, bool aRemove) const } bool -NativeKey::DispatchPluginEventsAndDiscardsCharMessages() const +NativeKey::MaybeDispatchPluginEventsForRemovedCharMessages() const { MOZ_ASSERT(IsKeyDownMessage()); MOZ_ASSERT(!IsKeyMessageOnPlugin()); - // Remove a possible WM_CHAR or WM_SYSCHAR messages from the message queue. - // They can be more than one because of: - // * Dead-keys not pairing with base character - // * Some keyboard layouts may map up to 4 characters to the single key - bool anyCharMessagesRemoved = false; - MSG msg; - while (GetFollowingCharMessage(msg)) { - if (msg.message == WM_NULL) { - continue; - } - anyCharMessagesRemoved = true; - // If the window handle is changed, focused window must be changed. - // So, plugin shouldn't handle it anymore. - if (msg.hwnd != mMsg.hwnd) { - break; - } + for (size_t i = 0; + i < mFollowingCharMsgs.Length() && mWidget->ShouldDispatchPluginEvent(); + ++i) { MOZ_RELEASE_ASSERT(!mWidget->Destroyed(), "NativeKey tries to dispatch a plugin event on destroyed widget"); - mWidget->DispatchPluginEvent(msg); - if (mWidget->Destroyed()) { + mWidget->DispatchPluginEvent(mFollowingCharMsgs[i]); + if (mWidget->Destroyed() || IsFocusedWindowChanged()) { return true; } } - if (!mFakeCharMsgs && !anyCharMessagesRemoved && - mDOMKeyCode == NS_VK_BACK && IsIMEDoingKakuteiUndo()) { - // This is for a hack for ATOK and WXG. So, PeekMessage() must scceed! - while (WinUtils::PeekMessage(&msg, mMsg.hwnd, WM_CHAR, WM_CHAR, - PM_REMOVE | PM_NOYIELD)) { - if (msg.message != WM_CHAR) { - MOZ_RELEASE_ASSERT(msg.message == WM_NULL, - "Unexpected message was removed"); - continue; - } - MOZ_RELEASE_ASSERT(!mWidget->Destroyed(), - "NativeKey tries to dispatch a plugin event on destroyed widget"); - mWidget->DispatchPluginEvent(msg); - return mWidget->Destroyed(); + // Dispatch odd char messages which are caused by ATOK or WXG (both of them + // are Japanese IME) and removed by RemoveFollowingOddCharMessages(). + for (size_t i = 0; + i < mRemovedOddCharMsgs.Length() && mWidget->ShouldDispatchPluginEvent(); + ++i) { + MOZ_RELEASE_ASSERT(!mWidget->Destroyed(), + "NativeKey tries to dispatch a plugin event on destroyed widget"); + mWidget->DispatchPluginEvent(mRemovedOddCharMsgs[i]); + if (mWidget->Destroyed() || IsFocusedWindowChanged()) { + return true; } - MOZ_CRASH("NativeKey failed to get WM_CHAR for ATOK or WXG"); } return false; @@ -3728,20 +3751,20 @@ KeyboardLayout::SynthesizeNativeKeyEvent(nsWindowBase* aWidget, OverrideLayout(loadedLayout); uint8_t argumentKeySpecific = 0; - switch (aNativeKeyCode) { + switch (aNativeKeyCode & 0xFF) { case VK_SHIFT: aModifierFlags &= ~(nsIWidget::SHIFT_L | nsIWidget::SHIFT_R); argumentKeySpecific = VK_LSHIFT; break; case VK_LSHIFT: aModifierFlags &= ~nsIWidget::SHIFT_L; - argumentKeySpecific = aNativeKeyCode; - aNativeKeyCode = VK_SHIFT; + argumentKeySpecific = aNativeKeyCode & 0xFF; + aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_SHIFT; break; case VK_RSHIFT: aModifierFlags &= ~nsIWidget::SHIFT_R; - argumentKeySpecific = aNativeKeyCode; - aNativeKeyCode = VK_SHIFT; + argumentKeySpecific = aNativeKeyCode & 0xFF; + aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_SHIFT; break; case VK_CONTROL: aModifierFlags &= ~(nsIWidget::CTRL_L | nsIWidget::CTRL_R); @@ -3749,13 +3772,13 @@ KeyboardLayout::SynthesizeNativeKeyEvent(nsWindowBase* aWidget, break; case VK_LCONTROL: aModifierFlags &= ~nsIWidget::CTRL_L; - argumentKeySpecific = aNativeKeyCode; - aNativeKeyCode = VK_CONTROL; + argumentKeySpecific = aNativeKeyCode & 0xFF; + aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_CONTROL; break; case VK_RCONTROL: aModifierFlags &= ~nsIWidget::CTRL_R; - argumentKeySpecific = aNativeKeyCode; - aNativeKeyCode = VK_CONTROL; + argumentKeySpecific = aNativeKeyCode & 0xFF; + aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_CONTROL; break; case VK_MENU: aModifierFlags &= ~(nsIWidget::ALT_L | nsIWidget::ALT_R); @@ -3763,13 +3786,13 @@ KeyboardLayout::SynthesizeNativeKeyEvent(nsWindowBase* aWidget, break; case VK_LMENU: aModifierFlags &= ~nsIWidget::ALT_L; - argumentKeySpecific = aNativeKeyCode; - aNativeKeyCode = VK_MENU; + argumentKeySpecific = aNativeKeyCode & 0xFF; + aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_MENU; break; case VK_RMENU: aModifierFlags &= ~nsIWidget::ALT_R; - argumentKeySpecific = aNativeKeyCode; - aNativeKeyCode = VK_MENU; + argumentKeySpecific = aNativeKeyCode & 0xFF; + aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_MENU; break; case VK_CAPITAL: aModifierFlags &= ~nsIWidget::CAPS_LOCK; @@ -3783,8 +3806,6 @@ KeyboardLayout::SynthesizeNativeKeyEvent(nsWindowBase* aWidget, AutoTArray keySequence; WinUtils::SetupKeyModifiersSequence(&keySequence, aModifierFlags); - NS_ASSERTION(aNativeKeyCode >= 0 && aNativeKeyCode < 256, - "Native VK key code out of range"); keySequence.AppendElement(KeyPair(aNativeKeyCode, argumentKeySpecific)); // Simulate the pressing of each modifier key and then the real key @@ -3793,18 +3814,22 @@ KeyboardLayout::SynthesizeNativeKeyEvent(nsWindowBase* aWidget, for (uint32_t i = 0; i < keySequence.Length(); ++i) { uint8_t key = keySequence[i].mGeneral; uint8_t keySpecific = keySequence[i].mSpecific; + uint16_t scanCode = keySequence[i].mScanCode; kbdState[key] = 0x81; // key is down and toggled on if appropriate if (keySpecific) { kbdState[keySpecific] = 0x81; } ::SetKeyboardState(kbdState); ModifierKeyState modKeyState; - UINT scanCode = - ComputeScanCodeForVirtualKeyCode(keySpecific ? keySpecific : key); + // If scan code isn't specified explicitly, let's compute it with current + // keyboard layout. + if (!scanCode) { + scanCode = + ComputeScanCodeForVirtualKeyCode(keySpecific ? keySpecific : key); + } LPARAM lParam = static_cast(scanCode << 16); - // Add extended key flag to the lParam for right control key and right alt - // key. - if (keySpecific == VK_RCONTROL || keySpecific == VK_RMENU) { + // If the scan code is for an extended key, set extended key flag. + if ((scanCode & 0xFF00) == 0xE000) { lParam |= 0x1000000; } bool makeSysKeyMsg = IsSysKey(key, modKeyState); @@ -3856,18 +3881,22 @@ KeyboardLayout::SynthesizeNativeKeyEvent(nsWindowBase* aWidget, for (uint32_t i = keySequence.Length(); i > 0; --i) { uint8_t key = keySequence[i - 1].mGeneral; uint8_t keySpecific = keySequence[i - 1].mSpecific; + uint16_t scanCode = keySequence[i - 1].mScanCode; kbdState[key] = 0; // key is up and toggled off if appropriate if (keySpecific) { kbdState[keySpecific] = 0; } ::SetKeyboardState(kbdState); ModifierKeyState modKeyState; - UINT scanCode = - ComputeScanCodeForVirtualKeyCode(keySpecific ? keySpecific : key); + // If scan code isn't specified explicitly, let's compute it with current + // keyboard layout. + if (!scanCode) { + scanCode = + ComputeScanCodeForVirtualKeyCode(keySpecific ? keySpecific : key); + } LPARAM lParam = static_cast(scanCode << 16); - // Add extended key flag to the lParam for right control key and right alt - // key. - if (keySpecific == VK_RCONTROL || keySpecific == VK_RMENU) { + // If the scan code is for an extended key, set extended key flag. + if ((scanCode & 0xFF00) == 0xE000) { lParam |= 0x1000000; } // Don't use WM_SYSKEYUP for Alt keyup. diff --git a/widget/windows/KeyboardLayout.h b/widget/windows/KeyboardLayout.h index 2d3e7b01ac85..a27319aa8b49 100644 --- a/widget/windows/KeyboardLayout.h +++ b/widget/windows/KeyboardLayout.h @@ -263,6 +263,18 @@ private: RefPtr mDispatcher; HKL mKeyboardLayout; MSG mMsg; + // mFollowingCharMsgs stores WM_CHAR, WM_SYSCHAR, WM_DEADCHAR or + // WM_SYSDEADCHAR message which follows WM_KEYDOWN. + // Note that the stored messaged are already removed from the queue. + nsTArray mFollowingCharMsgs; + // mRemovedOddCharMsgs stores WM_CHAR messages which are caused by ATOK or + // WXG (they are Japanese IME) when the user tries to do "Kakutei-undo" + // (it means "undo the last commit"). + nsTArray mRemovedOddCharMsgs; + // If dispatching eKeyDown or eKeyPress event causes focus change, + // the instance shouldn't handle remaning char messages. For checking it, + // this should store first focused window. + HWND mFocusedWndBeforeDispatch; uint32_t mDOMKeyCode; KeyNameIndex mKeyNameIndex; @@ -313,10 +325,6 @@ private: // mIsOverridingKeyboardLayout is true if the instance temporarily overriding // keyboard layout with specified by the constructor. bool mIsOverridingKeyboardLayout; - // mIsFollowedByNonControlCharMessage may be true when mMsg is a keydown - // message. When the keydown message is followed by a char message, this - // is true. - bool mIsFollowedByNonControlCharMessage; nsTArray* mFakeCharMsgs; @@ -372,6 +380,12 @@ private: // The result is one of nsIDOMKeyEvent::DOM_KEY_LOCATION_*. uint32_t GetKeyLocation() const; + /** + * RemoveFollowingOddCharMessages() removes odd WM_CHAR messages from the + * queue when IsIMEDoingKakuteiUndo() returns true. + */ + void RemoveFollowingOddCharMessages(); + /** * "Kakutei-Undo" of ATOK or WXG (both of them are Japanese IME) causes * strange WM_KEYDOWN/WM_KEYUP/WM_CHAR message pattern. So, when this @@ -439,11 +453,8 @@ private: * * WARNING: Even if this returns true, aCharMsg may be WM_NULL or its * hwnd may be different window. - * - * @param aRemove true if the found message should be removed from the - * queue. Otherwise, false. */ - bool GetFollowingCharMessage(MSG& aCharMsg, bool aRemove = true) const; + bool GetFollowingCharMessage(MSG& aCharMsg) const; /** * Whether the key event can compute virtual keycode from the scancode value. @@ -493,12 +504,12 @@ private: bool DispatchKeyPressEventsWithoutCharMessage() const; /** - * Remove all following WM_CHAR, WM_SYSCHAR and WM_DEADCHAR messages for the - * WM_KEYDOWN or WM_SYSKEYDOWN message. Additionally, dispatches plugin - * events if it's necessary. - * Returns true if the widget is destroyed. Otherwise, false. + * MaybeDispatchPluginEventsForRemovedCharMessages() dispatches plugin events + * for removed char messages when a windowless plugin has focus. + * Returns true if the widget is destroyed or blurred during dispatching a + * plugin event. */ - bool DispatchPluginEventsAndDiscardsCharMessages() const; + bool MaybeDispatchPluginEventsForRemovedCharMessages() const; /** * DispatchKeyPressEventForFollowingCharMessage() dispatches keypress event @@ -522,6 +533,15 @@ private: * state. */ void ComputeInputtingStringWithKeyboardLayout(); + + /** + * IsFocusedWindowChanged() returns true if focused window is changed + * after the instance is created. + */ + bool IsFocusedWindowChanged() const + { + return mFocusedWndBeforeDispatch != ::GetFocus(); + } }; class KeyboardLayout diff --git a/widget/windows/nsWindowBase.cpp b/widget/windows/nsWindowBase.cpp index da4c6c2c2edb..4c2edac6e527 100644 --- a/widget/windows/nsWindowBase.cpp +++ b/widget/windows/nsWindowBase.cpp @@ -21,7 +21,7 @@ InjectTouchInputPtr nsWindowBase::sInjectTouchFuncPtr; bool nsWindowBase::DispatchPluginEvent(const MSG& aMsg) { - if (!PluginHasFocus()) { + if (!ShouldDispatchPluginEvent()) { return false; } WidgetPluginEvent pluginEvent(true, ePluginInputEvent, this); @@ -36,6 +36,12 @@ nsWindowBase::DispatchPluginEvent(const MSG& aMsg) return DispatchWindowEvent(&pluginEvent); } +bool +nsWindowBase::ShouldDispatchPluginEvent() +{ + return PluginHasFocus(); +} + // static bool nsWindowBase::InitTouchInjection() diff --git a/widget/windows/nsWindowBase.h b/widget/windows/nsWindowBase.h index 46b237f4a1a5..405f5b359ea2 100644 --- a/widget/windows/nsWindowBase.h +++ b/widget/windows/nsWindowBase.h @@ -85,6 +85,11 @@ public: */ virtual bool DispatchPluginEvent(const MSG& aMsg); + /* + * Returns true if this should dispatch a plugin event. + */ + bool ShouldDispatchPluginEvent(); + /* * Touch input injection apis */ diff --git a/widget/windows/nsWindowDefs.h b/widget/windows/nsWindowDefs.h index 4e7529cd63b2..48a9356d28de 100644 --- a/widget/windows/nsWindowDefs.h +++ b/widget/windows/nsWindowDefs.h @@ -84,11 +84,17 @@ const wchar_t kClassNameTransition[] = L"MozillaTransitionWindowClass"; **************************************************************/ // Used for synthesizing events -struct KeyPair { +struct KeyPair +{ uint8_t mGeneral; uint8_t mSpecific; + uint16_t mScanCode; KeyPair(uint32_t aGeneral, uint32_t aSpecific) - : mGeneral(uint8_t(aGeneral)), mSpecific(uint8_t(aSpecific)) {} + : mGeneral(aGeneral & 0xFF) + , mSpecific(aSpecific & 0xFF) + , mScanCode((aGeneral & 0xFFFF0000) >> 16) + { + } }; #if (WINVER < 0x0600)