summaryrefslogtreecommitdiff
path: root/common/content/events.js
diff options
context:
space:
mode:
Diffstat (limited to 'common/content/events.js')
-rw-r--r--common/content/events.js349
1 files changed, 21 insertions, 328 deletions
diff --git a/common/content/events.js b/common/content/events.js
index 2693b9a9..b2a2ab6d 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -115,67 +115,6 @@ var Events = Module("events", {
if (isString(m))
m = { keys: m, timeRecorded: Date.now() };
- // NOTE: the order of ["Esc", "Escape"] or ["Escape", "Esc"]
- // matters, so use that string as the first item, that you
- // want to refer to within dactyl's source code for
- // comparisons like if (key == "<Esc>") { ... }
- this._keyTable = {
- add: ["Plus", "Add"],
- back_space: ["BS"],
- count: ["count"],
- delete: ["Del"],
- escape: ["Esc", "Escape"],
- insert: ["Insert", "Ins"],
- leader: ["Leader"],
- left_shift: ["LT", "<"],
- nop: ["Nop"],
- pass: ["Pass"],
- return: ["Return", "CR", "Enter"],
- right_shift: [">"],
- space: ["Space", " "],
- subtract: ["Minus", "Subtract"]
- };
-
- this._pseudoKeys = Set(["count", "leader", "nop", "pass"]);
-
- this._key_key = {};
- this._code_key = {};
- this._key_code = {};
- this._code_nativeKey = {};
-
- for (let list in values(this._keyTable))
- for (let v in values(list)) {
- if (v.length == 1)
- v = v.toLowerCase();
- this._key_key[v.toLowerCase()] = v;
- }
-
- for (let [k, v] in Iterator(KeyEvent)) {
- this._code_nativeKey[v] = k.substr(4);
-
- k = k.substr(7).toLowerCase();
- let names = [k.replace(/(^|_)(.)/g, function (m, n1, n2) n2.toUpperCase())
- .replace(/^NUMPAD/, "k")];
-
- if (names[0].length == 1)
- names[0] = names[0].toLowerCase();
-
- if (k in this._keyTable)
- names = this._keyTable[k];
- this._code_key[v] = names[0];
- for (let [, name] in Iterator(names)) {
- this._key_key[name.toLowerCase()] = name;
- this._key_code[name.toLowerCase()] = v;
- }
- }
-
- // HACK: as Gecko does not include an event for <, we must add this in manually.
- if (!("<" in this._key_code)) {
- this._key_code["<"] = 60;
- this._key_code["lt"] = 60;
- this._code_key[60] = "lt";
- }
-
this.popups = {
active: [],
@@ -298,8 +237,8 @@ var Events = Module("events", {
if (/[A-Z]/.test(macro)) { // uppercase (append)
macro = macro.toLowerCase();
- this._macroKeys = events.fromString((this._macros.get(macro) || { keys: "" }).keys, true)
- .map(events.closure.toString);
+ this._macroKeys = DOM.Event.stringify((this._macros.get(macro) || { keys: "" }).keys, true)
+ .map(DOM.Event.closure.stringify);
}
else if (macro) {
this._macroKeys = [];
@@ -421,9 +360,9 @@ var Events = Module("events", {
keys = mappings.expandLeader(keys);
- for (let [, evt_obj] in Iterator(events.fromString(keys))) {
+ for (let [, evt_obj] in Iterator(DOM.Event.parse(keys))) {
let now = Date.now();
- let key = events.toString(evt_obj);
+ let key = DOM.Event.stringify(evt_obj);
for (let type in values(["keydown", "keypress", "keyup"])) {
let evt = update({}, evt_obj, { type: type });
if (type !== "keypress" && !evt.keyCode)
@@ -472,268 +411,22 @@ var Events = Module("events", {
return true;
},
- create: deprecated("DOM.Event", function create() DOM.Event.apply(null, arguments)),
- dispatch: deprecated("DOM.Event.dispatch", function dispatch() DOM.Event.dispatch.apply(DOM.Event, arguments)),
+ canonicalKeys: deprecated("DOM.Event.canonicalKeys", { get: function canonicalKeys() DOM.Event.closure.canonicalKeys }),
+ create: deprecated("DOM.Event", function create() DOM.Event.apply(null, arguments)),
+ dispatch: deprecated("DOM.Event.dispatch", function dispatch() DOM.Event.dispatch.apply(DOM.Event, arguments)),
+ fromString: deprecated("DOM.Event.parse", { get: function fromString() DOM.Event.closure.parse }),
+ iterKeys: deprecated("DOM.Event.iterKeys", { get: function iterKeys() DOM.Event.closure.iterKeys }),
- /**
- * Converts a user-input string of keys into a canonical
- * representation.
- *
- * <C-A> maps to <C-a>, <C-S-a> maps to <C-S-A>
- * <C- > maps to <C-Space>, <S-a> maps to A
- * << maps to <lt><lt>
- *
- * <S-@> is preserved, as in Vim, to allow untypeable key-combinations
- * in macros.
- *
- * canonicalKeys(canonicalKeys(x)) == canonicalKeys(x) for all values
- * of x.
- *
- * @param {string} keys Messy form.
- * @param {boolean} unknownOk Whether unknown keys are passed
- * through rather than being converted to <lt>keyname>.
- * @default false
- * @returns {string} Canonical form.
- */
- canonicalKeys: function (keys, unknownOk) {
- if (arguments.length === 1)
- unknownOk = true;
- return events.fromString(keys, unknownOk).map(events.closure.toString).join("");
+ toString: function toString() {
+ if (!arguments.length)
+ return toString.supercall(this);
+ deprecated.warn(toString, "toString", "DOM.Event.stringify");
+ return DOM.Event.stringify.apply(DOM.Event, arguments);
},
- iterKeys: function (keys) iter(function () {
- let match, re = /<.*?>?>|[^<]/g;
- while (match = re.exec(keys))
- yield match[0];
- }()),
-
get defaultTarget() dactyl.focusedElement || content.document.body || document.documentElement,
/**
- * Converts an event string into an array of pseudo-event objects.
- *
- * These objects can be used as arguments to events.toString or
- * events.create, though they are unlikely to be much use for other
- * purposes. They have many of the properties you'd expect to find on a
- * real event, but none of the methods.
- *
- * Also may contain two "special" parameters, .dactylString and
- * .dactylShift these are set for characters that can never by
- * typed, but may appear in mappings, for example <Nop> is passed as
- * dactylString, and dactylShift is set when a user specifies
- * <S-@> where @ is a non-case-changeable, non-space character.
- *
- * @param {string} keys The string to parse.
- * @param {boolean} unknownOk Whether unknown keys are passed
- * through rather than being converted to <lt>keyname>.
- * @default false
- * @returns {Array[Object]}
- */
- fromString: function (input, unknownOk) {
-
- if (arguments.length === 1)
- unknownOk = true;
-
- let out = [];
- for (let match in util.regexp.iterate(/<.*?>?>|[^<]|<(?!.*>)/g, input)) {
- let evt_str = match[0];
-
- let evt_obj = { ctrlKey: false, shiftKey: false, altKey: false, metaKey: false,
- keyCode: 0, charCode: 0, type: "keypress" };
-
- if (evt_str.length == 1) {
- evt_obj.charCode = evt_str.charCodeAt(0);
- evt_obj._keyCode = this._key_code[evt_str[0].toLowerCase()];
- evt_obj.shiftKey = evt_str !== evt_str.toLowerCase();
- }
- else {
- let [match, modifier, keyname] = evt_str.match(/^<((?:[*12CASM⌘]-)*)(.+?)>$/i) || [false, '', ''];
- modifier = Set(modifier.toUpperCase());
- keyname = keyname.toLowerCase();
- evt_obj.dactylKeyname = keyname;
- if (/^u[0-9a-f]+$/.test(keyname))
- keyname = String.fromCharCode(parseInt(keyname.substr(1), 16));
-
- if (keyname && (unknownOk || keyname.length == 1 || /mouse$/.test(keyname) ||
- this._key_code[keyname] || Set.has(this._pseudoKeys, keyname))) {
- evt_obj.globKey ="*" in modifier;
- evt_obj.ctrlKey ="C" in modifier;
- evt_obj.altKey ="A" in modifier;
- evt_obj.shiftKey ="S" in modifier;
- evt_obj.metaKey ="M" in modifier || "⌘" in modifier;
- evt_obj.dactylShift = evt_obj.shiftKey;
-
- if (keyname.length == 1) { // normal characters
- if (evt_obj.shiftKey)
- keyname = keyname.toUpperCase();
-
- evt_obj.dactylShift = evt_obj.shiftKey && keyname.toUpperCase() == keyname.toLowerCase();
- evt_obj.charCode = keyname.charCodeAt(0);
- evt_obj._keyCode = this._key_code[keyname.toLowerCase()];
- }
- else if (Set.has(this._pseudoKeys, keyname)) {
- evt_obj.dactylString = "<" + this._key_key[keyname] + ">";
- }
- else if (/mouse$/.test(keyname)) { // mouse events
- evt_obj.type = (/2-/.test(modifier) ? "dblclick" : "click");
- evt_obj.button = ["leftmouse", "middlemouse", "rightmouse"].indexOf(keyname);
- delete evt_obj.keyCode;
- delete evt_obj.charCode;
- }
- else { // spaces, control characters, and <
- evt_obj.keyCode = this._key_code[keyname];
- evt_obj.charCode = 0;
- }
- }
- else { // an invalid sequence starting with <, treat as a literal
- out = out.concat(events.fromString("<lt>" + evt_str.substr(1)));
- continue;
- }
- }
-
- // TODO: make a list of characters that need keyCode and charCode somewhere
- if (evt_obj.keyCode == 32 || evt_obj.charCode == 32)
- evt_obj.charCode = evt_obj.keyCode = 32; // <Space>
- if (evt_obj.keyCode == 60 || evt_obj.charCode == 60)
- evt_obj.charCode = evt_obj.keyCode = 60; // <lt>
-
- evt_obj.modifiers = (evt_obj.ctrlKey && Ci.nsIDOMNSEvent.CONTROL_MASK)
- | (evt_obj.altKey && Ci.nsIDOMNSEvent.ALT_MASK)
- | (evt_obj.shiftKey && Ci.nsIDOMNSEvent.SHIFT_MASK)
- | (evt_obj.metaKey && Ci.nsIDOMNSEvent.META_MASK);
-
- out.push(evt_obj);
- }
- return out;
- },
-
- /**
- * Converts the specified event to a string in dactyl key-code
- * notation. Returns null for an unknown event.
- *
- * @param {Event} event
- * @returns {string}
- */
- toString: function toString(event) {
- if (!event)
- return toString.supercall(this);
-
- if (event.dactylString)
- return event.dactylString;
-
- let key = null;
- let modifier = "";
-
- if (event.globKey)
- modifier += "*-";
- if (event.ctrlKey)
- modifier += "C-";
- if (event.altKey)
- modifier += "A-";
- if (event.metaKey)
- modifier += "M-";
-
- if (/^key/.test(event.type)) {
- let charCode = event.type == "keyup" ? 0 : event.charCode; // Why? --Kris
- if (charCode == 0) {
- if (event.keyCode in this._code_key) {
- key = this._code_key[event.keyCode];
-
- if (event.shiftKey && (key.length > 1 || event.ctrlKey || event.altKey || event.metaKey) || event.dactylShift)
- modifier += "S-";
- else if (!modifier && key.length === 1)
- if (event.shiftKey)
- key = key.toUpperCase();
- else
- key = key.toLowerCase();
-
- if (!modifier && /^[a-z0-9]$/i.test(key))
- return key;
- }
- }
- // [Ctrl-Bug] special handling of mysterious <C-[>, <C-\\>, <C-]>, <C-^>, <C-_> bugs (OS/X)
- // (i.e., cntrl codes 27--31)
- // ---
- // For more information, see:
- // [*] Referenced mailing list msg: http://www.mozdev.org/pipermail/pentadactyl/2008-May/001548.html
- // [*] Mozilla bug 416227: event.charCode in keypress handler has unexpected values on Mac for Ctrl with chars in "[ ] _ \"
- // https://bugzilla.mozilla.org/show_bug.cgi?id=416227
- // [*] Mozilla bug 432951: Ctrl+'foo' doesn't seem same charCode as Meta+'foo' on Cocoa
- // https://bugzilla.mozilla.org/show_bug.cgi?id=432951
- // ---
- //
- // The following fixes are only activated if config.OS.isMacOSX.
- // Technically, they prevent mappings from <C-Esc> (and
- // <C-C-]> if your fancy keyboard permits such things<?>), but
- // these <C-control> mappings are probably pathological (<C-Esc>
- // certainly is on Windows), and so it is probably
- // harmless to remove the config.OS.isMacOSX if desired.
- //
- else if (config.OS.isMacOSX && event.ctrlKey && charCode >= 27 && charCode <= 31) {
- if (charCode == 27) { // [Ctrl-Bug 1/5] the <C-[> bug
- key = "Esc";
- modifier = modifier.replace("C-", "");
- }
- else // [Ctrl-Bug 2,3,4,5/5] the <C-\\>, <C-]>, <C-^>, <C-_> bugs
- key = String.fromCharCode(charCode + 64);
- }
- // a normal key like a, b, c, 0, etc.
- else if (charCode > 0) {
- key = String.fromCharCode(charCode);
-
- if (!/^[a-z0-9]$/i.test(key) && key in this._key_code) {
- // a named charCode key (<Space> and <lt>) space can be shifted, <lt> must be forced
- if ((key.match(/^\s$/) && event.shiftKey) || event.dactylShift)
- modifier += "S-";
-
- key = this._code_key[this._key_code[key]];
- }
- else {
- // a shift modifier is only allowed if the key is alphabetical and used in a C-A-M- mapping in the uppercase,
- // or if the shift has been forced for a non-alphabetical character by the user while :map-ping
- if (key !== key.toLowerCase() && (event.ctrlKey || event.altKey || event.metaKey) || event.dactylShift)
- modifier += "S-";
- if (/^\s$/.test(key))
- key = let (s = charCode.toString(16)) "U" + "0000".substr(4 - s.length) + s;
- else if (modifier.length == 0)
- return key;
- }
- }
- if (key == null) {
- if (event.shiftKey)
- modifier += "S-";
- key = this._key_key[event.dactylKeyname] || event.dactylKeyname;
- }
- if (key == null)
- return null;
- }
- else if (event.type == "click" || event.type == "dblclick") {
- if (event.shiftKey)
- modifier += "S-";
- if (event.type == "dblclick")
- modifier += "2-";
- // TODO: triple and quadruple click
-
- switch (event.button) {
- case 0:
- key = "LeftMouse";
- break;
- case 1:
- key = "MiddleMouse";
- break;
- case 2:
- key = "RightMouse";
- break;
- }
- }
-
- if (key == null)
- return null;
-
- return "<" + modifier + key + ">";
- },
-
- /**
* Returns true if there's a known native key handler for the given
* event in the given mode.
*
@@ -957,7 +650,7 @@ var Events = Module("events", {
event[k] = v;
DOM.Event.feedingEvent = null;
- let key = events.toString(event);
+ let key = DOM.Event.stringify(event);
// Hack to deal with <BS> and so forth not dispatching input
// events
@@ -1079,7 +772,7 @@ var Events = Module("events", {
!modes.passThrough && this.shouldPass(event) ||
!this.processor && event.type === "keydown"
&& options.get("passunknown").getKey(modes.main.allBases)
- && let (key = events.toString(event))
+ && let (key = DOM.Event.stringify(event))
!modes.main.allBases.some(
function (mode) mappings.hives.some(
function (hive) hive.get(mode, key) || hive.getCandidates(mode, key)));
@@ -1087,7 +780,7 @@ var Events = Module("events", {
if (event.type === "keydown")
this.passing = pass;
- events.dbg("ON " + event.type.toUpperCase() + " " + this.toString(event) + " pass: " + pass + " replay: " + event.isReplay + " macro: " + event.isMacro);
+ events.dbg("ON " + event.type.toUpperCase() + " " + DOM.Event.stringify(event) + " pass: " + pass + " replay: " + event.isReplay + " macro: " + event.isMacro);
// Prevents certain sites from transferring focus to an input box
// before we get a chance to process our key bindings on the
@@ -1220,7 +913,7 @@ var Events = Module("events", {
shouldPass: function shouldPass(event)
!event.noremap && (!dactyl.focusedElement || events.isContentNode(dactyl.focusedElement)) &&
- options.get("passkeys").has(events.toString(event))
+ options.get("passkeys").has(DOM.Event.stringify(event))
}, {
ABORT: {},
KILL: true,
@@ -1229,7 +922,7 @@ var Events = Module("events", {
WAIT: null,
isEscape: function isEscape(event)
- let (key = isString(event) ? event : events.toString(event))
+ let (key = isString(event) ? event : DOM.Event.stringify(event))
key === "<Esc>" || key === "<C-[>",
isHidden: function isHidden(elem, aggressive) {
@@ -1405,9 +1098,9 @@ var Events = Module("events", {
let value = parse.superapply(this, arguments);
value.forEach(function (filter) {
let vals = Option.splitList(filter.result);
- filter.keys = events.fromString(vals[0]).map(events.closure.toString);
+ filter.keys = DOM.Event.parse(vals[0]).map(DOM.Event.closure.stringify);
- filter.commandKeys = vals.slice(1).map(events.closure.canonicalKeys);
+ filter.commandKeys = vals.slice(1).map(DOM.Event.closure.canonicalKeys);
filter.inputKeys = filter.commandKeys.filter(bind("test", /^<[ACM]-/));
});
return value;