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.js67
1 files changed, 46 insertions, 21 deletions
diff --git a/common/content/events.js b/common/content/events.js
index b0cfecee..e6c3400a 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -33,6 +33,7 @@ var ProcessorStack = Class("ProcessorStack", {
process: function process(event) {
function dbg() {}
+ let dbg = util.closure.dump;
let key = events.toString(event);
this.events.push(event);
@@ -90,21 +91,20 @@ var ProcessorStack = Class("ProcessorStack", {
if (processors.length)
result = Events.KILL;
else if (this.actions.length) {
- if (actions.length == 0)
+ if (actions.length == 0) {
dactyl.beep();
-
- if (modes.replaying && !events.waitForPageLoad())
- result = Events.KILL;
- else {
- for (var res = this.actions[0]; callable(res);)
- res = res();
- result = res === Events.PASS ? Events.PASS : Events.KILL;
+ events.feedingKeys = false;
}
+
+ for (var res = this.actions[0]; callable(res);)
+ res = res();
+ result = res === Events.PASS ? Events.PASS : Events.KILL;
}
else if (result !== Events.KILL && !this.actions.length &&
processors.some(function (p) !p.main.passUnknown)) {
result = Events.KILL;
dactyl.beep();
+ events.feedingKeys = false;
}
else if (result === undefined)
result = Events.PASS;
@@ -115,9 +115,11 @@ var ProcessorStack = Class("ProcessorStack", {
if (result === Events.PASS || result === Events.ABORT)
this.events.filter(function (e) e.getPreventDefault())
.forEach(function (event, i) {
+ let elem = event.originalTarget;
if (event.originalTarget) {
- let evt = events.create(event.originalTarget.ownerDocument, event.type, event);
- events.dispatch(event.originalTarget, evt, { skipmap: true, isMacro: true });
+ let doc = elem.ownerDocument || elem.document || elem;
+ let evt = events.create(doc, event.type, event);
+ events.dispatch(elem, evt, { skipmap: true, isMacro: true, isReplay: true });
}
else if (i > 0)
events.events.keypress.call(events, event);
@@ -491,6 +493,8 @@ var Events = Module("events", {
util.threadYield(1, true);
for (let [, evt_obj] in Iterator(events.fromString(keys))) {
+ let now = Date.now();
+ util.dump("+feed", events.toString(evt_obj));
for (let type in values(["keydown", "keyup", "keypress"])) {
let evt = update({}, evt_obj, { type: type });
@@ -508,13 +512,10 @@ var Events = Module("events", {
else
events.events.keypress.call(events, event);
}
+ util.dump("-feed", events.toString(evt_obj), this.feedingKeys);
if (!this.feedingKeys)
break;
-
- // Stop feeding keys if page loading failed.
- if (modes.replaying && !this.waitForPageLoad())
- break;
}
}
catch (e) {
@@ -594,9 +595,14 @@ var Events = Module("events", {
* 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("");
},
@@ -1035,7 +1041,7 @@ var Events = Module("events", {
if (!key)
return null;
- if (modes.recording && (!this._input || !mappings.user.hasMap(modes.main, this._input.buffer + key)))
+ if (modes.recording && !event.isReplay)
events._macroKeys.push(key);
// feedingKeys needs to be separate from interrupted so
@@ -1043,8 +1049,6 @@ var Events = Module("events", {
// interrupting whatever it's started and a real <C-c>
// interrupting our playback.
if (events.feedingKeys && !event.isMacro) {
- if (!event.originalTarget)
- util.dumpStack();
if (key == "<C-c>") {
events.feedingKeys = false;
if (modes.replaying) {
@@ -1323,11 +1327,11 @@ var Events = Module("events", {
},
mappings: function () {
mappings.add(modes.all,
- ["<C-z>"], "Temporarily ignore all " + config.appName + " key bindings",
+ ["<C-z>", "<pass-all-keys>"], "Temporarily ignore all " + config.appName + " key bindings",
function () { modes.push(modes.PASS_THROUGH); });
mappings.add(modes.all,
- ["<C-v>"], "Pass through next key",
+ ["<C-v>", "<pass-next-key>"], "Pass through next key",
function () {
if (modes.main == modes.QUOTE)
return Events.PASS;
@@ -1340,7 +1344,7 @@ var Events = Module("events", {
// macros
mappings.add([modes.NORMAL, modes.TEXT_AREA, modes.PLAYER].filter(util.identity),
- ["q"], "Record a key sequence into a macro",
+ ["q", "<record-macro>"], "Record a key sequence into a macro",
function ({ arg }) {
events._macroKeys.pop();
events[modes.recording ? "finishRecording" : "startRecording"](arg);
@@ -1348,13 +1352,34 @@ var Events = Module("events", {
{ get arg() !modes.recording });
mappings.add([modes.NORMAL, modes.TEXT_AREA, modes.PLAYER].filter(util.identity),
- ["@"], "Play a macro",
+ ["@", "<play-macro>"], "Play a macro",
function ({ arg, count }) {
count = Math.max(count, 1);
while (count-- && events.playMacro(arg))
;
},
{ arg: true, count: true });
+
+ mappings.add([modes.COMMAND],
+ ["<A-m>s", "<sleep>"], "Sleep for {count} milliseconds before continuing macro playback",
+ function ({ command, count }) {
+ let now = Date.now();
+ util.dump("+<sleep>", count);
+ dactyl.assert(count, "Count required for " + command);
+ if (events.feedingKeys)
+ util.sleep(count);
+ util.dump("-<sleep>", count, now - Date.now());
+ },
+ { count: true });
+
+ mappings.add([modes.MAIN],
+ ["<A-m>l", "<wait-for-page-load>"], "Wait for the current page to finish loading before continuing macro playback",
+ function () {
+ if (!events.waitForPageLoad()) {
+ util.interrupted = true;
+ throw Error("Interrupted");
+ }
+ });
},
options: function () {
options.add(["passkeys", "pk"],