diff --git a/common/content/buffer.js b/common/content/buffer.js index bd468b65..0d8df89f 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -481,8 +481,8 @@ var Buffer = Module("buffer", { * * @returns {string} */ - getCurrentWord: function () { - let win = buffer.focusedFrame || content; + getCurrentWord: function (win) { + win = win || buffer.focusedFrame || content; let selection = win.getSelection(); if (selection.rangeCount == 0) return ""; diff --git a/common/content/commandline.js b/common/content/commandline.js index 3cf54785..ee7c30db 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -720,6 +720,7 @@ var CommandLine = Module("commandline", { commandline.updateOutputHeight(true); + elem.scrollTop = 0; if (options["more"] && Buffer.isScrollable(elem, 1)) { // start the last executed command's output at the top of the screen let elements = doc.getElementsByClassName("ex-command-output"); @@ -1030,11 +1031,6 @@ var CommandLine = Module("commandline", { let win = this.widgets.multilineOutput.contentWindow; let elem = win.document.documentElement; - let showMoreHelpPrompt = false; - let showMorePrompt = false; - let closeWindow = false; - let passEvent = false; - let key = events.toString(event); // TODO: Wouldn't multiple handlers be cleaner? --djk @@ -1080,127 +1076,13 @@ var CommandLine = Module("commandline", { function atEnd(dir) !Buffer.isScrollable(elem, dir || 1); - switch (key) { - case "": - closeWindow = true; - break; // handled globally in events.js:onEscape() - - case ":": - commandline.open(":", "", modes.EX); - return false; - - // down a line - case "j": - case "": - if (options["more"]) - Buffer.scrollVertical(elem, "lines", 1); - else - passEvent = true; - break; - - case "": - case "": - case "": - if (options["more"] && !atEnd(1)) - Buffer.scrollVertical(elem, "lines", 1); - else - closeWindow = true; // don't propagate the event for accept keys - break; - - // up a line - case "k": - case "": - case "": - if (options["more"]) - Buffer.scrollVertical(elem, "lines", -1); - else - passEvent = true; - break; - - // half page down - case "d": - if (options["more"]) - Buffer.scrollVertical(elem, "pages", .5); - else - passEvent = true; - break; - - // TODO: on the prompt line should scroll one page - // page down - case "f": - case "": - case "": - if (options["more"] && !atEnd(1)) - Buffer.scrollVertical(elem, "pages", 1); - else - passEvent = true; - break; - - // half page up - case "u": - // if (more and scrollable) - if (options["more"]) - Buffer.scrollVertical(elem, "pages", -.5); - else - passEvent = true; - break; - - // page up - case "b": - case "": - if (options["more"]) - Buffer.scrollVertical(elem, "pages", -1); - else - passEvent = true; - break; - - // top of page - case "g": - if (options["more"]) - elem.scrollTop = 0; - else - passEvent = true; - break; - - // bottom of page - case "G": - if (options["more"]) - elem.scrollTop = elem.scrollHeight; - else - passEvent = true; - break; - - // copy text to clipboard - case "": - dactyl.clipboardWrite(window.getSelection()); - break; - - // close the window - case "q": - closeWindow = true; - break; - - case ";": - hints.open(";", { window: win }); - return false; - - // unmapped key - default: - if (!options["more"] || atEnd(1)) - passEvent = true; - else - showMoreHelpPrompt = true; - } - - if (passEvent || closeWindow) { + if (!options["more"] || atEnd(1)) { + passEvent = true; modes.pop(); - - if (passEvent) - events.onKeyPress(event); + events.feedkeys(key); } else - commandline.updateMorePrompt(showMorePrompt, showMoreHelpPrompt); - return false; + commandline.updateMorePrompt(false, true); }, getSpaceNeeded: function getSpaceNeeded() { @@ -1782,6 +1664,85 @@ var CommandLine = Module("commandline", { mappings.add(myModes, ["", ""], "Recall the next command line from the history list", function () { events.feedkeys(""); }); + + // add the ":" mapping in all but insert mode mappings + mappings.add(modes.matchModes({ extended: false, input: false }), + [":"], "Enter command-line mode", + function () { commandline.open(":", "", modes.EX); }); + + function body() commandline.widgets.multilineOutput.contentDocument.documentElement; + function win() commandline.widgets.multilineOutput.contentWindow; + function atEnd(dir) !Buffer.isScrollable(body(), dir || 1); + + mappings.add([modes.OUTPUT_MULTILINE], + ["", ""], "Exit multi-line output mode", + function () {}); + + const PASS = true; + const DROP = false; + + function bind(keys, description, action, test, default_) { + mappings.add([modes.OUTPUT_MULTILINE], + keys, description, + function (command) { + if (!options["more"]) + var res = PASS; + else if (test && !test(command)) + res = default_; + else + res = action.call(command); + util.dump(String.quote(command), res, !!test, test && test(command)); + + if (res === PASS || res === DROP) + modes.pop(); + else + commandline.updateMorePrompt(); + if (res === PASS) + events.feedkeys(command); + }); + } + + bind(["j", "", ""], "Scroll down one line", + function () { Buffer.scrollVertical(body(), "lines", 1); }, + function () !atEnd(1), PASS); + + bind(["k", "", ""], "Scroll up one line", + function () { Buffer.scrollVertical(body(), "lines", -1); }); + + bind(["", "", ""], "Scroll down one line, exit on last line", + function () { Buffer.scrollVertical(body(), "lines", 1); }, + function () !atEnd(1), DROP); + + // half page down + bind([""], "Scroll down half a page", + function () { Buffer.scrollVertical(body(), "pages", .5); }, + function () atEnd(1), PASS); + + bind(["", "", ""], "Scroll down one page", + function () { Buffer.scrollVertical(body(), "pages", 1); }, + function () !atEnd(1), PASS); + + bind([""], "Scroll up half a page", + function () { Buffer.scrollVertical(body(), "pages", -.5); }); + + bind(["", ""], "Scroll up half a page", + function () { Buffer.scrollVertical(body(), "pages", -1); }); + + bind(["gg"], "Scroll to the beginning of output", + function () { Buffer.scrollToPercent(body(), null, 0); }); + + bind(["G"], "Scroll to the end of output", + function () { body().scrollTop = body().scrollHeight; }, + function () !atEnd(1), PASS); + + // copy text to clipboard + bind([""], "Yank selection to clipboard", + function () { dactyl.clipboardWrite(buffer.getCurrentWord(win())); }); + + // close the window + bind(["q"], "Close the output window", + function () {}, + function () false, DROP); }, options: function () { options.add(["history", "hi"], diff --git a/common/content/events.js b/common/content/events.js index 0c3b5a7a..cd69ff3b 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -1222,11 +1222,6 @@ var Events = Module("events", { }; }, mappings: function () { - // add the ":" mapping in all but insert mode mappings - mappings.add(modes.matchModes({ extended: false, input: false }), - [":"], "Enter command-line mode", - function () { commandline.open(":", "", modes.EX); }); - mappings.add(modes.all, [""], "Temporarily ignore all " + config.appName + " key bindings", function () { modes.push(modes.PASS_THROUGH); }); @@ -1242,7 +1237,7 @@ var Events = Module("events", { mappings.add(modes.all, [""], "Do nothing", - function () { return; }); + function () {}); // macros mappings.add([modes.NORMAL, modes.TEXT_AREA, modes.PLAYER].filter(util.identity), diff --git a/common/content/hints.js b/common/content/hints.js index 0bdd1d83..158ed857 100644 --- a/common/content/hints.js +++ b/common/content/hints.js @@ -833,6 +833,11 @@ var Hints = Module("hints", { */ show: function show(minor, opts) { opts = opts || {}; + + // Hack. + if (!opts.window && modes.main == modes.OUTPUT_MULTILINE) + opts.window = commandline.widgets.multilineOutput.contentWindow; + this._hintMode = this._hintModes[minor]; dactyl.assert(this._hintMode); @@ -1034,7 +1039,7 @@ var Hints = Module("hints", { Mode: Struct("name", "prompt", "action", "tags", "filter") }, { mappings: function () { - var myModes = config.browserModes; + var myModes = config.browserModes.concat(modes.OUTPUT_MULTILINE); mappings.add(myModes, ["f"], "Start QuickHint mode", function () { hints.show("o"); }); diff --git a/common/modules/services.jsm b/common/modules/services.jsm index 87db57df..da9072e4 100644 --- a/common/modules/services.jsm +++ b/common/modules/services.jsm @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2020 by Kris Maglione +// Copyright (c) 2008-2010 by Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. diff --git a/common/modules/util.jsm b/common/modules/util.jsm index 881acd9a..e46f78a4 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -997,8 +997,12 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), for (let [elem, xml, attr] in iterator) { if (elem = doc.getElementById(elem)) { let node = util.xmlToDom(xml, doc, obj.objects); - for (let n in array.iterValues(node.childNodes)) - doc.dactylOverlayElements.push(n); + if (!(node instanceof Ci.nsIDOMDocumentFragment)) + doc.dactylOverlayElements.push(node); + else + for (let n in array.iterValues(node.childNodes)) + doc.dactylOverlayElements.push(n); + fn(elem, node); for each (let attr in attr || []) // FIXME: Cleanup... if (attr.name() != "highlight")