1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-01-03 22:24:11 +01:00

Do away with services.(get|create), and move the prefs module to its own file.

This commit is contained in:
Kris Maglione
2010-12-01 21:57:51 -05:00
parent 0bf9cfb0bc
commit 5d51fd491a
26 changed files with 540 additions and 516 deletions

View File

@@ -1,5 +1,5 @@
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2009 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2007-2010 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2010 by Kris Maglione <maglione.k@gmail.com>
//
// This work is licensed for reuse under an MIT license. Details are
@@ -10,7 +10,7 @@ try {
Components.utils.import("resource://dactyl/base.jsm");
defineModule("util", {
exports: ["FailedAssertion", "Math", "NS", "Prefs", "Util", "XHTML", "XUL", "prefs", "util"],
exports: ["FailedAssertion", "Math", "NS", "Util", "XHTML", "XUL", "util"],
require: ["services"],
use: ["highlight", "template"]
});
@@ -46,7 +46,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
},
// FIXME: Only works for Pentadactyl
get activeWindow() services.get("windowMediator").getMostRecentWindow("navigator:browser"),
get activeWindow() services.windowMediator.getMostRecentWindow("navigator:browser"),
dactyl: {
__noSuchMethod__: function (meth, args) {
let win = util.activeWindow;
@@ -69,9 +69,9 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
addObserver: function (obj) {
let observers = obj.observe;
function register(meth) {
services.get("observer")[meth](obj, "quit-application", true);
services.observer[meth](obj, "quit-application", true);
for (let target in keys(observers))
services.get("observer")[meth](obj, target, true);
services.observer[meth](obj, target, true);
}
Class.replaceProperty(obj, "observe",
function (subject, target, data) {
@@ -155,7 +155,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
*/
createURI: function createURI(str) {
try {
return services.get("urifixup").createFixupURI(str, services.get("urifixup").FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP);
return services.urifixup.createFixupURI(str, services.urifixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP);
}
catch (e) {
return null;
@@ -225,20 +225,20 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
}
let doc = (node.getRangeAt ? node.getRangeAt(0) : node).startContainer.ownerDocument;
let encoder = services.create("htmlEncoder");
let encoder = services.HtmlEncoder();
encoder.init(doc, "text/unicode", encoder.OutputRaw|encoder.OutputPreformatted);
if (node instanceof Ci.nsISelection)
encoder.setSelection(node);
else if (node instanceof Ci.nsIDOMRange)
encoder.setRange(node);
let str = services.create("string");
let str = services.String();
str.data = encoder.encodeToString();
if (html)
return str.data;
let [result, length] = [{}, {}];
services.create("htmlConverter").convert("text/html", str, str.data.length*2, "text/unicode", result, length);
services.HtmlConverter().convert("text/html", str, str.data.length*2, "text/unicode", result, length);
return result.value.QueryInterface(Ci.nsISupportsString).data;
},
@@ -424,7 +424,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
*
* @param {string} ver The required version.
*/
haveGecko: function (ver) services.get("versionCompare").compare(services.get("runtime").platformVersion, ver) >= 0,
haveGecko: function (ver) services.versionCompare.compare(services.runtime.platformVersion, ver) >= 0,
/**
* Sends a synchronous or asynchronous HTTP request to *url* and returns
@@ -438,7 +438,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
*/
httpGet: function httpGet(url, callback) {
try {
let xmlhttp = services.create("xmlhttp");
let xmlhttp = services.Xmlhttp();
xmlhttp.mozBackgroundRequest = true;
if (callback)
xmlhttp.onreadystatechange = function () {
@@ -490,7 +490,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
/** Dactyl's notion of the current operating system platform. */
OS: {
_arch: services.get("runtime").OS,
_arch: services.runtime.OS,
/**
* @property {string} The normalised name of the OS. This is one of
* "Windows", "Mac OS X" or "Unix".
@@ -564,7 +564,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
* @returns {nsIURI}
*/
// FIXME: createURI needed too?
newURI: function (uri, charset, base) services.get("io").newURI(uri, charset, base),
newURI: function (uri, charset, base) services.io.newURI(uri, charset, base),
/**
* Pretty print a JavaScript object. Use HTML markup to color certain items
@@ -873,7 +873,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
let base = host.replace(/.*\.(.+?\..+?)$/, "$1");
try {
base = services.get("tld").getBaseDomainFromHost(host);
base = services.tld.getBaseDomainFromHost(host);
}
catch (e) {}
@@ -915,7 +915,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
* @param {number} delay The time period for which to sleep in milliseconds.
*/
sleep: function (delay) {
let mainThread = services.get("threading").mainThread;
let mainThread = services.threading.mainThread;
let end = Date.now() + delay;
while (Date.now() < end)
@@ -994,7 +994,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
},
threadYield: function (flush, interruptable) {
let mainThread = services.get("threading").mainThread;
let mainThread = services.threading.mainThread;
/* FIXME */
util.interrupted = false;
do {
@@ -1067,332 +1067,6 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference])
Array: array
});
const Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), {
SAVED: "extensions.dactyl.saved.",
RESTORE: "extensions.dactyl.restore.",
init: function () {
this._prefContexts = [];
util.addObserver(this);
this._branch = services.get("pref").getBranch("").QueryInterface(Ci.nsIPrefBranch2);
this._branch.addObserver("", this, false);
this._observers = {};
this.restore();
},
observe: {
"nsPref:changed": function (subject, data) {
let observers = this._observers[data];
if (observers) {
let value = this.get(data, false);
this._observers[data] = observers.filter(function (callback) {
if (!callback.get())
return false;
util.trapErrors(callback.get(), null, value);
return true;
});
}
}
},
/**
* Adds a new preference observer for the given preference.
*
* @param {string} pref The preference to observe.
* @param {function(object)} callback The callback, called with the
* new value of the preference whenever it changes.
*/
watch: function (pref, callback, strong) {
if (!this._observers[pref])
this._observers[pref] = [];
this._observers[pref].push(!strong ? Cu.getWeakReference(callback) : { get: function () callback });
},
/**
* Lists all preferences matching *filter* or only those with changed
* values if *onlyNonDefault* is specified.
*
* @param {boolean} onlyNonDefault Limit the list to prefs with a
* non-default value.
* @param {string} filter The list filter. A null filter lists all
* prefs.
* @optional
*/
list: function list(onlyNonDefault, filter) {
if (!filter)
filter = "";
let prefArray = this.getNames();
prefArray.sort();
function prefs() {
for (let [, pref] in Iterator(prefArray)) {
let userValue = services.get("pref").prefHasUserValue(pref);
if (onlyNonDefault && !userValue || pref.indexOf(filter) == -1)
continue;
let value = this.get(pref);
let option = {
isDefault: !userValue,
default: this._load(pref, null, true),
value: <>={template.highlight(value, true, 100)}</>,
name: pref,
pre: "\u00a0\u00a0" // Unicode nonbreaking space.
};
yield option;
}
};
return template.options(services.get("dactyl:").host + " Preferences", prefs.call(this));
},
/**
* Returns the value of a preference.
*
* @param {string} name The preference name.
* @param {value} defaultValue The value to return if the preference
* is unset.
*/
get: function (name, defaultValue) this._load(name, defaultValue),
/**
* Returns the default value of a preference
*
* @param {string} name The preference name.
* @param {value} defaultValue The value to return if the preference
* has no default value.
*/
getDefault: function (name, defaultValue) this._load(name, defaultValue, true),
/**
* Returns the names of all preferences.
*
* @param {string} branch The branch in which to search preferences.
* @default ""
*/
getNames: function (branch) services.get("pref").getChildList(branch || "", { value: 0 }),
_checkSafe: function (name, message, value) {
let curval = this._load(name, null, false);
if (arguments.length > 2 && curval === value)
return;
let defval = this._load(name, null, true);
let saved = this._load(this.SAVED + name);
if (saved == null && curval != defval || curval != saved) {
let msg = "Warning: setting preference " + name + ", but it's changed from its default value.";
if (message)
msg += " " + message;
util.dactyl.echomsg(msg);
}
},
/**
* Resets the preference *name* to *value* but warns the user if the value
* is changed from its default.
*
* @param {string} name The preference name.
* @param {value} value The new preference value.
*/
safeReset: function (name, message) {
this._checkSafe(name, message);
this.reset(name);
this.reset(this.SAVED + name);
},
/**
* Sets the preference *name* to *value* but warns the user if the value is
* changed from its default.
*
* @param {string} name The preference name.
* @param {value} value The new preference value.
*/
safeSet: function (name, value, message, skipSave) {
this._checkSafe(name, message, value);
this._store(name, value);
this[skipSave ? "reset" : "_store"](this.SAVED + name, value);
},
/**
* Sets the preference *name* to *value*.
*
* @param {string} name The preference name.
* @param {value} value The new preference value.
*/
set: function (name, value) {
this._store(name, value);
},
/**
* Saves the current value of a preference to be restored at next
* startup.
*
* @param {string} name The preference to save.
*/
save: function (name) {
let val = this.get(name);
this.set(this.RESTORE + name, val);
this.safeSet(name, val);
},
/**
* Restores saved preferences in the given branch.
*
* @param {string} branch The branch from which to restore
* preferences. @optional
*/
restore: function (branch) {
this.getNames(this.RESTORE + (branch || "")).forEach(function (pref) {
this.safeSet(pref.substr(this.RESTORE.length), this.get(pref), null, true)
this.reset(pref);
}, this);
},
/**
* Resets the preference *name* to its default value.
*
* @param {string} name The preference name.
*/
reset: function (name) {
try {
services.get("pref").clearUserPref(name);
}
catch (e) {} // ignore - thrown if not a user set value
},
/**
* Toggles the value of the boolean preference *name*.
*
* @param {string} name The preference name.
*/
toggle: function (name) {
util.assert(services.get("pref").getPrefType(name) === Ci.nsIPrefBranch.PREF_BOOL,
"E488: Trailing characters: " + name + "!");
this.set(name, !this.get(name));
},
/**
* Pushes a new preference context onto the context stack.
*
* @see #withContext
*/
pushContext: function () {
this._prefContexts.push({});
},
/**
* Pops the top preference context from the stack.
*
* @see #withContext
*/
popContext: function () {
for (let [k, v] in Iterator(this._prefContexts.pop()))
this._store(k, v);
},
/**
* Executes *func* with a new preference context. When *func* returns, the
* context is popped and any preferences set via {@link #setPref} or
* {@link #invertPref} are restored to their previous values.
*
* @param {function} func The function to call.
* @param {Object} func The 'this' object with which to call *func*
* @see #pushContext
* @see #popContext
*/
withContext: function (func, self) {
try {
this.pushContext();
return func.call(self);
}
finally {
this.popContext();
}
},
_store: function (name, value) {
if (this._prefContexts.length) {
let val = this._load(name, null);
if (val != null)
this._prefContexts[this._prefContexts.length - 1][name] = val;
}
function assertType(needType)
util.assert(type === Ci.nsIPrefBranch.PREF_INVALID || type === needType,
type === Ci.nsIPrefBranch.PREF_INT
? "E521: Number required after =: " + name + "=" + value
: "E474: Invalid argument: " + name + "=" + value);
let type = services.get("pref").getPrefType(name);
switch (typeof value) {
case "string":
assertType(Ci.nsIPrefBranch.PREF_STRING);
let supportString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
supportString.data = value;
services.get("pref").setComplexValue(name, Ci.nsISupportsString, supportString);
break;
case "number":
assertType(Ci.nsIPrefBranch.PREF_INT);
services.get("pref").setIntPref(name, value);
break;
case "boolean":
assertType(Ci.nsIPrefBranch.PREF_BOOL);
services.get("pref").setBoolPref(name, value);
break;
default:
throw FailedAssertion("Unknown preference type: " + typeof value + " (" + name + "=" + value + ")");
}
},
_load: function (name, defaultValue, defaultBranch) {
if (defaultValue == null)
defaultValue = null;
let branch = defaultBranch ? services.get("pref").getDefaultBranch("") : services.get("pref");
let type = services.get("pref").getPrefType(name);
try {
switch (type) {
case Ci.nsIPrefBranch.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 (!services.get("pref").prefIsLocked(name) && !services.get("pref").prefHasUserValue(name) &&
RegExp("chrome://.+/locale/.+\\.properties").test(value))
value = branch.getComplexValue(name, Ci.nsIPrefLocalizedString).data;
return value;
case Ci.nsIPrefBranch.PREF_INT:
return branch.getIntPref(name);
case Ci.nsIPrefBranch.PREF_BOOL:
return branch.getBoolPref(name);
default:
return defaultValue;
}
}
catch (e) {
return defaultValue;
}
}
}, {
}, {
completion: function (dactyl, modules) {
modules.completion.preference = function preference(context) {
context.anchored = false;
context.title = [services.get("dactyl:").host + " Preference", "Value"];
context.keys = { text: function (item) item, description: function (item) prefs.get(item) };
context.completions = prefs.getNames();
};
},
javascript: function (dactyl, modules) {
modules.JavaScript.setCompleter([this.get, this.safeSet, this.set, this.reset, this.toggle],
[function (context) (context.anchored=false, prefs.getNames().map(function (pref) [pref, ""]))]);
}
});
/**
* Math utility methods.