+ * Returns true if there's a known native key handler for the given
+ * event in the given mode.
+ *
+ * @param {Event} event A keypress event.
+ * @param {Modes.Mode} mode The main mode.
+ * @param {boolean} passUnknown Whether unknown keys should be passed.
+ */
+ hasNativeKey: function hasNativeKey(event, mode, passUnknown) {
+ if (mode.input && event.charCode && !(event.ctrlKey || event.metaKey))
+ return true;
+
+ if (!passUnknown)
+ return false;
+
+ var elements = document.getElementsByTagNameNS(XUL, "key");
+ var filters = [];
+
+ if (event.keyCode)
+ filters.push(["keycode", this._code_nativeKey[event.keyCode]]);
+ if (event.charCode) {
+ let key = String.fromCharCode(event.charCode);
+ filters.push(["key", key.toUpperCase()],
+ ["key", key.toLowerCase()]);
+ }
+
+ let accel = util.OS.isMacOSX ? "metaKey" : "ctrlKey";
+
+ let access = iter({ 1: "shiftKey", 2: "ctrlKey", 4: "altKey", 8: "metaKey" })
+ .filter(function ([k, v]) this & k, prefs.get("ui.key.chromeAccess"))
+ .map(function ([k, v]) [v, true])
+ .toObject();
+
+ outer:
+ for (let [, key] in iter(elements))
+ if (filters.some(function ([k, v]) key.getAttribute(k) == v)) {
+ let keys = { ctrlKey: false, altKey: false, shiftKey: false, metaKey: false };
+ let needed = { ctrlKey: event.ctrlKey, altKey: event.altKey, shiftKey: event.shiftKey, metaKey: event.metaKey };
+
+ let modifiers = (key.getAttribute("modifiers") || "").trim().split(/[\s,]+/);
+ for (let modifier in values(modifiers))
+ switch (modifier) {
+ case "access": update(keys, access); break;
+ case "accel": keys[accel] = true; break;
+ default: keys[modifier + "Key"] = true; break;
+ case "any":
+ if (!iter.some(keys, function ([k, v]) v && needed[k]))
+ continue outer;
+ for (let [k, v] in iter(keys)) {
+ if (v)
+ needed[k] = false;
+ keys[k] = false;
+ }
+ break;
+ }
+
+ if (iter(needed).every(function ([k, v]) v == keys[k]))
+ return key;
+ }
+
+ return false;
+ },
+
+ /**
+ * Returns true if *key* is a key code defined to accept/execute input on
+ * the command line.