diff --git a/common/content/autocommands.js b/common/content/autocommands.js index 5ce1ab49..e2eef7f9 100644 --- a/common/content/autocommands.js +++ b/common/content/autocommands.js @@ -12,6 +12,8 @@ const AutoCommand = new Struct("event", "pattern", "command"); * @instance autocommands */ const AutoCommands = Module("autocommands", { + requires: ["config"], + init: function () { this._store = []; }, diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js index 452d384d..230decd4 100644 --- a/common/content/bookmarks.js +++ b/common/content/bookmarks.js @@ -8,7 +8,7 @@ const DEFAULT_FAVICON = "chrome://mozapps/skin/places/defaultFavicon.png"; // also includes methods for dealing with keywords and search engines const Bookmarks = Module("bookmarks", { - requires: ["autocommands", "liberator", "storage", "services"], + requires: ["autocommands", "config", "liberator", "storage", "services"], init: function () { const faviconService = services.get("favicon"); diff --git a/common/content/buffer.js b/common/content/buffer.js index c08a42e1..4ae9d804 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -15,6 +15,8 @@ const Point = new Struct("x", "y"); * @instance buffer */ const Buffer = Module("buffer", { + requires: ["config"], + init: function () { this.pageInfo = {}; diff --git a/common/content/commandline.js b/common/content/commandline.js index 6a66f63d..f8d89139 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -12,7 +12,7 @@ * this class when the chrome is ready. */ const CommandLine = Module("commandline", { - requires: ["liberator", "modes", "services", "storage", "template", "util"], + requires: ["config", "liberator", "modes", "services", "storage", "template", "util"], init: function () { const self = this; diff --git a/common/content/commands.js b/common/content/commands.js index 9b4cdd34..ac598fca 100644 --- a/common/content/commands.js +++ b/common/content/commands.js @@ -33,6 +33,8 @@ * @private */ const Command = Class("Command", { + requires: ["config"], + init: function (specs, description, action, extraInfo) { specs = Array.concat(specs); diff --git a/common/content/configbase.js b/common/content/configbase.js index 51a59608..cc19deaf 100644 --- a/common/content/configbase.js +++ b/common/content/configbase.js @@ -3,8 +3,7 @@ // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. - -const configbase = { //{{{ +const ConfigBase = Class(ModuleBase, { /** * @property {[["string", "string"]]} A sequence of names and descriptions * of the autocommands available in this application. Primarily used @@ -99,6 +98,6 @@ const configbase = { //{{{ */ get tempFile() this.name.toLowerCase() + ".tmp" -}; //}}} +}); // vim: set fdm=marker sw=4 ts=4 et: diff --git a/common/content/editor.js b/common/content/editor.js index 2755d8ea..a1b62f80 100644 --- a/common/content/editor.js +++ b/common/content/editor.js @@ -11,6 +11,8 @@ /** @instance editor */ const Editor = Module("editor", { + requires: ["config"], + init: function () { // store our last search with f, F, t or T // diff --git a/common/content/events.js b/common/content/events.js index 8dcfc550..e8debadb 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -10,7 +10,7 @@ * @instance events */ const Events = Module("events", { - requires: ["autocommands"], + requires: ["autocommands", "config"], init: function () { const self = this; diff --git a/common/content/finder.js b/common/content/finder.js index 33334036..53a432e4 100644 --- a/common/content/finder.js +++ b/common/content/finder.js @@ -20,6 +20,8 @@ * @instance finder */ const Finder = Module("finder", { + requires: ["config"], + init: function () { const self = this; diff --git a/common/content/hints.js b/common/content/hints.js index a0fd440c..52452f4d 100644 --- a/common/content/hints.js +++ b/common/content/hints.js @@ -8,6 +8,8 @@ /** @instance hints */ const ELEM = 0, TEXT = 1, SPAN = 2, IMG_SPAN = 3; const Hints = Module("hints", { + requires: ["config"], + init: function () { this._hintMode; diff --git a/common/content/history.js b/common/content/history.js index c9427958..b285a7d4 100644 --- a/common/content/history.js +++ b/common/content/history.js @@ -4,6 +4,8 @@ // given in the LICENSE.txt file included with this file. const History = Module("history", { + requires: ["config"], + get format() bookmarks.format, get service() services.get("history"), diff --git a/common/content/io.js b/common/content/io.js index ed5f7143..5537af4d 100644 --- a/common/content/io.js +++ b/common/content/io.js @@ -267,7 +267,7 @@ const File = Class("File", { * @instance io */ const IO = Module("io", { - requires: ["services"], + requires: ["config", "services"], init: function () { this._processDir = services.get("directory").get("CurWorkD", Ci.nsIFile); diff --git a/common/content/liberator-overlay.js b/common/content/liberator-overlay.js index b2a310b4..e974b2e8 100644 --- a/common/content/liberator-overlay.js +++ b/common/content/liberator-overlay.js @@ -37,8 +37,8 @@ "commandline.js", "commands.js", "completion.js", - "config.js", "configbase.js", + "config.js", "liberator.js", "editor.js", "events.js", @@ -55,10 +55,9 @@ "template.js", "util.js", ].forEach(load); - modules.config.__proto__ = modules.configbase; - prefix.unshift("chrome://" + modules.config.name.toLowerCase() + "/content/"); - modules.config.scripts.forEach(load); + prefix.unshift("chrome://" + modules.Config.prototype.name.toLowerCase() + "/content/"); + modules.Config.prototype.scripts.forEach(load); })(); diff --git a/common/content/liberator.js b/common/content/liberator.js index ee717f28..e9cd7fe9 100644 --- a/common/content/liberator.js +++ b/common/content/liberator.js @@ -38,7 +38,7 @@ const FailedAssertion = Class("FailedAssertion", Error, { }); const Liberator = Module("liberator", { - requires: ["services"], + requires: ["config", "services"], init: function () { window.liberator = this; diff --git a/common/content/marks.js b/common/content/marks.js index 7213d8dd..ff9b1523 100644 --- a/common/content/marks.js +++ b/common/content/marks.js @@ -8,7 +8,7 @@ * @instance marks */ const Marks = Module("marks", { - requires: ["storage"], + requires: ["config", "storage"], init: function init() { this._localMarks = storage.newMap("local-marks", { store: true, privateData: true }); diff --git a/common/content/modes.js b/common/content/modes.js index c47ea658..3de622f1 100644 --- a/common/content/modes.js +++ b/common/content/modes.js @@ -6,7 +6,7 @@ /** @scope modules */ const Modes = Module("modes", { - requires: ["util"], + requires: ["config", "util"], init: function () { this._main = 1; // NORMAL diff --git a/common/content/modules.js b/common/content/modules.js index 7e1a0b1b..c7501c52 100644 --- a/common/content/modules.js +++ b/common/content/modules.js @@ -1,7 +1,10 @@ const ModuleBase = Class("ModuleBase", { requires: [] }); function Module(name, inst, clas, moduleInit) { - const module = Class(name, ModuleBase, inst, clas); + var base = ModuleBase; + if (callable(inst)) + base = Array.splice(arguments, 1, 1)[0] + const module = Class(name, base, inst, clas); module.INIT = moduleInit || {}; module.requires = inst.requires || []; Module.list.push(module); @@ -12,7 +15,7 @@ Module.list = []; Module.constructors = {}; window.addEventListener("load", function () { - function dump(str) window.dump(String.replace(str, /\n?$/, "\n").replace(/^/m, config.name.toLowerCase() + ": ")); + function dump(str) window.dump(String.replace(str, /\n?$/, "\n").replace(/^/m, Config.prototype.name.toLowerCase() + ": ")); const start = Date.now(); const deferredInit = { load: [] }; const seen = set(); diff --git a/common/content/options.js b/common/content/options.js index 32e63ee4..4af8899b 100644 --- a/common/content/options.js +++ b/common/content/options.js @@ -401,7 +401,7 @@ const Option = Class("Option", { * @instance options */ const Options = Module("options", { - requires: ["highlight", "storage"], + requires: ["config", "highlight", "storage"], init: function () { for (let [, pref] in Iterator(this.allPrefs(Options.OLD_SAVED))) { diff --git a/common/content/quickmarks.js b/common/content/quickmarks.js index ed0a8e4c..31ec693a 100644 --- a/common/content/quickmarks.js +++ b/common/content/quickmarks.js @@ -9,7 +9,7 @@ * @instance quickmarks */ const QuickMarks = Module("quickmarks", { - requires: ["storage"], + requires: ["config", "storage"], init: function () { this._qmarks = storage.newMap("quickmarks", { store: true }); diff --git a/common/content/style.js b/common/content/style.js index d6374a15..ba6ee58f 100644 --- a/common/content/style.js +++ b/common/content/style.js @@ -557,7 +557,7 @@ function Styles(name, store) { } Module("styles", { - requires: ["liberator", "storage", "util"], + requires: ["config", "liberator", "storage", "util"], init: function () { let (array = util.Array) { @@ -707,7 +707,7 @@ Module("styles", { }); Module("highlight", { - requires: ["styles"], + requires: ["config", "styles"], init: function () { const self = storage.newObject("highlight", Highlights, { store: false }); diff --git a/common/content/tabs.js b/common/content/tabs.js index 5e37959f..d8a349a5 100644 --- a/common/content/tabs.js +++ b/common/content/tabs.js @@ -12,6 +12,8 @@ * @instance tabs */ const Tabs = Module("tabs", { + requires: ["config"], + init: function () { this._alternates = [getBrowser().mCurrentTab, null]; diff --git a/muttator/content/config.js b/muttator/content/config.js index ff31088f..557aa581 100644 --- a/muttator/content/config.js +++ b/muttator/content/config.js @@ -3,7 +3,12 @@ // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. -const config = { //{{{ +const config = Module("config", ConfigBase, { + init: function () { + // don't wait too long when selecting new messages + // GetThreadTree()._selectDelay = 300; // TODO: make configurable + }, + /*** required options, no checks done if they really exist, so be careful ***/ name: "Muttator", hostApplication: "Thunderbird", // TODO: can this be found out otherwise? gBrandBundle.getString("brandShortName"); @@ -146,20 +151,21 @@ const config = { //{{{ get scripts() this.isComposeWindow() ? ["compose/compose.js"] : [ "addressbook.js", "mail.js", + "tabs.js", ], // to allow Vim to :set ft=mail automatically tempFile: "mutt-ator-mail", - init: function () { - // don't wait too long when selecting new messages - // GetThreadTree()._selectDelay = 300; // TODO: make configurable - +}, { +}, { + commands: function () { commands.add(["pref[erences]", "prefs"], "Show " + config.hostApplication + " preferences", function () { window.openOptionsDialog(); }, { argCount: "0" }); - + }, + optons: function () { // FIXME: comment obviously incorrect // 0: never automatically edit externally // 1: automatically edit externally when message window is shown the first time @@ -179,9 +185,7 @@ const config = { //{{{ }, getter: function () MailOfflineMgr.isOnline() }); - - //}}} - } -}; //}}} + }, +}) // vim: set fdm=marker sw=4 ts=4 et: diff --git a/muttator/content/mail.js b/muttator/content/mail.js index 416b95d4..c6a6d84f 100644 --- a/muttator/content/mail.js +++ b/muttator/content/mail.js @@ -479,7 +479,7 @@ const Mail = Module("mail", { bang: true, }); }, - completions: function () { + completion: function () { completion.mailFolder = function mailFolder(context) { let folders = mail.getFolders(context.filter); context.anchored = false; diff --git a/vimperator/content/config.js b/vimperator/content/config.js index 10a3046f..21fe014d 100644 --- a/vimperator/content/config.js +++ b/vimperator/content/config.js @@ -3,8 +3,10 @@ // This work is licensed for reuse under an MIT license. Details are // given in the LICENSE.txt file included with this file. +const Config = Module("config", ConfigBase, { + init: function () { + }, -const config = { //{{{ /*** required options, no checks done if they really exist, so be careful ***/ name: "Vimperator", hostApplication: "Firefox", @@ -97,15 +99,7 @@ const config = { //{{{ hasTabbrowser: true, - get ignoreKeys() { - delete this.ignoreKeys; - return this.ignoreKeys = { - "": modes.NORMAL | modes.INSERT, - "": modes.NORMAL | modes.INSERT, - "": modes.NORMAL | modes.INSERT, - "": modes.NORMAL | modes.INSERT - }; - }, + ignoreKeys: {}, scripts: [ "browser.js", @@ -126,8 +120,9 @@ const config = { //{{{ return prefix + ".tmp"; }, - - init: function () { +}, { +}, { + commands: function () { commands.add(["winon[ly]"], "Close all other windows", function () { @@ -227,28 +222,8 @@ const config = { //{{{ literal: 0, privateData: true }); - - /////////////////////////////////////////////////////////////////////////////}}} - ////////////////////// OPTIONS ///////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ - - options.add(["online"], - "Set the 'work offline' option", - "boolean", true, - { - setter: function (value) { - const ioService = services.get("io"); - if (ioService.offline == value) - BrowserOffline.toggleOfflineStatus(); - return value; - }, - getter: function () !services.get("io").offline - }); - - /////////////////////////////////////////////////////////////////////////////}}} - ////////////////////// COMPLETIONS ///////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ - + }, + completion: function () { var searchRunning = false; // only until Firefox fixes https://bugzilla.mozilla.org/show_bug.cgi?id=510589 completion.location = function location(context) { if (!services.get("autoCompleteSearch")) @@ -292,9 +267,29 @@ const config = { //{{{ completion.addUrlCompleter("l", "Firefox location bar entries (bookmarks and history sorted in an intelligent way)", completion.location); - - //}}} - } -}; //}}} + }, + modes: function () { + this.ignoreKeys = { + "": modes.NORMAL | modes.INSERT, + "": modes.NORMAL | modes.INSERT, + "": modes.NORMAL | modes.INSERT, + "": modes.NORMAL | modes.INSERT + }; + }, + options: function () { + options.add(["online"], + "Set the 'work offline' option", + "boolean", true, + { + setter: function (value) { + const ioService = services.get("io"); + if (ioService.offline == value) + BrowserOffline.toggleOfflineStatus(); + return value; + }, + getter: function () !services.get("io").offline + }); + }, +}); // vim: set fdm=marker sw=4 ts=4 et: diff --git a/xulmus/content/config.js b/xulmus/content/config.js index c743ab93..2733e8b3 100644 --- a/xulmus/content/config.js +++ b/xulmus/content/config.js @@ -6,7 +6,18 @@ Components.utils.import("resource://gre/modules/utils.js"); // XXX -const config = { //{{{ +const config = Module("config", { + init: function () { + // TODO: mention this to SB devs, they seem keen to provide these + // functions to make porting from FF as simple as possible. + window.toJavaScriptConsole = function () { + toOpenWindowByType("global:console", "chrome://global/content/console.xul"); + }; + + window.BrowserStop = function () { + SBGetBrowser().mCurrentBrowser.stop(); + }; + }, /*** required options, no checks done if they really exist, so be careful ***/ name: "Xulmus", hostApplication: "Songbird", @@ -158,98 +169,69 @@ const config = { //{{{ stop: function (tab) { SBGetBrowser().mCurrentBrowser.stop(); }, +}, { - init: function () { - // Adding a mode for Player - //modes.addMode("PLAYER"); // Player mode for songbird + // TODO: support 'nrformats'? -> probably not worth it --mst + incrementURL: function (count) { + let matches = buffer.URL.match(/(.*?)(\d+)(\D*)$/); + if (!matches) + return void liberator.beep(); - // TODO: support 'nrformats'? -> probably not worth it --mst - function incrementURL(count) { - let matches = buffer.URL.match(/(.*?)(\d+)(\D*)$/); - if (!matches) - return void liberator.beep(); - - let [, pre, number, post] = matches; - let newNumber = parseInt(number, 10) + count; - let newNumberStr = String(newNumber > 0 ? newNumber : 0); - if (number.match(/^0/)) { // add 0009 should become 0010 - while (newNumberStr.length < number.length) - newNumberStr = "0" + newNumberStr; - } - - liberator.open(pre + newNumberStr + post); + let [, pre, number, post] = matches; + let newNumber = parseInt(number, 10) + count; + let newNumberStr = String(newNumber > 0 ? newNumber : 0); + if (number.match(/^0/)) { // add 0009 should become 0010 + while (newNumberStr.length < number.length) + newNumberStr = "0" + newNumberStr; } - function showServicePane(value) { - const key = "splitter.servicepane_splitter.was_collapsed"; - gServicePane.open = value; - SBDataSetBoolValue(key, gServicePane.open); + liberator.open(pre + newNumberStr + post); + }, + + showServicePane: function (value) { + const key = "splitter.servicepane_splitter.was_collapsed"; + gServicePane.open = value; + SBDataSetBoolValue(key, gServicePane.open); + }, + + openDisplayPane: function (id) { + if (id == "servicepane") + this.showServicePane(true); + else { + let pane = document.getElementById(id); + let manager = Cc['@songbirdnest.com/Songbird/DisplayPane/Manager;1'].getService(Ci.sbIDisplayPaneManager); + let paneinfo = manager.getPaneInfo(pane._lastURL.stringValue); + + if (!paneinfo) + paneinfo = manager.defaultPaneInfo; + + pane.loadContent(paneinfo); } + }, - function openDisplayPane(id) { - if (id == "servicepane") - showServicePane(true); - else { - let pane = document.getElementById(id); - let manager = Cc['@songbirdnest.com/Songbird/DisplayPane/Manager;1'].getService(Ci.sbIDisplayPaneManager); - let paneinfo = manager.getPaneInfo(pane._lastURL.stringValue); - - if (!paneinfo) - paneinfo = manager.defaultPaneInfo; - - pane.loadContent(paneinfo); - } - } - - function closeDisplayPane(id) { - if (id == "servicepane") - showServicePane(false); - else - document.getElementById(id).hide(); - } - - // FIXME: best way to format these args? Hyphenated? One word like :dialog? - let displayPanes = { - "service pane left": "servicepane", - "content pane bottom": "displaypane_contentpane_bottom", - "service pane bottom": "displaypane_servicepane_bottom", - "right sidebar": "displaypane_right_sidebar" - }; - - completion.displayPane = function (context) { - context.title = ["Display Pane"]; - context.completions = displayPanes; // FIXME: useful description etc - }; - - //////////////////////////////////////////////////////////////////////////////// - ////////////////////// STYLES ////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ - - let img = Image(); - img.src = "chrome://xulmus/content/logo.png"; - img.onload = function () { - styles.addSheet(true, "logo", "chrome://liberator/locale/*", - ".xulmus-logo {" + <> - display: inline-block; - background: url({img.src}); - width: {img.width}px; - height: {img.height}px; - + "}", - true); - delete img; - }; - - /////////////////////////////////////////////////////////////////////////////}}} - ////////////////////// COMMANDS //////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ + closeDisplayPane: function (id) { + if (id == "servicepane") + this.showServicePane(false); + else + document.getElementById(id).hide(); + }, + // FIXME: best way to format these args? Hyphenated? One word like :dialog? + displayPanes: { + "service pane left": "servicepane", + "content pane bottom": "displaypane_contentpane_bottom", + "service pane bottom": "displaypane_servicepane_bottom", + "right sidebar": "displaypane_right_sidebar" + } +}, { + commands: function () { commands.add(["dpcl[ose]"], "Close a display pane", function (args) { let arg = args.literalArg; - if (arg in displayPanes) - closeDisplayPane(displayPanes[arg]); + if (arg in Config.displayPanes) + Config.closeDisplayPane(Config.displayPanes[arg]); else liberator.echoerr("E475: Invalid argument: " + arg); @@ -266,8 +248,8 @@ const config = { //{{{ function (args) { let arg = args.literalArg; - if (arg in displayPanes) - openDisplayPane(displayPanes[arg]); + if (arg in Config.displayPanes) + Config.openDisplayPane(Config.displayPanes[arg]); // TODO: focus when we have better key handling of these extended modes else liberator.echoerr("E475: Invalid argument: " + arg); @@ -293,11 +275,14 @@ const config = { //{{{ argCount: "0", bang: true }); - - /////////////////////////////////////////////////////////////////////////////}}} - ////////////////////// OPTIONS ///////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ - + }, + completion: function () { + completion.displayPane = function (context) { + context.title = ["Display Pane"]; + context.completions = Config.displayPanes; // FIXME: useful description etc + }; + }, + options: function () { // TODO: SB doesn't explicitly support an offline mode. Should we? --djk options.add(["online"], "Set the 'work offline' option", @@ -311,23 +296,7 @@ const config = { //{{{ }, getter: function () !services.get("io").offline }); - - /////////////////////////////////////////////////////////////////////////////}}} - ////////////////////// COMPLETIONS ///////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////{{{ - - //}}} - - // TODO: mention this to SB devs, they seem keen to provide these - // functions to make porting from FF as simple as possible. - window.toJavaScriptConsole = function () { - toOpenWindowByType("global:console", "chrome://global/content/console.xul"); - }; - - window.BrowserStop = function () { - SBGetBrowser().mCurrentBrowser.stop(); - }; } -}; //}}} +}); // vim: set fdm=marker sw=4 ts=4 et: diff --git a/xulmus/content/player.js b/xulmus/content/player.js index f3ccdb7f..a896884e 100644 --- a/xulmus/content/player.js +++ b/xulmus/content/player.js @@ -560,7 +560,7 @@ const Player = Module("player", { }, { argCount: "1" }); }, - completions: function () { + completion: function () { completion.song = function song(context, args) { // TODO: useful descriptions? function map(list) list.map(function (i) [i, ""]);