diff --git a/common/components/protocols.js b/common/components/protocols.js index 94eab5d7..78691973 100644 --- a/common/components/protocols.js +++ b/common/components/protocols.js @@ -1,4 +1,4 @@ -// Copyright (c) 2008-2010 Kris Maglione +// Copyright (c) 2008-2011 Kris Maglione // // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. @@ -8,14 +8,6 @@ function reportError(e) { Cu.reportError(e); } -/* Adds support for data: URIs with chrome privileges - * and fragment identifiers. - * - * "chrome-data:" [; ]* "," [] - * - * By Kris Maglione, ideas from Ed Anuff's nsChromeExtensionHandler. - */ - var NAME = "protocols"; var global = this; var Cc = Components.classes; @@ -76,6 +68,13 @@ function Factory(clas) ({ } }); +/* Adds support for data: URIs with chrome privileges + * and fragment identifiers. + * + * "chrome-data:" [; ]* "," [] + * + * By Kris Maglione, ideas from Ed Anuff's nsChromeExtensionHandler. + */ function ChromeData() {} ChromeData.prototype = { contractID: "@mozilla.org/network/protocol;1?name=chrome-data", diff --git a/common/content/browser.js b/common/content/browser.js index ff3fbc1a..1aaecedf 100644 --- a/common/content/browser.js +++ b/common/content/browser.js @@ -207,26 +207,39 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { argCount: "0" }); }, mappings: function initMappings(dactyl, modules, window) { - // opening websites - mappings.add([modes.NORMAL], - ["o"], "Open one or more URLs", - function () { CommandExMode().open("open "); }); + let openModes = array.toObject([ + [dactyl.CURRENT_TAB, ""], + [dactyl.NEW_TAB, "tab"], + [dactyl.NEW_BACKGROUND_TAB, "background tab"], + [dactyl.NEW_WINDOW, "win"] + ]); + + function open(mode, args) { + if (dactyl.forceTarget in openModes) + mode = openModes[dactyl.forceTarget]; + + CommandExMode().open(mode + "open " + (args || "")) + } function decode(uri) util.losslessDecodeURI(uri) .replace(/%20(?!(?:%20)*$)/g, " ") .replace(RegExp(options["urlseparator"], "g"), encodeURIComponent); + mappings.add([modes.NORMAL], + ["o"], "Open one or more URLs", + function () { open(""); }); + mappings.add([modes.NORMAL], ["O"], "Open one or more URLs, based on current location", - function () { CommandExMode().open("open " + decode(buffer.uri.spec)); }); + function () { open("", decode(buffer.uri.spec)); }); mappings.add([modes.NORMAL], ["s"], "Open a search prompt", - function () { CommandExMode().open("open " + options["defsearch"] + " "); }); + function () { open("", options["defsearch"] + " "); }); mappings.add([modes.NORMAL], ["S"], "Open a search prompt for a new tab", - function () { CommandExMode().open("tabopen " + options["defsearch"] + " "); }); + function () { open("tab", options["defsearch"] + " "); }); mappings.add([modes.NORMAL], ["t"], "Open one or more URLs in a new tab", @@ -234,15 +247,15 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), mappings.add([modes.NORMAL], ["T"], "Open one or more URLs in a new tab, based on current location", - function () { CommandExMode().open("tabopen " + decode(buffer.uri.spec)); }); + function () { open("tab", decode(buffer.uri.spec)); }); mappings.add([modes.NORMAL], ["w"], "Open one or more URLs in a new window", - function () { CommandExMode().open("winopen "); }); + function () { open("win"); }); mappings.add([modes.NORMAL], ["W"], "Open one or more URLs in a new window, based on current location", - function () { CommandExMode().open("winopen " + decode(buffer.uri.spec)); }); + function () { open("win", decode(buffer.uri.spec)); }); mappings.add([modes.NORMAL], ["", "~"], "Open home directory", diff --git a/common/content/buffer.js b/common/content/buffer.js index 6e7c9725..c9838bb2 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -592,11 +592,12 @@ var Buffer = Module("buffer", { } let ctrlKey = false, shiftKey = false; - switch (where) { + switch (dactyl.forceTarget || where) { case dactyl.NEW_TAB: case dactyl.NEW_BACKGROUND_TAB: ctrlKey = true; - shiftKey = (where != dactyl.NEW_BACKGROUND_TAB); + shiftKey = dactyl.forceBackground != null ? dactyl.forceBackground + : where != dactyl.NEW_BACKGROUND_TAB; break; case dactyl.NEW_WINDOW: shiftKey = true; diff --git a/common/content/commandline.js b/common/content/commandline.js index 4dfe2f08..ddc6dbd4 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -1350,6 +1350,8 @@ var CommandLine = Module("commandline", { arg = dactyl.userEval(arg); if (isObject(arg)) arg = util.objectToString(arg, useColor); + else if (callable(arg)) + arg = String(arg); else if (!isString(arg) && useColor) arg = template.highlight(arg); return arg; diff --git a/common/content/dactyl.js b/common/content/dactyl.js index b0f1b8ee..f5bb119d 100644 --- a/common/content/dactyl.js +++ b/common/content/dactyl.js @@ -172,8 +172,17 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { NEW_BACKGROUND_TAB: "background-tab", NEW_WINDOW: "window", + forceBackground: null, forceTarget: null, + get forceOpen() ({ background: this.forceBackground, + target: this.forceTarget }), + set forceOpen(val) { + for (let [k, v] in Iterator({ background: "forceBackground", target: "forceTarget" })) + if (k in val) + this[v] = val[k]; + }, + version: deprecated("config.version", { get: function version() config.version }), /** @@ -1038,11 +1047,12 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { let args = null; if (obj instanceof Command) { - link = function (cmd) {cmd}; + link = function (cmd) :{cmd}; args = obj.parseArgs("", CompletionContext(str || "")); + tag = function (cmd) <>:{cmd}; spec = function (cmd) <>{ obj.count ? count : <> - }{ + }:{ cmd }{ obj.bang ? ! : <> @@ -1228,26 +1238,28 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { } }, - onClick: function onClick(event) { - if (event.originalTarget instanceof Element) { - let command = event.originalTarget.getAttributeNS(NS, "command"); - if (command && event.button == 0) { - event.preventDefault(); + events: { + click: function onClick(event) { + if (event.originalTarget instanceof Element) { + let command = event.originalTarget.getAttributeNS(NS, "command"); + if (command && event.button == 0) { + event.preventDefault(); - if (dactyl.commands[command]) - dactyl.withSavedValues(["forceTarget"], function () { - if (event.ctrlKey || event.shiftKey || event.button == 1) - dactyl.forceTarget = dactyl.NEW_TAB; - dactyl.commands[command](event); - }); + if (dactyl.commands[command]) + dactyl.withSavedValues(["forceTarget"], function () { + if (event.ctrlKey || event.shiftKey || event.button == 1) + dactyl.forceTarget = dactyl.NEW_TAB; + dactyl.commands[command](event); + }); + } } - } - }, + }, - onExecute: function onExecute(event) { - let cmd = event.originalTarget.getAttribute("dactyl-execute"); - commands.execute(cmd, null, false, null, - { file: /*L*/"[Command Line]", line: 1 }); + "dactyl.execute": function onExecute(event) { + let cmd = event.originalTarget.getAttribute("dactyl-execute"); + commands.execute(cmd, null, false, null, + { file: /*L*/"[Command Line]", line: 1 }); + } }, /** @@ -1299,8 +1311,9 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { flags |= params[opt] && Ci.nsIWebNavigation["LOAD_FLAGS_" + flag]; let where = params.where || dactyl.CURRENT_TAB; - let background = ("background" in params) ? params.background - : params.where == dactyl.NEW_BACKGROUND_TAB; + let background = dactyl.forceBackground != null ? dactyl.forceBackground : + ("background" in params) ? params.background + : params.where == dactyl.NEW_BACKGROUND_TAB; if (params.from && dactyl.has("tabs")) { if (!params.where && options.get("newtab").has(params.from)) @@ -1547,10 +1560,9 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { return []; } }, - wrapCallback: function (callback, self) { self = self || this; - let save = ["forceTarget"]; + let save = ["forceOpen"]; let saved = save.map(function (p) dactyl[p]); return function wrappedCallback() { let args = arguments; @@ -1576,8 +1588,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), { toolbarHidden: function hidden(elem) (elem.getAttribute("autohide") || elem.getAttribute("collapsed")) == "true" }, { events: function () { - events.listen(window, "click", dactyl.closure.onClick, true); - events.listen(window, "dactyl.execute", dactyl.closure.onExecute, true); + events.listen(window, dactyl, "events", true); }, // Only general options are added here, which are valid for all Dactyl extensions options: function () { diff --git a/common/content/events.js b/common/content/events.js index d3812035..999685f8 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -352,10 +352,8 @@ var EventHive = Class("EventHive", Contexts.Hive, { listen: function (target, event, callback, capture, allowUntrusted) { if (!isObject(event)) var [self, events] = [null, array.toObject([[event, callback]])]; - else { + else [self, events] = [event, event[callback || "events"]]; - [, , capture, allowUntrusted] = arguments; - } if (Set.has(events, "input") && !Set.has(events, "dactyl-input")) events["dactyl-input"] = events.input; @@ -494,7 +492,7 @@ var Events = Module("events", { } this._activeMenubar = false; - this.listen(window, this, "events"); + this.listen(window, this, "events", true); }, signals: { diff --git a/common/content/hints.js b/common/content/hints.js index 2c4b29ed..8c2c7efe 100644 --- a/common/content/hints.js +++ b/common/content/hints.js @@ -17,6 +17,8 @@ var HintSession = Class("HintSession", CommandMode, { opts = opts || {}; + this.forceOpen = opts.forceOpen || dactyl.forceOpen; + // Hack. if (!opts.window && modes.main == modes.OUTPUT_MULTILINE) opts.window = commandline.widgets.multilineOutput.contentWindow; @@ -505,9 +507,12 @@ var HintSession = Class("HintSession", CommandMode, { modes.push(modes.IGNORE, modes.HINTS); } - dactyl.trapErrors("action", this.hintMode, - elem, elem.href || elem.src || "", - this.extendedhintCount, top); + dactyl.withSavedValues(["forceOpen"], function () { + dactyl.forceOpen = this.forceOpen; + dactyl.trapErrors("action", this.hintMode, + elem, elem.href || elem.src || "", + this.extendedhintCount, top); + }, this); this.timeout(function () { if (modes.main == modes.IGNORE && !this.continue) @@ -1030,6 +1035,11 @@ var Hints = Module("hints", { open: function open(mode, opts) { this._extendedhintCount = opts.count; + + opts = opts || {}; + if (!Set.has(opts, "forceOpen")) + opts.forceOpen = dactyl.forceOpen; + commandline.input(["Normal", mode], "", { autocomplete: false, completer: function (context) { diff --git a/common/content/tabs.js b/common/content/tabs.js index db0e5e9c..092ec1f3 100644 --- a/common/content/tabs.js +++ b/common/content/tabs.js @@ -663,6 +663,20 @@ var Tabs = Module("tabs", { subCommand: 0 }); + commands.add(["background", "bg"], + "Execute a command opening any new tabs in the background", + function (args) { + dactyl.withSavedValues(["forceBackground"], function () { + this.forceBackground = true; + dactyl.execute(args[0], null, true); + }); + }, { + argCount: "1", + completer: function (context) completion.ex(context), + literal: 0, + subCommand: 0 + }); + commands.add(["tabd[o]", "bufd[o]"], "Execute a command in each tab", function (args) { diff --git a/common/locale/en-US/tabs.xml b/common/locale/en-US/tabs.xml index fdf27624..ff387c57 100644 --- a/common/locale/en-US/tabs.xml +++ b/common/locale/en-US/tabs.xml @@ -66,6 +66,14 @@ + + :bg :background + :background + +

Execute a command opening any new tabs in the background.

+
+
+ :tab diff --git a/common/modules/util.jsm b/common/modules/util.jsm index 7bc226c7..70c4b1a9 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -9,7 +9,6 @@ try { Components.utils.import("resource://dactyl/bootstrap.jsm"); - let frag=1; defineModule("util", { exports: ["$", "DOM", "FailedAssertion", "Math", "NS", "Point", "Util", "XBL", "XHTML", "XUL", "util"], require: ["services"], @@ -1705,7 +1704,7 @@ var DOM = Class("DOM", { for (let i = 0; i < this.length; i++) { let tmp = fn.call(self || update(obj, [this[i]]), this[i], i); - if (tmp && "length" in tmp) + if (isObject(tmp) && "length" in tmp) for (let j = 0; j < tmp.length; j++) res[res.length++] = tmp[j]; else if (tmp !== undefined) @@ -2027,8 +2026,8 @@ var DOM = Class("DOM", { elem.setAttributeNS(ns, k, v); }); - if (Set.has(hooks, k) && hooks[k].get) - return hooks[k].get.call(this, elem); + if (Set.has(hooks, key) && hooks[key].get) + return hooks[key].get.call(this, this[0]); if (!this[0].hasAttributeNS(ns, key)) return null; @@ -2119,18 +2118,36 @@ var DOM = Class("DOM", { }, this); }, - toggle: function toggle(val) { + toggle: function toggle(val, self) { + if (callable(val)) + return this.each(function (elem, i) { + this[val.call(self || this, elem, i) ? "show" : "hide"](); + }); + if (arguments.length) return this[val ? "show" : "hide"](); - return this.each(function (elem) { - elem.style.display = this.style.display == "none" ? "block" : "none"; + + let hidden = this.map(function (elem) elem.style.display == "none"); + return this.each(function (elem, i) { + this[hidden[i] ? "show" : "hide"](); }); }, hide: function hide() { return this.each(function (elem) { elem.style.display = "none"; }, this); }, show: function show() { - return this.each(function (elem) { elem.style.display = "block"; }, this); + for (let i = 0; i < this.length; i++) + if (!this[i].dactylDefaultDisplay && this[i].style.display) + this[i].style.display = ""; + + this.each(function (elem) { + if (!elem.dactylDefaultDisplay) + elem.dactylDefaultDisplay = this.style.display; + }); + + return this.each(function (elem) { + elem.style.display = elem.dactylDefaultDisplay == "none" ? "block" : ""; + }, this); }, getSet: function getSet(args, get, set) { diff --git a/pentadactyl/NEWS b/pentadactyl/NEWS index d823f2aa..bcee26e7 100644 --- a/pentadactyl/NEWS +++ b/pentadactyl/NEWS @@ -104,6 +104,7 @@ buffer. Added -sort flag. [b6][b7] - :style now supports regexp site-filters on Firefox 6+. [b7] - :qa closes only the current window, per Vim. [b7] + - Added :background command. [b8] - Added :exit command. [b7] - Added :dlclear command. [b7] - :extensions has been replaced with a more powerful :addons. [b6]