diff --git a/common/content/buffer.js b/common/content/buffer.js index 594854cb..d773b842 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -745,15 +745,14 @@ function Buffer() //{{{ // get file size const ACCESS_READ = Ci.nsICache.ACCESS_READ; - const cacheService = Cc["@mozilla.org/network/cache-service;1"].getService(Ci.nsICacheService); let cacheKey = doc.location.toString().replace(/#.*$/, ""); for (let proto in util.Array.iterator(["HTTP", "FTP"])) { try { - var cacheEntryDescriptor = cacheService.createSession(proto, 0, true) - .openCacheEntry(cacheKey, ACCESS_READ, false); + var cacheEntryDescriptor = service["cache"].createSession(proto, 0, true) + .openCacheEntry(cacheKey, ACCESS_READ, false); break; } catch (e) {} diff --git a/common/content/completion.js b/common/content/completion.js index 24a20e53..fade644a 100644 --- a/common/content/completion.js +++ b/common/content/completion.js @@ -675,17 +675,10 @@ function Completion() //{{{ ////////////////////// PRIVATE SECTION ///////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ - try - { - var completionService = Cc["@mozilla.org/browser/global-history;2"].getService(Ci.nsIAutoCompleteSearch); - } - catch (e) {} - const EVAL_TMP = "__liberator_eval_tmp"; function Javascript() { - let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); const OFFSET = 0, CHAR = 1, STATEMENTS = 2, DOTS = 3, FULL_STATEMENTS = 4, COMMA = 5, FUNCTIONS = 6; let stack = []; let functions = []; @@ -1558,7 +1551,7 @@ function Completion() //{{{ location: function location(context) { - if (!completionService) + if (!service["autoCompleteSearch"]) return context.anchored = false; context.title = ["Smart Completions"]; @@ -1574,8 +1567,8 @@ function Completion() //{{{ for (i in util.range(0, result.matchCount)) ]; }); - completionService.stopSearch(); - completionService.startSearch(context.filter, "", context.result, { + service["autoCompleteSearch"].stopSearch(); + service["autoCompleteSearch"].startSearch(context.filter, "", context.result, { onSearchResult: function onSearchResult(search, result) { context.result = result; @@ -1655,11 +1648,10 @@ function Completion() //{{{ preference: function preference(context) { - let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); context.anchored = false; context.title = ["Firefox Preference", "Value"]; context.keys = { text: function (item) item, description: function (item) options.getPref(item) }; - context.completions = prefs.getChildList("", { value: 0 }); + context.completions = service["prefs"].getChildList("", { value: 0 }); }, search: function search(context, noSuggest) @@ -1706,12 +1698,11 @@ function Completion() //{{{ if (!context.filter) return; - let ss = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService); let engineList = (engineAliases || options["suggestengines"] || "google").split(","); let completions = []; engineList.forEach(function (name) { - let engine = ss.getEngineByAlias(name); + let engine = service["browserSearch"].getEngineByAlias(name); if (!engine) return; let [,word] = /^\s*(\S+)/.exec(context.filter) || []; @@ -1734,9 +1725,7 @@ function Completion() //{{{ context.title = ["Shell Command", "Path"]; context.generate = function () { - const environmentService = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); - - let dirNames = environmentService.get("PATH").split(RegExp(liberator.has("Win32") ? ";" : ":")); + let dirNames = service["environment"].get("PATH").split(RegExp(liberator.has("Win32") ? ";" : ":")); let commands = []; for (let [,dirName] in Iterator(dirNames)) diff --git a/common/content/events.js b/common/content/events.js index 40128b8c..ef0d429c 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -1549,10 +1549,9 @@ function Events() //{{{ // XXX: function may later be needed to detect a canceled synchronous openURL() onStateChange: function (webProgress, request, flags, status) { - const nsIWebProgressListener = Ci.nsIWebProgressListener; // STATE_IS_DOCUMENT | STATE_IS_WINDOW is important, because we also // receive statechange events for loading images and other parts of the web page - if (flags & (nsIWebProgressListener.STATE_IS_DOCUMENT | nsIWebProgressListener.STATE_IS_WINDOW)) + if (flags & (Ci.nsIWebProgressListener.STATE_IS_DOCUMENT | Ci.nsIWebProgressListener.STATE_IS_WINDOW)) { // This fires when the load event is initiated // only thrown for the current tab, not when another tab changes @@ -1581,12 +1580,11 @@ function Events() //{{{ // for notifying the user about secure web pages onSecurityChange: function (webProgress, aRequest, aState) { - const nsIWebProgressListener = Ci.nsIWebProgressListener; - if (aState & nsIWebProgressListener.STATE_IS_INSECURE) + if (aState & Ci.nsIWebProgressListener.STATE_IS_INSECURE) statusline.setClass("insecure"); - else if (aState & nsIWebProgressListener.STATE_IS_BROKEN) + else if (aState & Ci.nsIWebProgressListener.STATE_IS_BROKEN) statusline.setClass("broken"); - else if (aState & nsIWebProgressListener.STATE_IS_SECURE) + else if (aState & Ci.nsIWebProgressListener.STATE_IS_SECURE) statusline.setClass("secure"); }, onStatusChange: function (webProgress, request, status, message) @@ -1646,9 +1644,8 @@ function Events() //{{{ prefObserver: { register: function () { - const prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService); - this._branch = prefService.getBranch(""); // better way to monitor all changes? - this._branch.QueryInterface(Ci.nsIPrefBranch2); + this._branch = service["pref"].getBranch("") // better way to monitor all changes? + .QueryInterface(Ci.nsIPrefBranch2); this._branch.addObserver("", this, false); }, diff --git a/common/content/find.js b/common/content/find.js index 72c77388..09f02a43 100644 --- a/common/content/find.js +++ b/common/content/find.js @@ -138,9 +138,7 @@ function Search() //{{{ var highlightObj = { search: function (aWord, matchCase) { - var finder = Cc["@mozilla.org/embedcomp/rangefind;1"] - .createInstance() - .QueryInterface(Ci.nsIFind); + var finder = service.getFind(); if (matchCase !== undefined) finder.caseSensitive = matchCase; diff --git a/common/content/io.js b/common/content/io.js index 227c5568..de7eb73e 100644 --- a/common/content/io.js +++ b/common/content/io.js @@ -66,12 +66,9 @@ function IO() //{{{ const WINDOWS = liberator.has("Win32"); const EXTENSION_NAME = config.name.toLowerCase(); // "vimperator" or "muttator" - const ioService = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService); - const environmentService = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); - const directoryService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); const downloadManager = Cc["@mozilla.org/download-manager;1"].createInstance(Ci.nsIDownloadManager); - var processDir = directoryService.get("CurWorkD", Ci.nsIFile); + var processDir = service["directory"].get("CurWorkD", Ci.nsIFile); var cwd = processDir; var oldcwd = null; @@ -79,8 +76,7 @@ function IO() //{{{ var scriptNames = []; // default option values - var cdpath = "," + (environmentService.get("CDPATH").replace(/[:;]/g, ",") || ","); - var runtimepath = "~/" + (WINDOWS ? "" : ".") + EXTENSION_NAME; + var cdpath = "," + (service["environment"].get("CDPATH").replace(/[:;]/g, ",") || ","); var shell, shellcmdflag; if (WINDOWS) @@ -92,7 +88,7 @@ function IO() //{{{ } else { - shell = environmentService.get("SHELL") || "sh"; + shell = service["environment"].get("SHELL") || "sh"; shellcmdflag = "-c"; } @@ -120,7 +116,7 @@ function IO() //{{{ let path = ioManager.getFile(head); try { - path.appendRelativePath(ioManager.expandPath(tail)); // FIXME: should only expand env vars and normalise path separators + path.appendRelativePath(ioManager.expandPath(tail, true)); // FIXME: should only expand env vars and normalise path separators if (path.exists() && path.normalize) path.normalize(); } @@ -135,7 +131,7 @@ function IO() //{{{ { try { - Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile).initWithPath(path); + service.getFile().initWithPath(path); return true; } catch (e) @@ -179,7 +175,7 @@ function IO() //{{{ options.add(["runtimepath", "rtp"], "List of directories searched for runtime files", - "stringlist", runtimepath, + "stringlist", IO.runtimePath, { setter: function (value) expandPathList(value) }); options.add(["shell", "sh"], @@ -410,46 +406,7 @@ function IO() //{{{ pathSeparator: WINDOWS ? "\\" : "/", - expandPath: function (path) - { - // TODO: proper pathname separator translation like Vim - this should be done elsewhere - if (WINDOWS) - path = path.replace("/", "\\", "g"); - - // expand any $ENV vars - this is naive but so is Vim and we like to be compatible - // TODO: Vim does not expand variables set to an empty string (and documents it). - // Kris reckons we shouldn't replicate this 'bug'. --djk - // TODO: should we be doing this for all paths? - function expand(path) path.replace( - !WINDOWS ? /\$(\w+)\b|\${(\w+)}/g - : /\$(\w+)\b|\${(\w+)}|%(\w+)%/g, - function (m, n1, n2, n3) environmentService.get(n1 || n2 || n3) || m - ); - path = expand(path); - - // expand ~ - if ((WINDOWS ? /^~(?:$|\\)/ : /^~(?:$|\/)/).test(path)) - { - // Try $(VIMPERATOR|MUTTATOR)_HOME || $HOME first, on all systems - let home = environmentService.get(config.name.toUpperCase() + "_HOME") || - environmentService.get("HOME"); - - // Windows has its own ideosynchratic $HOME variables. - if (!home && WINDOWS) - home = environmentService.get("USERPROFILE") || - environmentService.get("HOMEDRIVE") + environmentService.get("HOMEPATH"); - - path = home + path.substr(1); - } - - // TODO: Vim expands paths twice, once before checking for ~, once - // after, but doesn't document it. Is this just a bug? --Kris - path = expand(path); - - // FIXME: Should we be doing this here? I think it should be done - // by the arg parser or nowhere. --Kris - return path.replace("\\ ", " ", "g"); - }, + expandPath: IO.expandPath, // TODO: there seems to be no way, short of a new component, to change // Firefox's CWD - see // https://bugzilla.mozilla.org/show_bug.cgi?id=280953 @@ -522,7 +479,7 @@ function IO() //{{{ // also expands relative paths getFile: function (path, noCheckPWD) { - let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); + let file = service.getFile(); if (/file:\/\//.test(path)) { @@ -563,7 +520,7 @@ function IO() //{{{ break; } - let file = directoryService.get("TmpD", Ci.nsIFile); + let file = service["directory"].get("TmpD", Ci.nsIFile); file.append(tmpName); file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600); @@ -669,7 +626,7 @@ function IO() //{{{ } else { - let dirs = environmentService.get("PATH").split(WINDOWS ? ";" : ":"); + let dirs = service["environment"].get("PATH").split(WINDOWS ? ";" : ":"); // Windows tries the cwd first TODO: desirable? if (WINDOWS) dirs = [io.getCurrentDirectory().path].concat(dirs); @@ -687,7 +644,7 @@ lookup: // automatically try to add the executable path extensions on windows if (WINDOWS) { - let extensions = environmentService.get("PATHEXT").split(";"); + let extensions = service["environment"].get("PATHEXT").split(";"); for (let [,extension] in Iterator(extensions)) { file = joinPaths(dir, program + extension); @@ -706,7 +663,7 @@ lookup: return -1; } - let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); + let process = service.getProcess(); process.init(file); process.run(blocking, args, args.length); @@ -820,7 +777,7 @@ lookup: liberator.echomsg("sourcing " + filename.quote(), 2); let str = ioManager.readFile(file); - let uri = ioService.newFileURI(file); + let uri = service["io"].newFileURI(file); // handle pure javascript files specially if (/\.js$/.test(filename)) @@ -964,4 +921,48 @@ lookup: }; //}}} +IO.__defineGetter__("runtimePath", function () service["environment"].get(config.name.toUpperCase() + "_RUNTIME") || + "~/" + (liberator.has("Win32") ? "" : ".") + config.name.toLowerCase()); + +IO.expandPath = function (path, relative) +{ + // TODO: proper pathname separator translation like Vim - this should be done elsewhere + const WINDOWS = liberator.has("Win32"); + if (WINDOWS) + path = path.replace("/", "\\", "g"); + + // expand any $ENV vars - this is naive but so is Vim and we like to be compatible + // TODO: Vim does not expand variables set to an empty string (and documents it). + // Kris reckons we shouldn't replicate this 'bug'. --djk + // TODO: should we be doing this for all paths? + function expand(path) path.replace( + !WINDOWS ? /\$(\w+)\b|\${(\w+)}/g + : /\$(\w+)\b|\${(\w+)}|%(\w+)%/g, + function (m, n1, n2, n3) service["environment"].get(n1 || n2 || n3) || m + ); + path = expand(path); + + // expand ~ + if (!relative && (WINDOWS ? /^~(?:$|\\)/ : /^~(?:$|\/)/).test(path)) + { + // Try $HOME first, on all systems + let home = service["environment"].get("HOME"); + + // Windows has its own ideosyncratic $HOME variables. + if (!home && WINDOWS) + home = service["environment"].get("USERPROFILE") || + service["environment"].get("HOMEDRIVE") + service["environment"].get("HOMEPATH"); + + path = home + path.substr(1); + } + + // TODO: Vim expands paths twice, once before checking for ~, once + // after, but doesn't document it. Is this just a bug? --Kris + path = expand(path); + + // FIXME: Should we be doing this here? I think it should be done + // by the arg parser or nowhere. --Kris + return path.replace("\\ ", " ", "g"); +}; + // vim: set fdm=marker sw=4 ts=4 et: diff --git a/common/content/liberator-overlay.js b/common/content/liberator-overlay.js index 9b0df22b..eb60e48f 100644 --- a/common/content/liberator-overlay.js +++ b/common/content/liberator-overlay.js @@ -31,7 +31,8 @@ let prefix = [BASE]; - ["liberator.js", + ["service.js", + "liberator.js", "config.js", "util.js", "style.js", diff --git a/common/content/liberator.js b/common/content/liberator.js index 47753817..eb9d6574 100644 --- a/common/content/liberator.js +++ b/common/content/liberator.js @@ -51,7 +51,6 @@ const liberator = (function () //{{{ ////////////////////// PRIVATE SECTION ///////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ - const threadManager = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager); function Runnable(self, func, args) { this.self = self; @@ -685,18 +684,18 @@ const liberator = (function () //{{{ return false; // so you can do: if (...) return liberator.beep(); }, - newThread: function () threadManager.newThread(0), + newThread: function () service["threadManager"].newThread(0), callAsync: function (thread, self, func) { - hread = thread || threadManager.newThread(0); + hread = thread || service["threadManager"].newThread(0); thread.dispatch(new Runnable(self, func, Array.slice(arguments, 2)), thread.DISPATCH_NORMAL); }, // be sure to call GUI related methods like alert() or dump() ONLY in the main thread callFunctionInThread: function (thread, func) { - thread = thread || threadManager.newThread(0); + thread = thread || service["threadManager"].newThread(0); // DISPATCH_SYNC is necessary, otherwise strange things will happen thread.dispatch(new Runnable(null, func, Array.slice(arguments, 2)), thread.DISPATCH_SYNC); @@ -768,8 +767,7 @@ const liberator = (function () //{{{ loadScript: function (uri, context) { - let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader); - loader.loadSubScript(uri, context); + service["subscriptLoader"].loadSubScript(uri, context); }, eval: function (str, context) @@ -903,8 +901,7 @@ const liberator = (function () //{{{ // if clearFocusedElement, also blur a focused link focusContent: function (clearFocusedElement) { - let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher); - if (window != ww.activeWindow) + if (window != service["windowWatcher"].activeWindow) return; let elem = config.mainWidget || window.content; @@ -937,8 +934,7 @@ const liberator = (function () //{{{ hasExtension: function (name) { - let manager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager); - let extensions = manager.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION, {}); + let extensions = service["extensionManager"].getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION, {}); return extensions.some(function (e) e.name == name); }, @@ -1062,8 +1058,7 @@ const liberator = (function () //{{{ if (typeof msg == "object") msg = util.objectToString(msg, false); - const consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService); - consoleService.logStringMessage(config.name.toLowerCase() + ": " + msg); + service["console"].logStringMessage(config.name.toLowerCase() + ": " + msg); }, // open one or more URLs @@ -1100,7 +1095,6 @@ const liberator = (function () //{{{ { let url = Array.concat(urls)[0]; let postdata = Array.concat(urls)[1]; - let whichwindow = window; // decide where to load the first url switch (where) @@ -1121,10 +1115,9 @@ const liberator = (function () //{{{ break; case liberator.NEW_WINDOW: - const wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); window.open(); - whichwindow = wm.getMostRecentWindow("navigator:browser"); - whichwindow.loadURI(url, null, postdata); + service["windowMediator"].getMostRecentWindow("navigator:browser") + .loadURI(url, null, postdata); break; default: @@ -1164,11 +1157,8 @@ const liberator = (function () //{{{ else options.setPref("browser.startup.page", 1); // start with default homepage session - const nsIAppStartup = Ci.nsIAppStartup; if (force) - Cc["@mozilla.org/toolkit/app-startup;1"] - .getService(nsIAppStartup) - .quit(nsIAppStartup.eForceQuit); + service["appStartup"].quit(Ci.nsIAppStartup.eForceQuit); else window.goQuitApplication(); }, @@ -1196,31 +1186,26 @@ const liberator = (function () //{{{ restart: function () { - const nsIAppStartup = Ci.nsIAppStartup; - // notify all windows that an application quit has been requested. - const os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); - const cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); - os.notifyObservers(cancelQuit, "quit-application-requested", null); + var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); + service["observer"].notifyObservers(cancelQuit, "quit-application-requested", null); // something aborted the quit process. if (cancelQuit.data) return; // notify all windows that an application quit has been granted. - os.notifyObservers(null, "quit-application-granted", null); + service["observer"].notifyObservers(null, "quit-application-granted", null); // enumerate all windows and call shutdown handlers - const wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); - let windows = wm.getEnumerator(null); + let windows = service["windowMediator"].getEnumerator(null); while (windows.hasMoreElements()) { let win = windows.getNext(); if (("tryToClose" in win) && !win.tryToClose()) return; } - Cc["@mozilla.org/toolkit/app-startup;1"].getService(nsIAppStartup) - .quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit); + service["appStartup"].quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit); }, // TODO: move to {muttator,vimperator,...}.js @@ -1245,6 +1230,19 @@ const liberator = (function () //{{{ config.dialogs = config.dialogs || []; config.helpFiles = config.helpFiles || []; + try + { + let infoPath = service.getFile(); + infoPath.initWithPath(IO.expandPath(IO.runtimePath.replace(/,.*/, ""))); + infoPath.append("info"); + infoPath.append(service["profile"].selectedProfile.name); + storage.infoPath = infoPath; + } + catch (e) + { + liberator.reportError(e); + } + liberator.triggerObserver("load"); // commands must always be the first module to be initialized @@ -1286,18 +1284,24 @@ const liberator = (function () //{{{ // make sourcing asynchronous, otherwise commands that open new tabs won't work setTimeout(function () { - let rcFile = io.getRCFile("~"); - - if (rcFile) - io.source(rcFile.path, true); + let init = service["environment"].get(config.name.toUpperCase() + "_INIT"); + if (init) + liberator.execute(init); else - liberator.log("No user RC file found", 3); + { + let rcFile = io.getRCFile("~"); + + if (rcFile) + io.source(rcFile.path, true); + else + liberator.log("No user RC file found", 3); + } if (options["exrc"]) { - let localRcFile = io.getRCFile(io.getCurrentDirectory().path); - if (localRcFile) - io.source(localRcFile.path, true); + let localRCFile = io.getRCFile(io.getCurrentDirectory().path); + if (localRCFile) + io.source(localRCFile.path, true); } if (options["loadplugins"]) @@ -1337,7 +1341,7 @@ const liberator = (function () //{{{ sleep: function (delay) { - let mainThread = threadManager.mainThread; + let mainThread = service["threadManager"].mainThread; let end = Date.now() + delay; while (Date.now() < end) @@ -1347,8 +1351,8 @@ const liberator = (function () //{{{ callInMainThread: function (callback, self) { - let mainThread = threadManager.mainThread; - if (!threadManager.isMainThread) + let mainThread = service["threadManager"].mainThread; + if (!service["threadManager"].isMainThread) mainThread.dispatch({ run: callback.call(self) }, mainThread.DISPATCH_NORMAL); else callback.call(self); @@ -1356,7 +1360,7 @@ const liberator = (function () //{{{ threadYield: function (flush, interruptable) { - let mainThread = threadManager.mainThread; + let mainThread = service["threadManager"].mainThread; liberator.interrupted = false; do { @@ -1395,10 +1399,8 @@ const liberator = (function () //{{{ get windows() { - const wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); let windows = []; - let enumerator = wm.getEnumerator("navigator:browser"); - + let enumerator = service["windowMediator"].getEnumerator("navigator:browser"); while (enumerator.hasMoreElements()) windows.push(enumerator.getNext()); diff --git a/common/content/options.js b/common/content/options.js index 0a1008ff..dfccebed 100644 --- a/common/content/options.js +++ b/common/content/options.js @@ -306,7 +306,6 @@ function Options() //{{{ const SAVED = "liberator.saved."; - const prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); const optionHash = {}; const prefContexts = []; @@ -331,27 +330,27 @@ function Options() //{{{ prefContexts[prefContexts.length - 1][name] = val; } - let type = prefService.getPrefType(name); + let type = service["pref"].getPrefType(name); switch (typeof value) { case "string": - if (type == prefService.PREF_INVALID || type == prefService.PREF_STRING) - prefService.setCharPref(name, value); - else if (type == prefService.PREF_INT) + if (type == service["pref"].PREF_INVALID || type == service["prefBranch"].PREF_STRING) + service["pref"].setCharPref(name, value); + else if (type == service["pref"].PREF_INT) liberator.echoerr("E521: Number required after =: " + name + "=" + value); else liberator.echoerr("E474: Invalid argument: " + name + "=" + value); break; case "number": - if (type == prefService.PREF_INVALID || type == prefService.PREF_INT) - prefService.setIntPref(name, value); + if (type == service["pref"].PREF_INVALID || type == service["pref"].PREF_INT) + service["pref"].setIntPref(name, value); else liberator.echoerr("E474: Invalid argument: " + name + "=" + value); break; case "boolean": - if (type == prefService.PREF_INVALID || type == prefService.PREF_BOOL) - prefService.setBoolPref(name, value); - else if (type == prefService.PREF_INT) + if (type == service["pref"].PREF_INVALID || type == service["pref"].PREF_BOOL) + service["pref"].setBoolPref(name, value); + else if (type == service["pref"].PREF_INT) liberator.echoerr("E521: Number required after =: " + name + "=" + value); else liberator.echoerr("E474: Invalid argument: " + name + "=" + value); @@ -367,22 +366,22 @@ function Options() //{{{ if (forcedDefault != null) // this argument sets defaults for non-user settable options (like extensions.history.comp_history) defaultValue = forcedDefault; - let branch = defaultBranch ? prefService.getDefaultBranch("") : prefService; - let type = prefService.getPrefType(name); + let branch = defaultBranch ? service["pref"].getDefaultBranch("") : service["pref"]; + let type = service["pref"].getPrefType(name); try { switch (type) { - case prefService.PREF_STRING: + case service["pref"].PREF_STRING: let value = branch.getComplexValue(name, Ci.nsISupportsString).data; // try in case it's a localized string (will throw an exception if not) - if (!prefService.prefIsLocked(name) && !prefService.prefHasUserValue(name) && + if (!service["pref"].prefIsLocked(name) && !service["pref"].prefHasUserValue(name) && /^chrome:\/\/.+\/locale\/.+\.properties/.test(value)) value = branch.getComplexValue(name, Ci.nsIPrefLocalizedString).data; return value; - case prefService.PREF_INT: + case service["pref"].PREF_INT: return branch.getIntPref(name); - case prefService.PREF_BOOL: + case service["pref"].PREF_BOOL: return branch.getBoolPref(name); default: return defaultValue; @@ -787,9 +786,8 @@ function Options() //{{{ { completion.setFunctionCompleter(options.get, [function () ([o.name, o.description] for (o in options))]); completion.setFunctionCompleter([options.getPref, options.safeSetPref, options.setPref, options.resetPref, options.invertPref], - [function () Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch) - .getChildList("", { value: 0 }) - .map(function (pref) [pref, ""])]); + [function () service["pref"].getChildList("", { value: 0 }) + .map(function (pref) [pref, ""])]); }); return { @@ -890,12 +888,12 @@ function Options() //{{{ if (!filter) filter = ""; - let prefArray = prefService.getChildList("", { value: 0 }); + let prefArray = service["pref"].getChildList("", { value: 0 }); prefArray.sort(); let prefs = function () { for each (let pref in prefArray) { - let userValue = prefService.prefHasUserValue(pref); + let userValue = service["pref"].prefHasUserValue(pref); if (onlyNonDefault && !userValue || pref.indexOf(filter) == -1) continue; @@ -988,13 +986,13 @@ function Options() //{{{ resetPref: function (name) { - return prefService.clearUserPref(name); + return service["pref"].clearUserPref(name); }, // this works only for booleans invertPref: function (name) { - if (prefService.getPrefType(name) == prefService.PREF_BOOL) + if (service["pref"].getPrefType(name) == service["pref"].PREF_BOOL) this.setPref(name, !this.getPref(name)); else liberator.echoerr("E488: Trailing characters: " + name + "!"); diff --git a/common/content/service.js b/common/content/service.js new file mode 100644 index 00000000..084a72b5 --- /dev/null +++ b/common/content/service.js @@ -0,0 +1,35 @@ +/** @scope modules */ + +let (cc = function (class, iface, meth) { try { return Cc[class][meth || "getService"](iface) } catch (e) {} }) +{ + /** + * Cached XPCOM services and instances. + * + * @singleton + */ + const service = { + appStartup: cc("@mozilla.org/toolkit/app-startup;1", Ci.nsIAppStartup), + autoCompleteSearch: cc("@mozilla.org/browser/global-history;2", Ci.nsIAutoCompleteSearch), + browserSearch: cc("@mozilla.org/browser/search-service;1", Ci.nsIBrowserSearchService), + cache: cc("@mozilla.org/network/cache-service;1", Ci.nsICacheService), + console: cc("@mozilla.org/consoleservice;1", Ci.nsIConsoleService), + directory: cc("@mozilla.org/file/directory_service;1", Ci.nsIProperties), + environment: cc("@mozilla.org/process/environment;1", Ci.nsIEnvironment), + extensionManager: cc("@mozilla.org/extensions/manager;1", Ci.nsIExtensionManager), + io: cc("@mozilla.org/network/io-service;1", Ci.nsIIOService).QueryInterface(Ci.nsIIOService2), + json: cc("@mozilla.org/dom/json;1", Ci.nsIJSON, "createInstance"), + observer: cc("@mozilla.org/observer-service;1", Ci.nsIObserverService), + profile: cc("@mozilla.org/toolkit/profile-service;1", Ci.nsIToolkitProfileService), + pref: cc("@mozilla.org/preferences-service;1", Ci.nsIPrefService) + .QueryInterface(Ci.nsIPrefBranch).QueryInterface(Ci.nsIPrefBranch2), + sessionStore: cc("@mozilla.org/browser/sessionstore;1", Ci.nsISessionStore), + subscriptLoader: cc("@mozilla.org/moz/jssubscript-loader;1", Ci.mozIJSSubScriptLoader), + threadManager: cc("@mozilla.org/thread-manager;1", Ci.nsIThreadManager), + windowMediator: cc("@mozilla.org/appshell/window-mediator;1", Ci.nsIWindowMediator), + windowWatcher: cc("@mozilla.org/embedcomp/window-watcher;1", Ci.nsIWindowWatcher), + getFile: function () Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile), + getFind: function () Cc["@mozilla.org/embedcomp/rangefind;1"].createInstance(Ci.nsIFind), + getProcess: function () Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess) + }; +}; + diff --git a/common/content/style.js b/common/content/style.js index 6bdcf232..2459dbb4 100644 --- a/common/content/style.js +++ b/common/content/style.js @@ -248,8 +248,8 @@ function Styles(name, store, serial) const util = modules.util; const sleep = liberator.sleep; const storage = modules.storage; - const consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService); - const ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); + const consoleService = service["console"]; + const ios = service["io"]; const sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); const namespace = '@namespace html "' + XHTML + '";\n' + '@namespace xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";\n' + diff --git a/common/content/tabs.js b/common/content/tabs.js index 6436f8ea..64b47a02 100644 --- a/common/content/tabs.js +++ b/common/content/tabs.js @@ -99,13 +99,11 @@ function Tabs() //{{{ function copyTab(to, from) { - const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore); - if (!from) from = getBrowser().mTabContainer.selectedItem; - let tabState = ss.getTabState(from); - ss.setTabState(to, tabState); + let tabState = service["sessionStore"].getTabState(from); + service["sessionStore"].setTabState(to, tabState); } // hide tabs initially @@ -741,9 +739,7 @@ function Tabs() //{{{ get closedTabs() { - const json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); - const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore); - return json.decode(ss.getClosedTabData(window)); + return service["json"].decode(service["sessionStore"].getClosedTabData(window)); }, list: function (filter) @@ -846,8 +842,7 @@ function Tabs() //{{{ { if (bypassCache) { - const nsIWebNavigation = Ci.nsIWebNavigation; - const flags = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE; + const flags = Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE; getBrowser().getBrowserForTab(tab).reloadWithFlags(flags); } else @@ -971,8 +966,7 @@ function Tabs() //{{{ tab = getBrowser().mTabContainer.selectedItem; window.open(); - const wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); - let win = wm.getMostRecentWindow("navigator:browser"); + let win = service["windowMediator"].getMostRecentWindow("navigator:browser"); copyTab(win.getBrowser().mCurrentTab, tab); this.remove(tab, 1, false, 1); diff --git a/common/content/ui.js b/common/content/ui.js index 8eadbf3e..0ad27fd6 100644 --- a/common/content/ui.js +++ b/common/content/ui.js @@ -660,9 +660,8 @@ function CommandLine() //{{{ { completer: function completer(value) { - let ss = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService); - let engines = ss.getEngines({}) - .filter(function (engine) engine.supportsResponseType("application/x-suggestions+json")); + let engines = service["browserSearch"].getEngines({}) + .filter(function (engine) engine.supportsResponseType("application/x-suggestions+json")); return engines.map(function (engine) [engine.alias, engine.description]); }, diff --git a/common/content/util.js b/common/content/util.js index cf5bdcb3..411c3dd2 100644 --- a/common/content/util.js +++ b/common/content/util.js @@ -83,60 +83,6 @@ const util = { //{{{ } }, - // TODO: class could have better variable names/documentation - Timer: function Timer(minInterval, maxInterval, callback) - { - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - this.doneAt = 0; - this.latest = 0; - this.notify = function (aTimer) - { - timer.cancel(); - this.latest = 0; - /* minInterval is the time between the completion of the command and the next firing. */ - this.doneAt = Date.now() + minInterval; - - try - { - callback(this.arg); - } - finally - { - this.doneAt = Date.now() + minInterval; - } - }; - this.tell = function (arg) - { - if (arg !== undefined) - this.arg = arg; - - let now = Date.now(); - if (this.doneAt == -1) - timer.cancel(); - - let timeout = minInterval; - if (now > this.doneAt && this.doneAt > -1) - timeout = 0; - else if (this.latest) - timeout = Math.min(timeout, this.latest - now); - else - this.latest = now + maxInterval; - - timer.initWithCallback(this, Math.max(timeout, 0), timer.TYPE_ONE_SHOT); - this.doneAt = -1; - }; - this.reset = function () - { - timer.cancel(); - this.doneAt = 0; - }; - this.flush = function () - { - if (this.latest) - this.notify(); - }; - }, - cloneObject: function cloneObject(obj) { if (obj instanceof Array) diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm index 61ebf01e..22b89605 100644 --- a/common/modules/storage.jsm +++ b/common/modules/storage.jsm @@ -29,10 +29,14 @@ the terms of any one of the MPL, the GPL or the LGPL. var EXPORTED_SYMBOLS = ["storage", "Timer"]; +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; +const Cu = Components.utils; + function Timer(minInterval, maxInterval, callback) { - let timer = Components.classes["@mozilla.org/timer;1"] - .createInstance(Components.interfaces.nsITimer); + let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); this.doneAt = 0; this.latest = 0; this.notify = function (aTimer) @@ -75,7 +79,7 @@ function Timer(minInterval, maxInterval, callback) { timer.cancel(); this.doneAt = 0; - }; + } this.flush = function () { if (this.latest) @@ -83,43 +87,95 @@ function Timer(minInterval, maxInterval, callback) }; } -var prefService = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefService) +function getFile(name) +{ + let file = storage.infoPath.clone(); + file.append(name); + return file; +} + +function readFile(file) +{ + let fileStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); + let stream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream); + + try + { + fileStream.init(file, -1, 0, 0); + stream.init(fileStream, "UTF-8", 4096, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); // 4096 bytes buffering + + let hunks = []; + let res = {}; + while (stream.readString(4096, res) != 0) + hunks.push(res.value); + + stream.close(); + fileStream.close(); + + return hunks.join(""); + } + catch (e) {} +} + +function writeFile(file, data) +{ + if (!file.exists()) + file.create(file.NORMAL_FILE_TYPE, 0600); + + let fileStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); + let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream); + + fileStream.init(file, 0x20 | 0x08 | 0x02, 0600, 0); // PR_TRUNCATE | PR_CREATE | PR_WRITE + stream.init(fileStream, "UTF-8", 0, 0); + + stream.writeString(data); + + stream.close(); + fileStream.close(); +} + +var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); +var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService) .getBranch("extensions.liberator.datastore."); -var json = Components.classes["@mozilla.org/dom/json;1"] - .createInstance(Components.interfaces.nsIJSON); +var json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); function getCharPref(name) { try { - return prefService.getComplexValue(name, Components.interfaces.nsISupportsString).data; + return prefService.getComplexValue(name, Ci.nsISupportsString).data; } catch (e) {} } function setCharPref(name, value) { - var str = Components.classes['@mozilla.org/supports-string;1'] - .createInstance(Components.interfaces.nsISupportsString); + var str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString); str.data = value; - return prefService.setComplexValue(name, Components.interfaces.nsISupportsString, str); + return prefService.setComplexValue(name, Ci.nsISupportsString, str); } function loadPref(name, store, type) { if (store) var pref = getCharPref(name); + if (!pref && storage.infoPath) + var file = readFile(getFile(name)); + if (pref || file) + var result = json.decode(pref || file); if (pref) - var result = json.decode(pref); + { + prefService.clearUserPref(name); + savePref({ name: name, store: true, serial: pref }) + } if (result instanceof type) return result; } function savePref(obj) { - if (obj.store) - setCharPref(obj.name, obj.serial) + if (obj.store && storage.infoPath) + writeFile(getFile(obj.name), obj.serial); } var prototype = { @@ -259,7 +315,7 @@ var storage = { if (!(key in observers)) observers[key] = []; if (observers[key].indexOf(callback) == -1) - observers[key].push({ ref: ref && Components.utils.getWeakReference(ref), callback: callback }); + observers[key].push({ ref: ref && Cu.getWeakReference(ref), callback: callback }); }, removeObserver: function (key, callback) diff --git a/vimperator/NEWS b/vimperator/NEWS index f982feda..0e57b9d4 100644 --- a/vimperator/NEWS +++ b/vimperator/NEWS @@ -20,7 +20,10 @@ * IMPORTANT: renamed Startup and Quit autocmd events to VimperatorEnter and VimperatorLeave respectively * IMPORTANT: 'verbose' is now by default at 1, set to 0 to not show any status messages + * IMPORTANT: $VIMPERATOR_HOME is no longer used. + * Added ~/.vimperator/info/{profile}/, similar to viminfo + * added $VIMPERATOR_RUNTIME, $VIMPERATOR_INIT * :hardcopy now supports output redirection to a file on Unix and MacUnix * add ";f" extended hint mode to focus a frame * add "r", "l", and "b" to 'guioptions' to toggle the scrollbars. diff --git a/vimperator/content/bookmarks.js b/vimperator/content/bookmarks.js index c21e2ee8..12bf8276 100644 --- a/vimperator/content/bookmarks.js +++ b/vimperator/content/bookmarks.js @@ -59,8 +59,8 @@ function Bookmarks() //{{{ const historyService = PlacesUtils.history; const bookmarksService = PlacesUtils.bookmarks; const taggingService = PlacesUtils.tagging; - const searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService); - const ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); + const searchService = service.browserSearch; + const ioService = service.io; const faviconService = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService); const Bookmark = new Struct("url", "title", "icon", "keyword", "tags", "id"); @@ -561,7 +561,7 @@ function Bookmarks() //{{{ getSuggestions: function getSuggestions(engine, query, callback) { - let ss = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService); + let ss = service.browserSearch; const responseType = "application/x-suggestions+json"; let engine = ss.getEngineByAlias(engine); @@ -572,7 +572,7 @@ function Bookmarks() //{{{ function process(resp) { - const json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); + const json = service.json; let results = []; try { @@ -876,7 +876,7 @@ function History() //{{{ let items = completion.runCompleter("history", filter, maxItems); if (items.length) - return liberator.open([i[0] for each (i in items)], liberator.NEW_TAB); + return liberator.open(items.map(function (i) i.url), liberator.NEW_TAB); if (filter.length > 0) liberator.echoerr("E283: No history matching \"" + filter + "\""); diff --git a/vimperator/content/config.js b/vimperator/content/config.js index cc353a28..bfde7c86 100644 --- a/vimperator/content/config.js +++ b/vimperator/content/config.js @@ -418,16 +418,13 @@ const config = { //{{{ { setter: function (value) { - const ioService = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService2); - - ioService.offline = !value; - gPrefService.setBoolPref("browser.offline", ioService.offline); - + service.io.offline = !value; + gPrefService.setBoolPref("browser.offline", service.io.offline); return value; }, getter: function () { - return Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService2).offline; + return service.io.offline; } }); diff --git a/vimperator/locale/en-US/options.txt b/vimperator/locale/en-US/options.txt index 31487e54..16b93731 100644 --- a/vimperator/locale/en-US/options.txt +++ b/vimperator/locale/en-US/options.txt @@ -590,10 +590,11 @@ match being used. The patterns are case insensitive regular expressions. ____ +|$VIMPERATOR_RUNTIME| |\'rtp'| |\'runtimepath'| ||'runtimepath' 'rtp'|| stringlist ____ -(default: Unix, Mac: "\~/.vimperator", Windows: "\~/vimperator") +(default: \'$VIMPERATOR_RUNTIME' or Unix, Mac: "\~/.vimperator", Windows: "\~/vimperator") List of directories searched for runtime files: + macros/ + diff --git a/vimperator/locale/en-US/starting.txt b/vimperator/locale/en-US/starting.txt index 618820ba..e7b87b5b 100644 --- a/vimperator/locale/en-US/starting.txt +++ b/vimperator/locale/en-US/starting.txt @@ -5,20 +5,20 @@ be documented here. section:Initialization[initialization,startup] -At startup Vimperator sources a user RC file, containing Ex commands, and any -JavaScript files found in the plugin directory. The RC file may be named -[a].vimperatorrc[a] or [a]\_vimperatorrc[a]. The search order is: +At startup Vimperator can perform user initialization commands. When one of +the following is successfully located, it is executed, and no further +locations are tried. -* Unix and Mac: [a]\~/.vimperatorrc[a] then [a]\~/_vimperatorrc[a] -* Windows - [a]\~/_vimperatorrc[a] then [a]\~/.vimperatorrc[a] +|$VIMPERATOR_INIT| +1. _$VIMPERATOR_INIT_ - May contain a single ex command, usually + [c]:source {file}[c]. +2. [a]\~/_vimperatorrc[a] - Windows only. If this file exists, its contents + are executed. +3. [a]\~/.vimperatorrc[a] - If this file exists, its contents are executed. If 'exrc' is set then any RC file in the current directory is also sourced. -The plugin directory can be in any of the directories in 'runtimepath'. Using -the default value of 'runtimepath' this would be: - -* Unix and Mac - [a]\~/.vimperator/plugin[a] -* Windows - [a]\~/vimperator/plugin[a] +The plugin directory can be in any of the directories in 'runtimepath'. All directories in 'runtimepath' are searched for plugins and they are are all loaded. @@ -31,8 +31,6 @@ The user's \'$HOME'(~) directory is determined as follows: * Windows - if _%HOME%_ is set then this is used, otherwise _%USERPROFILE%_ or finally _%HOMEDRIVE%%HOMEPATH%_. -_$VIMPERATOR_HOME_ can be used to override the calculated _$HOME_ directory. - section:Saving{nbsp}settings[save-settings] |:mkv| |:mkvimperatorrc|