1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-21 07:17:58 +01:00

Finish the Great Opening Brace Correction.

This commit is contained in:
Doug Kearns
2009-11-09 16:03:00 +11:00
parent 8ef1674c6e
commit a7925705d7
22 changed files with 334 additions and 656 deletions

View File

@@ -29,10 +29,8 @@ const systemPrincipal = channel.owner;
channel.cancel(NS_BINDING_ABORTED); channel.cancel(NS_BINDING_ABORTED);
delete channel; delete channel;
function dataURL(type, data) function dataURL(type, data) "data:" + (type || "application/xml;encoding=UTF-8") + "," + escape(data);
"data:" + (type || "application/xml;encoding=UTF-8") + "," + escape(data); function makeChannel(url, orig) {
function makeChannel(url, orig)
{
if (typeof url == "function") if (typeof url == "function")
url = dataURL.apply(null, url()); url = dataURL.apply(null, url());
let uri = ioService.newURI(url, null, null); let uri = ioService.newURI(url, null, null);
@@ -41,10 +39,8 @@ function makeChannel(url, orig)
channel.originalURI = orig; channel.originalURI = orig;
return channel; return channel;
} }
function fakeChannel(orig) function fakeChannel(orig) makeChannel("chrome://liberator/content/does/not/exist", orig);
makeChannel("chrome://liberator/content/does/not/exist", orig); function redirect(to, orig) {
function redirect(to, orig)
{
let html = <html><head><meta http-equiv="Refresh" content={"0;" + to}/></head></html>.toXMLString(); let html = <html><head><meta http-equiv="Refresh" content={"0;" + to}/></head></html>.toXMLString();
return makeChannel(dataURL('text/html', html), ioServices.newURI(to, null, null)); return makeChannel(dataURL('text/html', html), ioServices.newURI(to, null, null));
} }
@@ -56,8 +52,7 @@ ChromeData.prototype = {
classDescription: "Data URIs with chrome privileges", classDescription: "Data URIs with chrome privileges",
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIProtocolHandler]), QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIProtocolHandler]),
_xpcom_factory: { _xpcom_factory: {
createInstance: function (outer, iid) createInstance: function (outer, iid) {
{
if (!ChromeData.instance) if (!ChromeData.instance)
ChromeData.instance = new ChromeData(); ChromeData.instance = new ChromeData();
if (outer != null) if (outer != null)
@@ -73,8 +68,7 @@ ChromeData.prototype = {
| nsIProtocolHandler.URI_NOAUTH | nsIProtocolHandler.URI_NOAUTH
| nsIProtocolHandler.URI_IS_UI_RESOURCE, | nsIProtocolHandler.URI_IS_UI_RESOURCE,
newURI: function (spec, charset, baseURI) newURI: function (spec, charset, baseURI) {
{
var uri = Components.classes["@mozilla.org/network/standard-url;1"] var uri = Components.classes["@mozilla.org/network/standard-url;1"]
.createInstance(Components.interfaces.nsIStandardURL) .createInstance(Components.interfaces.nsIStandardURL)
.QueryInterface(Components.interfaces.nsIURI); .QueryInterface(Components.interfaces.nsIURI);
@@ -82,10 +76,8 @@ ChromeData.prototype = {
return uri; return uri;
}, },
newChannel: function (uri) newChannel: function (uri) {
{ try {
try
{
if (uri.scheme == this.scheme) if (uri.scheme == this.scheme)
return makeChannel(uri.spec.replace(/^.*?:\/*(.*)(?:#.*)?/, "data:$1"), uri); return makeChannel(uri.spec.replace(/^.*?:\/*(.*)(?:#.*)?/, "data:$1"), uri);
} }
@@ -94,8 +86,7 @@ ChromeData.prototype = {
} }
}; };
function Liberator() function Liberator() {
{
this.wrappedJSObject = this; this.wrappedJSObject = this;
const self = this; const self = this;
@@ -109,8 +100,7 @@ Liberator.prototype = {
classDescription: "Liberator utility protocol", classDescription: "Liberator utility protocol",
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIProtocolHandler]), QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIProtocolHandler]),
_xpcom_factory: { _xpcom_factory: {
createInstance: function (outer, iid) createInstance: function (outer, iid) {
{
if (!Liberator.instance) if (!Liberator.instance)
Liberator.instance = new Liberator(); Liberator.instance = new Liberator();
if (outer != null) if (outer != null)
@@ -119,10 +109,8 @@ Liberator.prototype = {
} }
}, },
init: function (obj) init: function (obj) {
{ for each (let prop in ["HELP_TAGS", "FILE_MAP", "OVERLAY_MAP"]) {
for each (let prop in ["HELP_TAGS", "FILE_MAP", "OVERLAY_MAP"])
{
this[prop] = this[prop].constructor(); this[prop] = this[prop].constructor();
for (let [k, v] in Iterator(obj[prop] || {})) for (let [k, v] in Iterator(obj[prop] || {}))
this[prop][k] = v this[prop][k] = v
@@ -136,8 +124,7 @@ Liberator.prototype = {
| nsIProtocolHandler.URI_IS_UI_RESOURCE | nsIProtocolHandler.URI_IS_UI_RESOURCE
| nsIProtocolHandler.URI_IS_LOCAL_RESOURCE, | nsIProtocolHandler.URI_IS_LOCAL_RESOURCE,
newURI: function (spec, charset, baseURI) newURI: function (spec, charset, baseURI) {
{
var uri = Components.classes["@mozilla.org/network/standard-url;1"] var uri = Components.classes["@mozilla.org/network/standard-url;1"]
.createInstance(Components.interfaces.nsIStandardURL) .createInstance(Components.interfaces.nsIStandardURL)
.QueryInterface(Components.interfaces.nsIURI); .QueryInterface(Components.interfaces.nsIURI);
@@ -145,12 +132,9 @@ Liberator.prototype = {
return uri; return uri;
}, },
newChannel: function (uri) newChannel: function (uri) {
{ try {
try switch(uri.host) {
{
switch(uri.host)
{
case "help": case "help":
let url = this.FILE_MAP[uri.path.replace(/^\/|#.*/g, "")]; let url = this.FILE_MAP[uri.path.replace(/^\/|#.*/g, "")];
return makeChannel(url, uri); return makeChannel(url, uri);
@@ -170,9 +154,6 @@ Liberator.prototype = {
var components = [ChromeData, Liberator]; var components = [ChromeData, Liberator];
function NSGetModule(compMgr, fileSpec) function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule(components)
{
return XPCOMUtils.generateModule(components);
}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -355,10 +355,8 @@ const Buffer = Module("buffer", {
for (let [, regex] in Iterator(regexes)) { for (let [, regex] in Iterator(regexes)) {
for (let i in util.range(res.snapshotLength, 0, -1)) { for (let i in util.range(res.snapshotLength, 0, -1)) {
let elem = res.snapshotItem(i); let elem = res.snapshotItem(i);
if (regex.test(elem.textContent) || if (regex.test(elem.textContent) || regex.test(elem.title) ||
regex.test(elem.title) || Array.some(elem.childNodes, function (child) regex.test(child.alt))) {
Array.some(elem.childNodes, function (child) regex.test(child.alt)))
{
buffer.followLink(elem, liberator.CURRENT_TAB); buffer.followLink(elem, liberator.CURRENT_TAB);
return true; return true;
} }

View File

@@ -321,8 +321,7 @@ function Highlights(name, store) {
this.loadCSS = function (css) { this.loadCSS = function (css) {
css.replace(/^(\s*\S*\s+)\{((?:.|\n)*?)\}\s*$/gm, function (_, _1, _2) _1 + " " + _2.replace(/\n\s*/g, " ")) css.replace(/^(\s*\S*\s+)\{((?:.|\n)*?)\}\s*$/gm, function (_, _1, _2) _1 + " " + _2.replace(/\n\s*/g, " "))
.split("\n").filter(function (s) /\S/.test(s)) .split("\n").filter(function (s) /\S/.test(s))
.forEach(function (style) .forEach(function (style) {
{
style = Highlight.apply(Highlight, Array.slice(style.match(/^\s*((?:[^,\s]|\s\S)+)(?:,((?:[^,\s]|\s\S)+)?)?(?:,((?:[^,\s]|\s\S)+))?\s*(.*)$/), 1)); style = Highlight.apply(Highlight, Array.slice(style.match(/^\s*((?:[^,\s]|\s\S)+)(?:,((?:[^,\s]|\s\S)+)?)?(?:,((?:[^,\s]|\s\S)+))?\s*(.*)$/), 1));
if (/^[>+ ]/.test(style.selector)) if (/^[>+ ]/.test(style.selector))
style.selector = self.selector(style.class) + style.selector; style.selector = self.selector(style.class) + style.selector;

View File

@@ -227,9 +227,7 @@ const Tabs = Module("tabs", {
if (getBrowser().mTabs.length > 1) if (getBrowser().mTabs.length > 1)
getBrowser().removeTab(tab); getBrowser().removeTab(tab);
else { else {
if (buffer.URL != "about:blank" || if (buffer.URL != "about:blank" || window.getWebNavigation().sessionHistory.count > 0) {
window.getWebNavigation().sessionHistory.count > 0)
{
liberator.open("about:blank", liberator.NEW_BACKGROUND_TAB); liberator.open("about:blank", liberator.NEW_BACKGROUND_TAB);
getBrowser().removeTab(tab); getBrowser().removeTab(tab);
} }

View File

@@ -9,8 +9,7 @@ var CommandLineHandler;
function initCommandLineHandler(Name) { function initCommandLineHandler(Name) {
var name = Name.toLowerCase(); var name = Name.toLowerCase();
CommandLineHandler = function CommandLineHandler() CommandLineHandler = function CommandLineHandler() {
{
this.wrappedJSObject = this; this.wrappedJSObject = this;
} }
CommandLineHandler.prototype = { CommandLineHandler.prototype = {
@@ -28,21 +27,18 @@ function initCommandLineHandler(Name) {
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler]), QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler]),
handle: function (commandLine) handle: function (commandLine) {
{
// TODO: handle remote launches differently? // TODO: handle remote launches differently?
try try {
{
this.optionValue = commandLine.handleFlagWithParam(name, false); this.optionValue = commandLine.handleFlagWithParam(name, false);
} }
catch (e) catch (e) {
{
//"vimperator: option -vimperator requires an argument" //"vimperator: option -vimperator requires an argument"
} }
} }
}; };
} }
function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([CommandLineHandler]); function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([CommandLineHandler])
// vim: set ft=javascript fdm=marker sw=4 ts=4 et: // vim: set ft=javascript fdm=marker sw=4 ts=4 et:

View File

@@ -27,29 +27,24 @@ const Ci = Components.interfaces;
const Cu = Components.utils; const Cu = Components.utils;
// XXX: does not belong here // XXX: does not belong here
function Timer(minInterval, maxInterval, callback) function Timer(minInterval, maxInterval, callback) {
{
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this.doneAt = 0; this.doneAt = 0;
this.latest = 0; this.latest = 0;
this.notify = function (aTimer) this.notify = function (aTimer) {
{
timer.cancel(); timer.cancel();
this.latest = 0; this.latest = 0;
// minInterval is the time between the completion of the command and the next firing // minInterval is the time between the completion of the command and the next firing
this.doneAt = Date.now() + minInterval; this.doneAt = Date.now() + minInterval;
try try {
{
callback(this.arg); callback(this.arg);
} }
finally finally {
{
this.doneAt = Date.now() + minInterval; this.doneAt = Date.now() + minInterval;
} }
}; };
this.tell = function (arg) this.tell = function (arg) {
{
if (arguments.length > 0) if (arguments.length > 0)
this.arg = arg; this.arg = arg;
@@ -68,32 +63,27 @@ function Timer(minInterval, maxInterval, callback)
timer.initWithCallback(this, Math.max(timeout, 0), timer.TYPE_ONE_SHOT); timer.initWithCallback(this, Math.max(timeout, 0), timer.TYPE_ONE_SHOT);
this.doneAt = -1; this.doneAt = -1;
}; };
this.reset = function () this.reset = function () {
{
timer.cancel(); timer.cancel();
this.doneAt = 0; this.doneAt = 0;
}; };
this.flush = function () this.flush = function () {
{
if (this.doneAt == -1) if (this.doneAt == -1)
this.notify(); this.notify();
}; };
} }
function getFile(name) function getFile(name) {
{
let file = storage.infoPath.clone(); let file = storage.infoPath.clone();
file.append(name); file.append(name);
return file; return file;
} }
function readFile(file) function readFile(file) {
{
let fileStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); 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); let stream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
try try {
{
fileStream.init(file, -1, 0, 0); fileStream.init(file, -1, 0, 0);
stream.init(fileStream, "UTF-8", 4096, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); // 4096 bytes buffering stream.init(fileStream, "UTF-8", 4096, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); // 4096 bytes buffering
@@ -110,8 +100,7 @@ function readFile(file)
catch (e) {} catch (e) {}
} }
function writeFile(file, data) function writeFile(file, data) {
{
if (!file.exists()) if (!file.exists())
file.create(file.NORMAL_FILE_TYPE, 0600); file.create(file.NORMAL_FILE_TYPE, 0600);
@@ -132,34 +121,28 @@ var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPref
.getBranch("extensions.liberator.datastore."); .getBranch("extensions.liberator.datastore.");
var json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); var json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
function getCharPref(name) function getCharPref(name) {
{ try {
try
{
return prefService.getComplexValue(name, Ci.nsISupportsString).data; return prefService.getComplexValue(name, Ci.nsISupportsString).data;
} }
catch (e) {} catch (e) {}
} }
function setCharPref(name, value) function setCharPref(name, value) {
{
var str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString); var str = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
str.data = value; str.data = value;
return prefService.setComplexValue(name, Ci.nsISupportsString, str); return prefService.setComplexValue(name, Ci.nsISupportsString, str);
} }
function loadPref(name, store, type) function loadPref(name, store, type) {
{ try {
try
{
if (store) if (store)
var pref = getCharPref(name); var pref = getCharPref(name);
if (!pref && storage.infoPath) if (!pref && storage.infoPath)
var file = readFile(getFile(name)); var file = readFile(getFile(name));
if (pref || file) if (pref || file)
var result = json.decode(pref || file); var result = json.decode(pref || file);
if (pref) if (pref) {
{
prefService.clearUserPref(name); prefService.clearUserPref(name);
savePref({ name: name, store: true, serial: pref }); savePref({ name: name, store: true, serial: pref });
} }
@@ -169,8 +152,7 @@ function loadPref(name, store, type)
catch (e) {} catch (e) {}
} }
function savePref(obj) function savePref(obj) {
{
if (obj.privateData && storage.privateMode) if (obj.privateData && storage.privateMode)
return; return;
if (obj.store && storage.infoPath) if (obj.store && storage.infoPath)
@@ -181,8 +163,7 @@ var prototype = {
OPTIONS: ["privateData"], OPTIONS: ["privateData"],
fireEvent: function (event, arg) { storage.fireEvent(this.name, event, arg); }, fireEvent: function (event, arg) { storage.fireEvent(this.name, event, arg); },
save: function () { savePref(this); }, save: function () { savePref(this); },
init: function (name, store, data, options) init: function (name, store, data, options) {
{
this.__defineGetter__("store", function () store); this.__defineGetter__("store", function () store);
this.__defineGetter__("name", function () name); this.__defineGetter__("name", function () name);
for (let [k, v] in Iterator(options)) for (let [k, v] in Iterator(options))
@@ -192,12 +173,10 @@ var prototype = {
} }
}; };
function ObjectStore(name, store, load, options) function ObjectStore(name, store, load, options) {
{
var object = {}; var object = {};
this.reload = function reload() this.reload = function reload() {
{
object = load() || {}; object = load() || {};
this.fireEvent("change", null); this.fireEvent("change", null);
}; };
@@ -205,8 +184,7 @@ function ObjectStore(name, store, load, options)
this.init.apply(this, arguments); this.init.apply(this, arguments);
this.__defineGetter__("serial", function () json.encode(object)); this.__defineGetter__("serial", function () json.encode(object));
this.set = function set(key, val) this.set = function set(key, val) {
{
var defined = key in object; var defined = key in object;
var orig = object[key]; var orig = object[key];
object[key] = val; object[key] = val;
@@ -216,8 +194,7 @@ function ObjectStore(name, store, load, options)
this.fireEvent("change", key); this.fireEvent("change", key);
}; };
this.remove = function remove(key) this.remove = function remove(key) {
{
var ret = object[key]; var ret = object[key];
delete object[key]; delete object[key];
this.fireEvent("remove", key); this.fireEvent("remove", key);
@@ -226,8 +203,7 @@ function ObjectStore(name, store, load, options)
this.get = function get(val) object[val]; this.get = function get(val) object[val];
this.clear = function () this.clear = function () {
{
object = {}; object = {};
}; };
@@ -235,12 +211,10 @@ function ObjectStore(name, store, load, options)
} }
ObjectStore.prototype = prototype; ObjectStore.prototype = prototype;
function ArrayStore(name, store, load, options) function ArrayStore(name, store, load, options) {
{
var array = []; var array = [];
this.reload = function reload() this.reload = function reload() {
{
array = load() || []; array = load() || [];
this.fireEvent("change", null); this.fireEvent("change", null);
}; };
@@ -249,31 +223,26 @@ function ArrayStore(name, store, load, options)
this.__defineGetter__("serial", function () json.encode(array)); this.__defineGetter__("serial", function () json.encode(array));
this.__defineGetter__("length", function () array.length); this.__defineGetter__("length", function () array.length);
this.set = function set(index, value) this.set = function set(index, value) {
{
var orig = array[index]; var orig = array[index];
array[index] = value; array[index] = value;
this.fireEvent("change", index); this.fireEvent("change", index);
}; };
this.push = function push(value) this.push = function push(value) {
{
array.push(value); array.push(value);
this.fireEvent("push", array.length); this.fireEvent("push", array.length);
}; };
this.pop = function pop(value) this.pop = function pop(value) {
{
var ret = array.pop(); var ret = array.pop();
this.fireEvent("pop", array.length); this.fireEvent("pop", array.length);
return ret; return ret;
}; };
this.truncate = function truncate(length, fromEnd) this.truncate = function truncate(length, fromEnd) {
{
var ret = array.length; var ret = array.length;
if (array.length > length) if (array.length > length) {
{
if (fromEnd) if (fromEnd)
array.splice(0, array.length - length); array.splice(0, array.length - length);
array.length = length; array.length = length;
@@ -283,16 +252,14 @@ function ArrayStore(name, store, load, options)
}; };
// XXX: Awkward. // XXX: Awkward.
this.mutate = function mutate(aFuncName) this.mutate = function mutate(aFuncName) {
{
var funcName = aFuncName; var funcName = aFuncName;
arguments[0] = array; arguments[0] = array;
array = Array[funcName].apply(Array, arguments); array = Array[funcName].apply(Array, arguments);
this.fireEvent("change", null); this.fireEvent("change", null);
}; };
this.get = function get(index) this.get = function get(index) {
{
return index >= 0 ? array[index] : array[array.length + index]; return index >= 0 ? array[index] : array[array.length + index];
}; };
@@ -306,10 +273,8 @@ var timers = {};
var storage = { var storage = {
alwaysReload: {}, alwaysReload: {},
newObject: function newObject(key, constructor, params) newObject: function newObject(key, constructor, params) {
{ if (!(key in keys) || params.reload || this.alwaysReload[key]) {
if (!(key in keys) || params.reload || this.alwaysReload[key])
{
if (key in this && !(params.reload || this.alwaysReload[key])) if (key in this && !(params.reload || this.alwaysReload[key]))
throw Error(); throw Error();
let load = function () loadPref(key, params.store, params.type || Object); let load = function () loadPref(key, params.store, params.type || Object);
@@ -320,27 +285,22 @@ var storage = {
return keys[key]; return keys[key];
}, },
newMap: function newMap(key, options) newMap: function newMap(key, options) {
{
return this.newObject(key, ObjectStore, options); return this.newObject(key, ObjectStore, options);
}, },
newArray: function newArray(key, options) newArray: function newArray(key, options) {
{
return this.newObject(key, ArrayStore, { type: Array, __proto__: options }); return this.newObject(key, ArrayStore, { type: Array, __proto__: options });
}, },
addObserver: function addObserver(key, callback, ref) addObserver: function addObserver(key, callback, ref) {
{ if (ref) {
if (ref)
{
if (!ref.liberatorStorageRefs) if (!ref.liberatorStorageRefs)
ref.liberatorStorageRefs = []; ref.liberatorStorageRefs = [];
ref.liberatorStorageRefs.push(callback); ref.liberatorStorageRefs.push(callback);
var callbackRef = Cu.getWeakReference(callback); var callbackRef = Cu.getWeakReference(callback);
} }
else else {
{
callbackRef = { get: function () callback }; callbackRef = { get: function () callback };
} }
this.removeDeadObservers(); this.removeDeadObservers();
@@ -350,8 +310,7 @@ var storage = {
observers[key].push({ ref: ref && Cu.getWeakReference(ref), callback: callbackRef }); observers[key].push({ ref: ref && Cu.getWeakReference(ref), callback: callbackRef });
}, },
removeObserver: function (key, callback) removeObserver: function (key, callback) {
{
this.removeDeadObservers(); this.removeDeadObservers();
if (!(key in observers)) if (!(key in observers))
return; return;
@@ -360,10 +319,8 @@ var storage = {
delete obsevers[key]; delete obsevers[key];
}, },
removeDeadObservers: function () removeDeadObservers: function () {
{ for (let [key, ary] in Iterator(observers)) {
for (let [key, ary] in Iterator(observers))
{
observers[key] = ary = ary.filter(function (o) o.callback.get() && (!o.ref || o.ref.get() && o.ref.get().liberatorStorageRefs)); observers[key] = ary = ary.filter(function (o) o.callback.get() && (!o.ref || o.ref.get() && o.ref.get().liberatorStorageRefs));
if (!ary.length) if (!ary.length)
delete observers[key]; delete observers[key];
@@ -372,8 +329,7 @@ var storage = {
get observers() observers, get observers() observers,
fireEvent: function fireEvent(key, event, arg) fireEvent: function fireEvent(key, event, arg) {
{
if (!(key in this)) if (!(key in this))
return; return;
this.removeDeadObservers(); this.removeDeadObservers();
@@ -383,27 +339,23 @@ var storage = {
timers[key].tell(); timers[key].tell();
}, },
load: function load(key) load: function load(key) {
{
if (this[key].store && this[key].reload) if (this[key].store && this[key].reload)
this[key].reload(); this[key].reload();
}, },
save: function save(key) save: function save(key) {
{
savePref(keys[key]); savePref(keys[key]);
}, },
saveAll: function storeAll() saveAll: function storeAll() {
{
for each (let obj in keys) for each (let obj in keys)
savePref(obj); savePref(obj);
}, },
_privateMode: false, _privateMode: false,
get privateMode() this._privateMode, get privateMode() this._privateMode,
set privateMode(val) set privateMode(val) {
{
if (!val && this._privateMode) if (!val && this._privateMode)
for (let key in keys) for (let key in keys)
this.load(key); this.load(key);

View File

@@ -25,19 +25,16 @@ AboutHandler.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]), QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
newChannel: function (uri) newChannel: function (uri) {
{
let channel = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService) let channel = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService)
.newChannel("chrome://" + name + "/content/about.html", null, null); .newChannel("chrome://" + name + "/content/about.html", null, null);
channel.originalURI = uri; channel.originalURI = uri;
return channel; return channel;
}, },
getURIFlags: function (uri) Ci.nsIAboutModule.ALLOW_SCRIPT, getURIFlags: function (uri) Ci.nsIAboutModule.ALLOW_SCRIPT,
}; };
function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([AboutHandler]); function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([AboutHandler])
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -11,8 +11,7 @@ const Name = "Muttator";
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const name = Name.toLowerCase(); const name = Name.toLowerCase();
function CommandLineHandler() function CommandLineHandler() {
{
this.wrappedJSObject = this; this.wrappedJSObject = this;
} }
CommandLineHandler.prototype = { CommandLineHandler.prototype = {
@@ -30,20 +29,17 @@ CommandLineHandler.prototype = {
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler]), QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler]),
handle: function (commandLine) handle: function (commandLine) {
{
// TODO: handle remote launches differently? // TODO: handle remote launches differently?
try try {
{
this.optionValue = commandLine.handleFlagWithParam(name, false); this.optionValue = commandLine.handleFlagWithParam(name, false);
} }
catch (e) catch (e) {
{
//"vimperator: option -vimperator requires an argument" //"vimperator: option -vimperator requires an argument"
} }
} }
}; };
function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([CommandLineHandler]); function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([CommandLineHandler])
// vim: set ft=javascript fdm=marker sw=4 ts=4 et: // vim: set ft=javascript fdm=marker sw=4 ts=4 et:

View File

@@ -3,8 +3,7 @@
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
function Addressbook() //{{{ function Addressbook() { //{{{
{
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -14,8 +13,7 @@ function Addressbook() //{{{
// TODO: add option for a format specifier, like: // TODO: add option for a format specifier, like:
// :set displayname=%l, %f // :set displayname=%l, %f
function generateDisplayName(firstName, lastName) function generateDisplayName(firstName, lastName) {
{
if (firstName && lastName) if (firstName && lastName)
return lastName + ", " + firstName; return lastName + ", " + firstName;
else if (firstName) else if (firstName)
@@ -40,14 +38,11 @@ function Addressbook() //{{{
mappings.add(myModes, ["a"], mappings.add(myModes, ["a"],
"Open a prompt to save a new addressbook entry for the sender of the selected message", "Open a prompt to save a new addressbook entry for the sender of the selected message",
function () function () {
{ try {
try
{
var to = gDBView.hdrForFirstSelectedMessage.mime2DecodedAuthor; var to = gDBView.hdrForFirstSelectedMessage.mime2DecodedAuthor;
} }
catch (e) catch (e) {
{
liberator.beep(); liberator.beep();
} }
@@ -57,8 +52,7 @@ function Addressbook() //{{{
let address = to.substring(to.indexOf("<") + 1, to.indexOf(">")); let address = to.substring(to.indexOf("<") + 1, to.indexOf(">"));
let displayName = to.substr(0, to.indexOf("<") - 1); let displayName = to.substr(0, to.indexOf("<") - 1);
if (/^\S+\s+\S+\s*$/.test(displayName)) if (/^\S+\s+\S+\s*$/.test(displayName)) {
{
let names = displayName.split(/\s+/); let names = displayName.split(/\s+/);
displayName = "-firstname=" + names[0].replace(/"/g, "") displayName = "-firstname=" + names[0].replace(/"/g, "")
+ " -lastname=" + names[1].replace(/"/g, ""); + " -lastname=" + names[1].replace(/"/g, "");
@@ -75,8 +69,7 @@ function Addressbook() //{{{
commands.add(["con[tact]"], commands.add(["con[tact]"],
"Add an address book entry", "Add an address book entry",
function (args) function (args) {
{
let mailAddr = args[0]; // TODO: support more than one email address let mailAddr = args[0]; // TODO: support more than one email address
let firstName = args["-firstname"] || null; let firstName = args["-firstname"] || null;
let lastName = args["-lastname"] || null; let lastName = args["-lastname"] || null;
@@ -108,8 +101,7 @@ function Addressbook() //{{{
return { return {
add: function (address, firstName, lastName, displayName) add: function (address, firstName, lastName, displayName) {
{
const personalAddressbookURI = "moz-abmdbdirectory://abook.mab"; const personalAddressbookURI = "moz-abmdbdirectory://abook.mab";
let directory = getDirectoryFromURI(personalAddressbookURI); let directory = getDirectoryFromURI(personalAddressbookURI);
let card = Cc["@mozilla.org/addressbook/cardproperty;1"].createInstance(Ci.nsIAbCard); let card = Cc["@mozilla.org/addressbook/cardproperty;1"].createInstance(Ci.nsIAbCard);
@@ -126,18 +118,15 @@ function Addressbook() //{{{
}, },
// TODO: add telephone number support // TODO: add telephone number support
list: function (filter, newMail) list: function (filter, newMail) {
{
let addresses = []; let addresses = [];
let dirs = abManager.directories; let dirs = abManager.directories;
let lowerFilter = filter.toLowerCase(); let lowerFilter = filter.toLowerCase();
while (dirs.hasMoreElements()) while (dirs.hasMoreElements()) {
{
let addrbook = dirs.getNext().QueryInterface(Ci.nsIAbDirectory); let addrbook = dirs.getNext().QueryInterface(Ci.nsIAbDirectory);
let cards = addrbook.childCards; let cards = addrbook.childCards;
while (cards.hasMoreElements()) while (cards.hasMoreElements()) {
{
let card = cards.getNext().QueryInterface(Ci.nsIAbCard); let card = cards.getNext().QueryInterface(Ci.nsIAbCard);
//var mail = card.primaryEmail || ""; //XXX //var mail = card.primaryEmail || ""; //XXX
let displayName = card.displayName; let displayName = card.displayName;
@@ -150,8 +139,7 @@ function Addressbook() //{{{
} }
} }
if (addresses.length < 1) if (addresses.length < 1) {
{
if (!filter) if (!filter)
liberator.echoerr("Exxx: No contacts", commandline.FORCE_SINGLELINE); liberator.echoerr("Exxx: No contacts", commandline.FORCE_SINGLELINE);
else else
@@ -159,8 +147,7 @@ function Addressbook() //{{{
return false; return false;
} }
if (newMail) if (newMail) {
{
// Now we have to create a new message // Now we have to create a new message
let args = {}; let args = {};
args.to = addresses.map( args.to = addresses.map(
@@ -169,8 +156,7 @@ function Addressbook() //{{{
mail.composeNewMail(args); mail.composeNewMail(args);
} }
else else {
{
let list = template.tabular(["Name", "Address"], [], let list = template.tabular(["Name", "Address"], [],
[[util.clip(address[0], 50), address[1]] for ([, address] in Iterator(addresses))] [[util.clip(address[0], 50), address[1]] for ([, address] in Iterator(addresses))]
); );

View File

@@ -3,8 +3,7 @@
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
function Compose() //{{{ function Compose() { //{{{
{
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -12,19 +11,16 @@ function Compose() //{{{
config.features = ["addressbook"]; // the composer has no special features config.features = ["addressbook"]; // the composer has no special features
var stateListener = { var stateListener = {
QueryInterface: function (id) QueryInterface: function (id) {
{
if (id.equals(Ci.nsIDocumentStateListener)) if (id.equals(Ci.nsIDocumentStateListener))
return this; return this;
throw Cr.NS_NOINTERFACE; throw Cr.NS_NOINTERFACE;
}, },
// this is (also) fired once the new compose window loaded the message for the first time // this is (also) fired once the new compose window loaded the message for the first time
NotifyDocumentStateChanged: function (nowDirty) NotifyDocumentStateChanged: function (nowDirty) {
{
// only edit with external editor if this window was not cached! // only edit with external editor if this window was not cached!
if (options["autoexternal"] && !window.messageWasEditedExternally/* && !gMsgCompose.recycledWindow*/) if (options["autoexternal"] && !window.messageWasEditedExternally/* && !gMsgCompose.recycledWindow*/) {
{
window.messageWasEditedExternally = true; window.messageWasEditedExternally = true;
editor.editFieldExternally(); editor.editFieldExternally();
} }
@@ -36,8 +32,7 @@ function Compose() //{{{
// XXX: Hack! // XXX: Hack!
window.document.addEventListener("load", function () { window.document.addEventListener("load", function () {
if (window.messageWasEditedExternally === undefined) if (window.messageWasEditedExternally === undefined) {
{
window.messageWasEditedExternally = false; window.messageWasEditedExternally = false;
GetCurrentEditor().addDocumentStateListener(stateListener); GetCurrentEditor().addDocumentStateListener(stateListener);
} }

View File

@@ -3,8 +3,7 @@
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
const config = (function () //{{{ const config = (function () { //{{{
{
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -101,11 +100,9 @@ const config = (function () //{{{
function () { buffer.viewSelectionSource(); }]*/ function () { buffer.viewSelectionSource(); }]*/
], ],
focusChange: function (win) focusChange: function (win) {
{
// we switch to -- MESSAGE -- mode for Muttator, when the main HTML widget gets focus // we switch to -- MESSAGE -- mode for Muttator, when the main HTML widget gets focus
if (win && win.document instanceof HTMLDocument || liberator.focus instanceof HTMLAnchorElement) if (win && win.document instanceof HTMLDocument || liberator.focus instanceof HTMLAnchorElement) {
{
if (config.isComposeWindow) if (config.isComposeWindow)
modes.set(modes.INSERT, modes.TEXTAREA); modes.set(modes.INSERT, modes.TEXTAREA);
else if (liberator.mode != modes.MESSAGE) else if (liberator.mode != modes.MESSAGE)
@@ -114,8 +111,7 @@ const config = (function () //{{{
}, },
getBrowser: function () { getBrowser: function () {
if (!tabmail) if (!tabmail) {
{
tabmail = { __proto__: document.getElementById("tabmail") }; tabmail = { __proto__: document.getElementById("tabmail") };
tabmail.__defineGetter__("mTabContainer", function () this.tabContainer); tabmail.__defineGetter__("mTabContainer", function () this.tabContainer);
tabmail.__defineGetter__("mTabs", function () this.tabContainer.childNodes); tabmail.__defineGetter__("mTabs", function () this.tabContainer.childNodes);
@@ -145,10 +141,8 @@ const config = (function () //{{{
], ],
// NOTE: as I don't use TB I have no idea how robust this is. --djk // NOTE: as I don't use TB I have no idea how robust this is. --djk
get outputHeight() get outputHeight() {
{ if (!this.isComposeWindow) {
if (!this.isComposeWindow)
{
let container = document.getElementById("tabpanelcontainer").boxObject; let container = document.getElementById("tabpanelcontainer").boxObject;
let deck = document.getElementById("displayDeck"); let deck = document.getElementById("displayDeck");
let box = document.getElementById("messagepanebox"); let box = document.getElementById("messagepanebox");
@@ -173,8 +167,7 @@ const config = (function () //{{{
// to allow Vim to :set ft=mail automatically // to allow Vim to :set ft=mail automatically
tempFile: "mutt-ator-mail", tempFile: "mutt-ator-mail",
init: function () init: function () {
{
// don't wait too long when selecting new messages // don't wait too long when selecting new messages
// GetThreadTree()._selectDelay = 300; // TODO: make configurable // GetThreadTree()._selectDelay = 300; // TODO: make configurable
@@ -182,8 +175,7 @@ const config = (function () //{{{
if (this.isComposeWindow) if (this.isComposeWindow)
// TODO: this should probably be "composer" // TODO: this should probably be "composer"
liberator.loadModule("compose", Compose); liberator.loadModule("compose", Compose);
else else {
{
liberator.loadModule("mail", Mail); liberator.loadModule("mail", Mail);
liberator.loadModule("addressbook", Addressbook); liberator.loadModule("addressbook", Addressbook);
liberator.loadModule("tabs", Tabs); liberator.loadModule("tabs", Tabs);
@@ -208,8 +200,7 @@ const config = (function () //{{{
"Set the 'work offline' option", "Set the 'work offline' option",
"boolean", true, "boolean", true,
{ {
setter: function (value) setter: function (value) {
{
if (MailOfflineMgr.isOnline() != value) if (MailOfflineMgr.isOnline() != value)
MailOfflineMgr.toggleOfflineStatus(); MailOfflineMgr.toggleOfflineStatus();
return value; return value;

View File

@@ -3,8 +3,7 @@
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
function Mail() //{{{ function Mail() { //{{{
{
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -25,20 +24,16 @@ function Mail() //{{{
OnItemUnicharPropertyChanged: function (item, property, oldValue, newValue) {}, OnItemUnicharPropertyChanged: function (item, property, oldValue, newValue) {},
OnItemPropertyFlagChanged: function (item, property, oldFlag, newFlag) {}, OnItemPropertyFlagChanged: function (item, property, oldFlag, newFlag) {},
OnItemEvent: function (folder, event) OnItemEvent: function (folder, event) {
{
let eventType = event.toString(); let eventType = event.toString();
if (eventType == "FolderLoaded") if (eventType == "FolderLoaded") {
{ if (folder) {
if (folder)
{
let msgFolder = folder.QueryInterface(Ci.nsIMsgFolder); let msgFolder = folder.QueryInterface(Ci.nsIMsgFolder);
autocommands.trigger("FolderLoaded", { url: msgFolder }); autocommands.trigger("FolderLoaded", { url: msgFolder });
// Jump to a message when requested // Jump to a message when requested
let indices = []; let indices = [];
if (selectMessageKeys.length > 0) if (selectMessageKeys.length > 0) {
{
for (let j = 0; j < selectMessageKeys.length; j++) for (let j = 0; j < selectMessageKeys.length; j++)
indices.push([gDBView.findIndexFromKey(selectMessageKeys[j], true), selectMessageKeys[j]]); indices.push([gDBView.findIndexFromKey(selectMessageKeys[j], true), selectMessageKeys[j]]);
@@ -67,19 +62,16 @@ function Mail() //{{{
var notifyFlags = nsIFolderListener.intPropertyChanged | nsIFolderListener.event; var notifyFlags = nsIFolderListener.intPropertyChanged | nsIFolderListener.event;
mailSession.AddFolderListener(folderListener, notifyFlags); mailSession.AddFolderListener(folderListener, notifyFlags);
function getCurrentFolderIndex() function getCurrentFolderIndex() {
{
// for some reason, the index is interpreted as a string, therefore the parseInt // for some reason, the index is interpreted as a string, therefore the parseInt
return parseInt(gFolderTreeView.getIndexOfFolder(gFolderTreeView.getSelectedFolders()[0])); return parseInt(gFolderTreeView.getIndexOfFolder(gFolderTreeView.getSelectedFolders()[0]));
} }
function getRSSUrl() function getRSSUrl() {
{
return gDBView.hdrForFirstSelectedMessage.messageId.replace(/(#.*)?@.*$/, ""); return gDBView.hdrForFirstSelectedMessage.messageId.replace(/(#.*)?@.*$/, "");
} }
function moveOrCopy(copy, destinationFolder, operateOnThread) function moveOrCopy(copy, destinationFolder, operateOnThread) {
{
let folders = mail.getFolders(destinationFolder); let folders = mail.getFolders(destinationFolder);
if (folders.length == 0) if (folders.length == 0)
return void liberator.echoerr("Exxx: No matching folder for " + destinationFolder); return void liberator.echoerr("Exxx: No matching folder for " + destinationFolder);
@@ -96,13 +88,11 @@ function Mail() //{{{
}, 100); }, 100);
} }
function parentIndex(index) function parentIndex(index) {
{
let parent = index; let parent = index;
let tree = GetThreadTree(); let tree = GetThreadTree();
while (true) while (true) {
{
let tmp = tree.view.getParentIndex(parent); let tmp = tree.view.getParentIndex(parent);
if (tmp >= 0) if (tmp >= 0)
parent = tmp; parent = tmp;
@@ -113,18 +103,15 @@ function Mail() //{{{
} }
// does not wrap yet, intentional? // does not wrap yet, intentional?
function selectUnreadFolder(backwards, count) function selectUnreadFolder(backwards, count) {
{
count = Math.max(1, count); count = Math.max(1, count);
let direction = backwards ? -1 : 1; let direction = backwards ? -1 : 1;
let c = getCurrentFolderIndex(); let c = getCurrentFolderIndex();
let i = direction; let i = direction;
let folder; let folder;
while (count > 0 && (c + i) < gFolderTreeView.rowCount && (c + i) >= 0) while (count > 0 && (c + i) < gFolderTreeView.rowCount && (c + i) >= 0) {
{
let resource = gFolderTreeView._rowMap[c+i]._folder; let resource = gFolderTreeView._rowMap[c+i]._folder;
if (!resource.isServer && resource.getNumUnread(false)) if (!resource.isServer && resource.getNumUnread(false)) {
{
count -= 1; count -= 1;
folder = i; folder = i;
} }
@@ -136,8 +123,7 @@ function Mail() //{{{
gFolderTreeView.selection.timedSelect(c + folder, 500); gFolderTreeView.selection.timedSelect(c + folder, 500);
} }
function escapeRecipient(recipient) function escapeRecipient(recipient) {
{
// strip all ": // strip all ":
recipient = recipient.replace(/"/g, ""); recipient = recipient.replace(/"/g, "");
return "\"" + recipient + "\""; return "\"" + recipient + "\"";
@@ -162,10 +148,8 @@ function Mail() //{{{
"Set the layout of the mail window", "Set the layout of the mail window",
"string", "inherit", "string", "inherit",
{ {
setter: function (value) setter: function (value) {
{ switch (value) {
switch (value)
{
case "classic": ChangeMailLayout(0); break; case "classic": ChangeMailLayout(0); break;
case "wide": ChangeMailLayout(1); break; case "wide": ChangeMailLayout(1); break;
case "vertical": ChangeMailLayout(2); break; case "vertical": ChangeMailLayout(2); break;
@@ -188,8 +172,7 @@ function Mail() //{{{
"string", services.get("smtpService").defaultServer.key, // TODO: how should we handle these persistent external defaults - "inherit" or null? "string", services.get("smtpService").defaultServer.key, // TODO: how should we handle these persistent external defaults - "inherit" or null?
{ {
getter: function () services.get("smtpService").defaultServer.key, getter: function () services.get("smtpService").defaultServer.key,
setter: function (value) setter: function (value) {
{
let server = mail.smtpServers.filter(function (s) s.key == value)[0]; let server = mail.smtpServers.filter(function (s) s.key == value)[0];
services.get("smtpService").defaultServer = server; services.get("smtpService").defaultServer = server;
return value; return value;
@@ -202,8 +185,7 @@ function Mail() //{{{
"Use threading to group messages", "Use threading to group messages",
"boolean", true, "boolean", true,
{ {
setter: function (value) setter: function (value) {
{
if (value) if (value)
MsgSortThreaded(); MsgSortThreaded();
else else
@@ -225,8 +207,7 @@ function Mail() //{{{
mappings.add(myModes, ["I"], mappings.add(myModes, ["I"],
"Open the message in new tab", "Open the message in new tab",
function () function () {
{
if (gDBView && gDBView.selection.count < 1) if (gDBView && gDBView.selection.count < 1)
return void liberator.beep(); return void liberator.beep();
@@ -282,10 +263,8 @@ function Mail() //{{{
mappings.add(myModes, ["*"], mappings.add(myModes, ["*"],
"Select next message from the same sender", "Select next message from the same sender",
function (count) function (count) {
{ try {
try
{
let author = gDBView.hdrForFirstSelectedMessage.mime2DecodedAuthor.toLowerCase(); let author = gDBView.hdrForFirstSelectedMessage.mime2DecodedAuthor.toLowerCase();
mail.selectMessage(function (msg) msg.mime2DecodedAuthor.toLowerCase().indexOf(author) == 0, true, true, false, count); mail.selectMessage(function (msg) msg.mime2DecodedAuthor.toLowerCase().indexOf(author) == 0, true, true, false, count);
} }
@@ -295,10 +274,8 @@ function Mail() //{{{
mappings.add(myModes, ["#"], mappings.add(myModes, ["#"],
"Select previous message from the same sender", "Select previous message from the same sender",
function (count) function (count) {
{ try {
try
{
let author = gDBView.hdrForFirstSelectedMessage.mime2DecodedAuthor.toLowerCase(); let author = gDBView.hdrForFirstSelectedMessage.mime2DecodedAuthor.toLowerCase();
mail.selectMessage(function (msg) msg.mime2DecodedAuthor.toLowerCase().indexOf(author) == 0, true, true, true, count); mail.selectMessage(function (msg) msg.mime2DecodedAuthor.toLowerCase().indexOf(author) == 0, true, true, true, count);
} }
@@ -313,15 +290,12 @@ function Mail() //{{{
mappings.add(myModes, ["M"], mappings.add(myModes, ["M"],
"Compose a new message to the sender of selected mail", "Compose a new message to the sender of selected mail",
function () function () {
{ try {
try
{
let to = escapeRecipient(gDBView.hdrForFirstSelectedMessage.mime2DecodedAuthor); let to = escapeRecipient(gDBView.hdrForFirstSelectedMessage.mime2DecodedAuthor);
commandline.open(":", "mail " + to + " -subject=", modes.EX); commandline.open(":", "mail " + to + " -subject=", modes.EX);
} }
catch (e) catch (e) {
{
liberator.beep(); liberator.beep();
} }
}); });
@@ -366,8 +340,7 @@ function Mail() //{{{
// UNDO/REDO // UNDO/REDO
mappings.add(myModes, ["u"], mappings.add(myModes, ["u"],
"Undo", "Undo",
function () function () {
{
if (messenger.canUndo()) if (messenger.canUndo())
messenger.undo(msgWindow); messenger.undo(msgWindow);
else else
@@ -375,8 +348,7 @@ function Mail() //{{{
}); });
mappings.add(myModes, ["<C-r>"], mappings.add(myModes, ["<C-r>"],
"Redo", "Redo",
function () function () {
{
if (messenger.canRedo()) if (messenger.canRedo())
messenger.redo(msgWindow); messenger.redo(msgWindow);
else else
@@ -432,8 +404,7 @@ function Mail() //{{{
// FOLDER SWITCHING // FOLDER SWITCHING
mappings.add(myModes, ["gi"], mappings.add(myModes, ["gi"],
"Go to inbox", "Go to inbox",
function (count) function (count) {
{
let folder = mail.getFolders("Inbox", false, true)[(count > 0) ? (count - 1) : 0]; let folder = mail.getFolders("Inbox", false, true)[(count > 0) ? (count - 1) : 0];
if (folder) if (folder)
SelectFolder(folder.URI); SelectFolder(folder.URI);
@@ -444,12 +415,10 @@ function Mail() //{{{
mappings.add(myModes, ["<C-n>"], mappings.add(myModes, ["<C-n>"],
"Select next folder", "Select next folder",
function (count) function (count) {
{
count = Math.max(1, count); count = Math.max(1, count);
let newPos = getCurrentFolderIndex() + count; let newPos = getCurrentFolderIndex() + count;
if (newPos >= gFolderTreeView.rowCount) if (newPos >= gFolderTreeView.rowCount) {
{
newPos = newPos % gFolderTreeView.rowCount; newPos = newPos % gFolderTreeView.rowCount;
commandline.echo("search hit BOTTOM, continuing at TOP", commandline.HL_WARNINGMSG, commandline.APPEND_TO_MESSAGES); commandline.echo("search hit BOTTOM, continuing at TOP", commandline.HL_WARNINGMSG, commandline.APPEND_TO_MESSAGES);
} }
@@ -459,20 +428,17 @@ function Mail() //{{{
mappings.add(myModes, ["<C-N>"], mappings.add(myModes, ["<C-N>"],
"Go to next mailbox with unread messages", "Go to next mailbox with unread messages",
function (count) function (count) {
{
selectUnreadFolder(false, count); selectUnreadFolder(false, count);
}, },
{ count: true }); { count: true });
mappings.add(myModes, ["<C-p>"], mappings.add(myModes, ["<C-p>"],
"Select previous folder", "Select previous folder",
function (count) function (count) {
{
count = Math.max(1, count); count = Math.max(1, count);
let newPos = getCurrentFolderIndex() - count; let newPos = getCurrentFolderIndex() - count;
if (newPos < 0) if (newPos < 0) {
{
newPos = (newPos % gFolderTreeView.rowCount) + gFolderTreeView.rowCount; newPos = (newPos % gFolderTreeView.rowCount) + gFolderTreeView.rowCount;
commandline.echo("search hit TOP, continuing at BOTTOM", commandline.HL_WARNINGMSG, commandline.APPEND_TO_MESSAGES); commandline.echo("search hit TOP, continuing at BOTTOM", commandline.HL_WARNINGMSG, commandline.APPEND_TO_MESSAGES);
} }
@@ -482,8 +448,7 @@ function Mail() //{{{
mappings.add(myModes, ["<C-P>"], mappings.add(myModes, ["<C-P>"],
"Go to previous mailbox with unread messages", "Go to previous mailbox with unread messages",
function (count) function (count) {
{
selectUnreadFolder(true, count); selectUnreadFolder(true, count);
}, },
{ count: true }); { count: true });
@@ -532,13 +497,11 @@ function Mail() //{{{
// tagging messages // tagging messages
mappings.add(myModes, ["l"], mappings.add(myModes, ["l"],
"Label message", "Label message",
function (arg) function (arg) {
{
if (!GetSelectedMessages()) if (!GetSelectedMessages())
return void liberator.beep(); return void liberator.beep();
switch (arg) switch (arg) {
{
case "r": MsgMarkMsgAsRead(); break; case "r": MsgMarkMsgAsRead(); break;
case "s": MsgMarkAsFlagged(); break; case "s": MsgMarkAsFlagged(); break;
case "i": ToggleMessageTagKey(1); break; // Important case "i": ToggleMessageTagKey(1); break; // Important
@@ -556,8 +519,7 @@ function Mail() //{{{
// TODO: change binding? // TODO: change binding?
mappings.add(myModes, ["T"], mappings.add(myModes, ["T"],
"Mark current folder as read", "Mark current folder as read",
function () function () {
{
if (mail.currentFolder.isServer) if (mail.currentFolder.isServer)
return liberator.beep(); return liberator.beep();
@@ -566,16 +528,14 @@ function Mail() //{{{
mappings.add(myModes, ["<C-t>"], mappings.add(myModes, ["<C-t>"],
"Mark all messages as read", "Mark all messages as read",
function () function () {
{
mail.getFolders("", false).forEach(function (folder) { folder.markAllMessagesRead(msgWindow); }); mail.getFolders("", false).forEach(function (folder) { folder.markAllMessagesRead(msgWindow); });
}); });
// DISPLAY OPTIONS // DISPLAY OPTIONS
mappings.add(myModes, ["h"], mappings.add(myModes, ["h"],
"Toggle displayed headers", "Toggle displayed headers",
function () function () {
{
let value = gPrefBranch.getIntPref("mail.show_headers", 2); let value = gPrefBranch.getIntPref("mail.show_headers", 2);
gPrefBranch.setIntPref("mail.show_headers", value == 2 ? 1 : 2); gPrefBranch.setIntPref("mail.show_headers", value == 2 ? 1 : 2);
ReloadMessage(); ReloadMessage();
@@ -583,8 +543,7 @@ function Mail() //{{{
mappings.add(myModes, ["x"], mappings.add(myModes, ["x"],
"Toggle HTML message display", "Toggle HTML message display",
function () function () {
{
let wantHtml = (gPrefBranch.getIntPref("mailnews.display.html_as", 1) == 1); let wantHtml = (gPrefBranch.getIntPref("mailnews.display.html_as", 1) == 1);
mail.setHTML(wantHtml ? 1 : 0); mail.setHTML(wantHtml ? 1 : 0);
}); });
@@ -592,10 +551,8 @@ function Mail() //{{{
// YANKING TEXT // YANKING TEXT
mappings.add(myModes, ["Y"], mappings.add(myModes, ["Y"],
"Yank subject", "Yank subject",
function () function () {
{ try {
try
{
let subject = gDBView.hdrForFirstSelectedMessage.mime2DecodedSubject; let subject = gDBView.hdrForFirstSelectedMessage.mime2DecodedSubject;
util.copyToClipboard(subject, true); util.copyToClipboard(subject, true);
} }
@@ -604,10 +561,8 @@ function Mail() //{{{
mappings.add(myModes, ["y"], mappings.add(myModes, ["y"],
"Yank sender or feed URL", "Yank sender or feed URL",
function () function () {
{ try {
try
{
if (mail.currentAccount.server.type == "rss") if (mail.currentAccount.server.type == "rss")
util.copyToClipboard(getRSSUrl(), true); util.copyToClipboard(getRSSUrl(), true);
else else
@@ -619,16 +574,13 @@ function Mail() //{{{
// RSS specific mappings // RSS specific mappings
mappings.add(myModes, ["p"], mappings.add(myModes, ["p"],
"Open RSS message in browser", "Open RSS message in browser",
function () function () {
{ try {
try
{
if (mail.currentAccount.server.type == "rss") if (mail.currentAccount.server.type == "rss")
messenger.launchExternalURL(getRSSUrl()); messenger.launchExternalURL(getRSSUrl());
// TODO: what to do for non-rss message? // TODO: what to do for non-rss message?
} }
catch (e) catch (e) {
{
liberator.beep(); liberator.beep();
} }
}); });
@@ -639,8 +591,7 @@ function Mail() //{{{
commands.add(["go[to]"], commands.add(["go[to]"],
"Select a folder", "Select a folder",
function (args) function (args) {
{
let count = Math.max(0, args.count - 1); let count = Math.max(0, args.count - 1);
let arg = args.literalArg || "Inbox"; let arg = args.literalArg || "Inbox";
@@ -661,8 +612,7 @@ function Mail() //{{{
commands.add(["m[ail]"], commands.add(["m[ail]"],
"Write a new message", "Write a new message",
function (args) function (args) {
{
let mailargs = {}; let mailargs = {};
mailargs.to = args.join(", "); mailargs.to = args.join(", ");
mailargs.subject = args["-subject"]; mailargs.subject = args["-subject"];
@@ -746,13 +696,11 @@ function Mail() //{{{
get currentFolder() gFolderTreeView.getSelectedFolders()[0], get currentFolder() gFolderTreeView.getSelectedFolders()[0],
/** @property {nsISmtpServer[]} The list of configured SMTP servers. */ /** @property {nsISmtpServer[]} The list of configured SMTP servers. */
get smtpServers() get smtpServers() {
{
let servers = services.get("smtpService").smtpServers; let servers = services.get("smtpService").smtpServers;
let ret = []; let ret = [];
while (servers.hasMoreElements()) while (servers.hasMoreElements()) {
{
let server = servers.getNext(); let server = servers.getNext();
if (server instanceof Ci.nsISmtpServer) if (server instanceof Ci.nsISmtpServer)
ret.push(server); ret.push(server);
@@ -761,13 +709,11 @@ function Mail() //{{{
return ret; return ret;
}, },
composeNewMail: function (args) composeNewMail: function (args) {
{
let params = Cc["@mozilla.org/messengercompose/composeparams;1"].createInstance(Ci.nsIMsgComposeParams); let params = Cc["@mozilla.org/messengercompose/composeparams;1"].createInstance(Ci.nsIMsgComposeParams);
params.composeFields = Cc["@mozilla.org/messengercompose/composefields;1"].createInstance(Ci.nsIMsgCompFields); params.composeFields = Cc["@mozilla.org/messengercompose/composefields;1"].createInstance(Ci.nsIMsgCompFields);
if (args) if (args) {
{
if (args.originalMsg) if (args.originalMsg)
params.originalMsgURI = args.originalMsg; params.originalMsgURI = args.originalMsg;
if (args.to) if (args.to)
@@ -783,10 +729,8 @@ function Mail() //{{{
if (args.body) if (args.body)
params.composeFields.body = args.body; params.composeFields.body = args.body;
if (args.attachments) if (args.attachments) {
{ while (args.attachments.length > 0) {
while (args.attachments.length > 0)
{
let url = args.attachments.pop(); let url = args.attachments.pop();
let file = io.getFile(url); let file = io.getFile(url);
if (!file.exists()) if (!file.exists())
@@ -807,8 +751,7 @@ function Mail() //{{{
}, },
// returns an array of nsIMsgFolder objects // returns an array of nsIMsgFolder objects
getFolders: function (filter, includeServers, includeMsgFolders) getFolders: function (filter, includeServers, includeMsgFolders) {
{
let folders = []; let folders = [];
if (!filter) if (!filter)
filter = ""; filter = "";
@@ -820,8 +763,7 @@ function Mail() //{{{
if (includeMsgFolders === undefined) if (includeMsgFolders === undefined)
includeMsgFolders = true; includeMsgFolders = true;
for (let i = 0; i < gFolderTreeView.rowCount; i++) for (let i = 0; i < gFolderTreeView.rowCount; i++) {
{
let resource = gFolderTreeView._rowMap[i]._folder; let resource = gFolderTreeView._rowMap[i]._folder;
if ((resource.isServer && !includeServers) || (!resource.isServer && !includeMsgFolders)) if ((resource.isServer && !includeServers) || (!resource.isServer && !includeMsgFolders))
continue; continue;
@@ -836,22 +778,19 @@ function Mail() //{{{
return folders; return folders;
}, },
getNewMessages: function (currentAccountOnly) getNewMessages: function (currentAccountOnly) {
{
if (currentAccountOnly) if (currentAccountOnly)
MsgGetMessagesForAccount(); MsgGetMessagesForAccount();
else else
GetMessagesForAllAuthenticatedAccounts(); GetMessagesForAllAuthenticatedAccounts();
}, },
getStatistics: function (currentAccountOnly) getStatistics: function (currentAccountOnly) {
{
let accounts = currentAccountOnly ? [this.currentAccount] let accounts = currentAccountOnly ? [this.currentAccount]
: this.getFolders("", true, false); : this.getFolders("", true, false);
let unreadCount = 0, totalCount = 0, newCount = 0; let unreadCount = 0, totalCount = 0, newCount = 0;
for (let i = 0; i < accounts.length; i++) for (let i = 0; i < accounts.length; i++) {
{
let account = accounts[i]; let account = accounts[i];
unreadCount += account.getNumUnread(true); // true == deep (includes subfolders) unreadCount += account.getNumUnread(true); // true == deep (includes subfolders)
totalCount += account.getTotalMessages(true); totalCount += account.getTotalMessages(true);
@@ -861,14 +800,11 @@ function Mail() //{{{
return { numUnread: unreadCount, numTotal: totalCount, numNew: newCount }; return { numUnread: unreadCount, numTotal: totalCount, numNew: newCount };
}, },
collapseThread: function () collapseThread: function () {
{
let tree = GetThreadTree(); let tree = GetThreadTree();
if (tree) if (tree) {
{
let parent = parentIndex(tree.currentIndex); let parent = parentIndex(tree.currentIndex);
if (tree.changeOpenState(parent, false)) if (tree.changeOpenState(parent, false)) {
{
tree.view.selection.select(parent); tree.view.selection.select(parent);
tree.treeBoxObject.ensureRowIsVisible(parent); tree.treeBoxObject.ensureRowIsVisible(parent);
return true; return true;
@@ -877,11 +813,9 @@ function Mail() //{{{
return false; return false;
}, },
expandThread: function () expandThread: function () {
{
let tree = GetThreadTree(); let tree = GetThreadTree();
if (tree) if (tree) {
{
let row = tree.currentIndex; let row = tree.currentIndex;
if (row >= 0 && tree.changeOpenState(row, true)) if (row >= 0 && tree.changeOpenState(row, true))
return true; return true;
@@ -898,18 +832,15 @@ function Mail() //{{{
* @param {boolean} openThreads Should we open closed threads? * @param {boolean} openThreads Should we open closed threads?
* @param {boolean} reverse Change direction of searching. * @param {boolean} reverse Change direction of searching.
*/ */
selectMessage: function (validatorFunc, canWrap, openThreads, reverse, count) selectMessage: function (validatorFunc, canWrap, openThreads, reverse, count) {
{ function currentIndex() {
function currentIndex()
{
let index = gDBView.selection.currentIndex; let index = gDBView.selection.currentIndex;
if (index < 0) if (index < 0)
index = 0; index = 0;
return index; return index;
} }
function closedThread(index) function closedThread(index) {
{
if (!(gDBView.viewFlags & nsMsgViewFlagsType.kThreadedDisplay)) if (!(gDBView.viewFlags & nsMsgViewFlagsType.kThreadedDisplay))
return false; return false;
@@ -924,34 +855,28 @@ function Mail() //{{{
count = 1; count = 1;
// first try to find in current folder // first try to find in current folder
if (gDBView) if (gDBView) {
{
for (let i = currentIndex() + (reverse ? -1 : (openThreads && closedThread() ? 0 : 1)); for (let i = currentIndex() + (reverse ? -1 : (openThreads && closedThread() ? 0 : 1));
reverse ? (i >= 0) : (i < gDBView.rowCount); reverse ? (i >= 0) : (i < gDBView.rowCount);
reverse ? i-- : i++) reverse ? i-- : i++) {
{
let key = gDBView.getKeyAt(i); let key = gDBView.getKeyAt(i);
let msg = gDBView.db.GetMsgHdrForKey(key); let msg = gDBView.db.GetMsgHdrForKey(key);
// a closed thread // a closed thread
if (openThreads && closedThread(i)) if (openThreads && closedThread(i)) {
{
let thread = gDBView.db.GetThreadContainingMsgHdr(msg); let thread = gDBView.db.GetThreadContainingMsgHdr(msg);
let originalCount = count; let originalCount = count;
for (let j = (i == currentIndex() && !reverse) ? 1 : (reverse ? thread.numChildren - 1 : 0); for (let j = (i == currentIndex() && !reverse) ? 1 : (reverse ? thread.numChildren - 1 : 0);
reverse ? (j >= 0) : (j < thread.numChildren); reverse ? (j >= 0) : (j < thread.numChildren);
reverse ? j-- : j++) reverse ? j-- : j++) {
{
msg = thread.getChildAt(j); msg = thread.getChildAt(j);
if (validatorFunc(msg) && --count == 0) if (validatorFunc(msg) && --count == 0) {
{
// this hack is needed to get the correct message, because getChildAt() does not // this hack is needed to get the correct message, because getChildAt() does not
// necessarily return the messages in the order they are displayed // necessarily return the messages in the order they are displayed
gDBView.selection.timedSelect(i, GetThreadTree()._selectDelay || 500); gDBView.selection.timedSelect(i, GetThreadTree()._selectDelay || 500);
GetThreadTree().treeBoxObject.ensureRowIsVisible(i); GetThreadTree().treeBoxObject.ensureRowIsVisible(i);
if (j > 0) if (j > 0) {
{
GetThreadTree().changeOpenState(i, true); GetThreadTree().changeOpenState(i, true);
this.selectMessage(validatorFunc, false, false, false, originalCount); this.selectMessage(validatorFunc, false, false, false, originalCount);
} }
@@ -959,10 +884,8 @@ function Mail() //{{{
} }
} }
} }
else // simple non-threaded message else { // simple non-threaded message
{ if (validatorFunc(msg) && --count == 0) {
if (validatorFunc(msg) && --count == 0)
{
gDBView.selection.timedSelect(i, GetThreadTree()._selectDelay || 500); gDBView.selection.timedSelect(i, GetThreadTree()._selectDelay || 500);
GetThreadTree().treeBoxObject.ensureRowIsVisible(i); GetThreadTree().treeBoxObject.ensureRowIsVisible(i);
return; return;
@@ -972,14 +895,12 @@ function Mail() //{{{
} }
// then in other folders // then in other folders
if (canWrap) if (canWrap) {
{
selectMessageReverse = reverse; selectMessageReverse = reverse;
let folders = this.getFolders("", true, true); let folders = this.getFolders("", true, true);
let ci = getCurrentFolderIndex(); let ci = getCurrentFolderIndex();
for (let i = 1; i < folders.length; i++) for (let i = 1; i < folders.length; i++) {
{
let index = (i + ci) % folders.length; let index = (i + ci) % folders.length;
if (reverse) if (reverse)
index = folders.length - 1 - index; index = folders.length - 1 - index;
@@ -993,29 +914,24 @@ function Mail() //{{{
// sometimes folder.getMessages can fail with an exception // sometimes folder.getMessages can fail with an exception
// TODO: find out why, and solve the problem // TODO: find out why, and solve the problem
try try {
{
var msgs = folder.messages; var msgs = folder.messages;
} }
catch (e) catch (e) {
{
msgs = folder.getMessages(msgWindow); // for older thunderbirds msgs = folder.getMessages(msgWindow); // for older thunderbirds
liberator.dump("WARNING: " + folder.prettyName + " failed to getMessages, trying old API"); liberator.dump("WARNING: " + folder.prettyName + " failed to getMessages, trying old API");
//continue; //continue;
} }
while (msgs.hasMoreElements()) while (msgs.hasMoreElements()) {
{
let msg = msgs.getNext().QueryInterface(Ci.nsIMsgDBHdr); let msg = msgs.getNext().QueryInterface(Ci.nsIMsgDBHdr);
if (validatorFunc(msg)) if (validatorFunc(msg)) {
{
count--; count--;
selectMessageKeys.push(msg.messageKey); selectMessageKeys.push(msg.messageKey);
} }
} }
if (count <= 0) if (count <= 0) {
{
// SelectFolder is asynchronous, message is selected in folderListener // SelectFolder is asynchronous, message is selected in folderListener
SelectFolder(folder.URI); SelectFolder(folder.URI);
return; return;
@@ -1028,8 +944,7 @@ function Mail() //{{{
liberator.beep(); liberator.beep();
}, },
setHTML: function (value) setHTML: function (value) {
{
let values = [[true, 1, gDisallow_classes_no_html], // plaintext let values = [[true, 1, gDisallow_classes_no_html], // plaintext
[false, 0, 0], // HTML [false, 0, 0], // HTML
[false, 3, gDisallow_classes_no_html]]; // sanitized/simple HTML [false, 3, gDisallow_classes_no_html]]; // sanitized/simple HTML

View File

@@ -25,8 +25,7 @@ AboutHandler.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]), QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
newChannel: function (uri) newChannel: function (uri) {
{
let channel = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService) let channel = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService)
.newChannel("chrome://" + name + "/content/about.html", null, null); .newChannel("chrome://" + name + "/content/about.html", null, null);
@@ -38,6 +37,6 @@ AboutHandler.prototype = {
getURIFlags: function (uri) Ci.nsIAboutModule.ALLOW_SCRIPT, getURIFlags: function (uri) Ci.nsIAboutModule.ALLOW_SCRIPT,
}; };
function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([AboutHandler]); function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([AboutHandler])
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -11,8 +11,7 @@ const Name = "Vimperator";
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const name = Name.toLowerCase(); const name = Name.toLowerCase();
function CommandLineHandler() function CommandLineHandler() {
{
this.wrappedJSObject = this; this.wrappedJSObject = this;
} }
CommandLineHandler.prototype = { CommandLineHandler.prototype = {
@@ -30,20 +29,17 @@ CommandLineHandler.prototype = {
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler]), QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler]),
handle: function (commandLine) handle: function (commandLine) {
{
// TODO: handle remote launches differently? // TODO: handle remote launches differently?
try try {
{
this.optionValue = commandLine.handleFlagWithParam(name, false); this.optionValue = commandLine.handleFlagWithParam(name, false);
} }
catch (e) catch (e) {
{
//"vimperator: option -vimperator requires an argument" //"vimperator: option -vimperator requires an argument"
} }
} }
}; };
function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([CommandLineHandler]); function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([CommandLineHandler])
// vim: set ft=javascript fdm=marker sw=4 ts=4 et: // vim: set ft=javascript fdm=marker sw=4 ts=4 et:

View File

@@ -119,8 +119,7 @@ const config = { //{{{
get tempFile() { get tempFile() {
let prefix = this.name.toLowerCase(); let prefix = this.name.toLowerCase();
try try {
{
prefix += "-" + window.content.document.location.hostname; prefix += "-" + window.content.document.location.hostname;
} }
catch (e) {} catch (e) {}
@@ -128,12 +127,10 @@ const config = { //{{{
return prefix + ".tmp"; return prefix + ".tmp";
}, },
init: function () init: function () {
{
commands.add(["winon[ly]"], commands.add(["winon[ly]"],
"Close all other windows", "Close all other windows",
function () function () {
{
liberator.windows.forEach(function (win) { liberator.windows.forEach(function (win) {
if (win != window) if (win != window)
win.close(); win.close();
@@ -143,10 +140,8 @@ const config = { //{{{
commands.add(["pref[erences]", "prefs"], commands.add(["pref[erences]", "prefs"],
"Show " + config.hostApplication + " preferences", "Show " + config.hostApplication + " preferences",
function (args) function (args) {
{ if (args.bang) { // open Firefox settings GUI dialog
if (args.bang) // open Firefox settings GUI dialog
{
liberator.open("about:config", liberator.open("about:config",
(options["newtab"] && options.get("newtab").has("all", "prefs")) (options["newtab"] && options.get("newtab").has("all", "prefs"))
? liberator.NEW_TAB : liberator.CURRENT_TAB); ? liberator.NEW_TAB : liberator.CURRENT_TAB);
@@ -161,8 +156,7 @@ const config = { //{{{
commands.add(["sbcl[ose]"], commands.add(["sbcl[ose]"],
"Close the sidebar window", "Close the sidebar window",
function () function () {
{
if (!document.getElementById("sidebar-box").hidden) if (!document.getElementById("sidebar-box").hidden)
window.toggleSidebar(); window.toggleSidebar();
}, },
@@ -170,24 +164,20 @@ const config = { //{{{
commands.add(["sideb[ar]", "sb[ar]", "sbope[n]"], commands.add(["sideb[ar]", "sb[ar]", "sbope[n]"],
"Open the sidebar window", "Open the sidebar window",
function (args) function (args) {
{
let arg = args.literalArg; let arg = args.literalArg;
function compare(a, b) util.compareIgnoreCase(a, b) == 0 function compare(a, b) util.compareIgnoreCase(a, b) == 0
// focus if the requested sidebar is already open // focus if the requested sidebar is already open
if (compare(document.getElementById("sidebar-title").value, arg)) if (compare(document.getElementById("sidebar-title").value, arg)) {
{
document.getElementById("sidebar-box").focus(); document.getElementById("sidebar-box").focus();
return; return;
} }
let menu = document.getElementById("viewSidebarMenu"); let menu = document.getElementById("viewSidebarMenu");
for (let [, panel] in Iterator(menu.childNodes)) for (let [, panel] in Iterator(menu.childNodes)) {
{ if (compare(panel.label, arg)) {
if (compare(panel.label, arg))
{
panel.doCommand(); panel.doCommand();
return; return;
} }
@@ -197,8 +187,7 @@ const config = { //{{{
}, },
{ {
argCount: "1", argCount: "1",
completer: function (context) completer: function (context) {
{
context.ignoreCase = true; context.ignoreCase = true;
return completion.sidebar(context); return completion.sidebar(context);
}, },
@@ -207,8 +196,7 @@ const config = { //{{{
commands.add(["wind[ow]"], commands.add(["wind[ow]"],
"Execute a command and tell it to output in a new window", "Execute a command and tell it to output in a new window",
function (args) function (args) {
{
liberator.forceNewWindow = true; liberator.forceNewWindow = true;
liberator.execute(args.string, null, true); liberator.execute(args.string, null, true);
liberator.forceNewWindow = false; liberator.forceNewWindow = false;
@@ -226,8 +214,7 @@ const config = { //{{{
commands.add(["wino[pen]", "wo[pen]", "wine[dit]"], commands.add(["wino[pen]", "wo[pen]", "wine[dit]"],
"Open one or more URLs in a new window", "Open one or more URLs in a new window",
function (args) function (args) {
{
args = args.string; args = args.string;
if (args) if (args)
@@ -249,8 +236,7 @@ const config = { //{{{
"Set the 'work offline' option", "Set the 'work offline' option",
"boolean", true, "boolean", true,
{ {
setter: function (value) setter: function (value) {
{
const ioService = services.get("io"); const ioService = services.get("io");
if (ioService.offline == value) if (ioService.offline == value)
BrowserOffline.toggleOfflineStatus(); BrowserOffline.toggleOfflineStatus();
@@ -289,8 +275,7 @@ const config = { //{{{
services.get("autoCompleteSearch").startSearch(context.filter, "", context.result, { services.get("autoCompleteSearch").startSearch(context.filter, "", context.result, {
onSearchResult: function onSearchResult(search, result) { onSearchResult: function onSearchResult(search, result) {
timer.tell(result); timer.tell(result);
if (result.searchResult <= result.RESULT_SUCCESS) if (result.searchResult <= result.RESULT_SUCCESS) {
{
searchRunning = false; searchRunning = false;
timer.flush(); timer.flush();
} }

View File

@@ -4,8 +4,7 @@
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
function checkFragment() function checkFragment() {
{
let frag = document.location.hash.substr(1); let frag = document.location.hash.substr(1);
if (!frag || document.getElementById(frag)) if (!frag || document.getElementById(frag))
return; return;

View File

@@ -76,8 +76,7 @@ let functions = [
// even after doing major Vimperator refactoring // even after doing major Vimperator refactoring
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
function resetEnvironment() function resetEnvironment() {
{
multilineOutput.contentDocument.body.innerHTML = ""; multilineOutput.contentDocument.body.innerHTML = "";
singlelineOutput.value = ""; singlelineOutput.value = "";
commandline.close(); commandline.close();
@@ -91,8 +90,7 @@ function getSinglelineOutput() singlelineOutput.value;
function getTabIndex() getBrowser().mTabContainer.selectedIndex; function getTabIndex() getBrowser().mTabContainer.selectedIndex;
function getTabCount() getBrowser().mTabs.length; function getTabCount() getBrowser().mTabs.length;
function getBufferPosition() function getBufferPosition() {
{
let win = window.content; let win = window.content;
return { x: win.scrollMaxX ? win.pageXOffset / win.scrollMaxX : 0, return { x: win.scrollMaxX ? win.pageXOffset / win.scrollMaxX : 0,
y: win.scrollMaxY ? win.pageYOffset / win.scrollMaxY : 0 } y: win.scrollMaxY ? win.pageYOffset / win.scrollMaxY : 0 }
@@ -100,8 +98,7 @@ function getBufferPosition()
function getLocation() window.content.document.location.href; function getLocation() window.content.document.location.href;
function echoLine(str, group) function echoLine(str, group) {
{
if (!doc) if (!doc)
return; return;
@@ -109,8 +106,7 @@ function echoLine(str, group)
<div highlight={group} style="border: 1px solid gray; white-space: pre; height: 1.5em; line-height: 1.5em;">{str}</div>, <div highlight={group} style="border: 1px solid gray; white-space: pre; height: 1.5em; line-height: 1.5em;">{str}</div>,
doc)); doc));
} }
function echoMulti(str, group) function echoMulti(str, group) {
{
if (!doc) if (!doc)
return; return;
@@ -122,8 +118,7 @@ function echoMulti(str, group)
commands.addUserCommand(["regr[essions]"], commands.addUserCommand(["regr[essions]"],
"Run regression tests", "Run regression tests",
function (args) function (args) {
{
// TODO: might need to increase the 'messages' option temporarily // TODO: might need to increase the 'messages' option temporarily
// TODO: count (better even range) support to just run test 34 of 102 // TODO: count (better even range) support to just run test 34 of 102
// TODO: bang support to either: a) run commands like deleting bookmarks which // TODO: bang support to either: a) run commands like deleting bookmarks which
@@ -131,8 +126,7 @@ commands.addUserCommand(["regr[essions]"],
// just Ex command tests; Yet to be decided // just Ex command tests; Yet to be decided
let updateOutputHeight = null; let updateOutputHeight = null;
function init() function init() {
{
liberator.registerObserver("echoLine", echoLine); liberator.registerObserver("echoLine", echoLine);
liberator.registerObserver("echoMultiline", echoMulti); liberator.registerObserver("echoMultiline", echoMulti);
liberator.open("chrome://liberator/content/buffer.xhtml", liberator.NEW_TAB); liberator.open("chrome://liberator/content/buffer.xhtml", liberator.NEW_TAB);
@@ -141,23 +135,20 @@ commands.addUserCommand(["regr[essions]"],
doc.body.setAttributeNS(NS.uri, "highlight", "CmdLine"); doc.body.setAttributeNS(NS.uri, "highlight", "CmdLine");
updateOutputHeight = commandline.updateOutputHeight; updateOutputHeight = commandline.updateOutputHeight;
commandline.updateOutputHeight = function (open) commandline.updateOutputHeight = function (open) {
{
let elem = document.getElementById("liberator-multiline-output"); let elem = document.getElementById("liberator-multiline-output");
if (open) if (open)
elem.collapsed = false; elem.collapsed = false;
elem.height = 0; elem.height = 0;
}; };
} }
function cleanup() function cleanup() {
{
liberator.unregisterObserver("echoLine", echoLine); liberator.unregisterObserver("echoLine", echoLine);
liberator.unregisterObserver("echoMultiline", echoMulti); liberator.unregisterObserver("echoMultiline", echoMulti);
commandline.updateOutputHeight = updateOutputHeight; commandline.updateOutputHeight = updateOutputHeight;
} }
function run() function run() {
{
let now = Date.now(); let now = Date.now();
let totalTests = tests.length + functions.length; let totalTests = tests.length + functions.length;
let successfulTests = 0; let successfulTests = 0;
@@ -169,17 +160,14 @@ commands.addUserCommand(["regr[essions]"],
// TODO: might want to unify 'tests' and 'functions' handling // TODO: might want to unify 'tests' and 'functions' handling
// 1.) run commands and mappings tests // 1.) run commands and mappings tests
outer: outer:
for (let [, test] in Iterator(tests)) for (let [, test] in Iterator(tests)) {
{
currentTest++; currentTest++;
if (args.count >= 1 && currentTest != args.count) if (args.count >= 1 && currentTest != args.count)
continue; continue;
let testDescription = util.clip(test.cmds.join(" -> "), 80); let testDescription = util.clip(test.cmds.join(" -> "), 80);
for (let [, cmd] in Iterator(test.cmds)) for (let [, cmd] in Iterator(test.cmds)) {
{ if (skipTests.indexOf(cmd) != -1) {
if (skipTests.indexOf(cmd) != -1)
{
skippedTests++; skippedTests++;
liberator.echomsg("Skipping test " + currentTest + " of " + totalTests + ": " + testDescription, 0); liberator.echomsg("Skipping test " + currentTest + " of " + totalTests + ": " + testDescription, 0);
continue outer; continue outer;
@@ -205,8 +193,7 @@ commands.addUserCommand(["regr[essions]"],
} }
// 2.) Run function tests // 2.) Run function tests
for (let [, func] in Iterator(functions)) for (let [, func] in Iterator(functions)) {
{
currentTest++; currentTest++;
if (args.count >= 1 && currentTest != args.count) if (args.count >= 1 && currentTest != args.count)
continue; continue;
@@ -232,8 +219,7 @@ commands.addUserCommand(["regr[essions]"],
liberator.execute(":messages"); liberator.execute(":messages");
} }
if (!args.bang) if (!args.bang) {
{
liberator.echo(<e4x> liberator.echo(<e4x>
<span style="font-weight: bold">Running tests should always be done in a new profile.</span><br/> <span style="font-weight: bold">Running tests should always be done in a new profile.</span><br/>

View File

@@ -25,19 +25,16 @@ AboutHandler.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]), QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
newChannel: function (uri) newChannel: function (uri) {
{
let channel = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService) let channel = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService)
.newChannel("chrome://" + name + "/content/about.html", null, null); .newChannel("chrome://" + name + "/content/about.html", null, null);
channel.originalURI = uri; channel.originalURI = uri;
return channel; return channel;
}, },
getURIFlags: function (uri) Ci.nsIAboutModule.ALLOW_SCRIPT, getURIFlags: function (uri) Ci.nsIAboutModule.ALLOW_SCRIPT,
}; };
function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([AboutHandler]); function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([AboutHandler])
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -11,8 +11,7 @@ const Name = "Xulmus";
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const name = Name.toLowerCase(); const name = Name.toLowerCase();
function CommandLineHandler() function CommandLineHandler() {
{
this.wrappedJSObject = this; this.wrappedJSObject = this;
} }
CommandLineHandler.prototype = { CommandLineHandler.prototype = {
@@ -30,20 +29,17 @@ CommandLineHandler.prototype = {
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler]), QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsICommandLineHandler]),
handle: function (commandLine) handle: function (commandLine) {
{
// TODO: handle remote launches differently? // TODO: handle remote launches differently?
try try {
{
this.optionValue = commandLine.handleFlagWithParam(name, false); this.optionValue = commandLine.handleFlagWithParam(name, false);
} }
catch (e) catch (e) {
{
//"vimperator: option -vimperator requires an argument" //"vimperator: option -vimperator requires an argument"
} }
} }
}; };
function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([CommandLineHandler]); function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([CommandLineHandler])
// vim: set ft=javascript fdm=marker sw=4 ts=4 et: // vim: set ft=javascript fdm=marker sw=4 ts=4 et:

View File

@@ -124,8 +124,7 @@ const config = { //{{{
function () { SBSubscribe(); }] function () { SBSubscribe(); }]
], ],
focusChange: function () focusChange: function () {
{
// Switch to -- PLAYER -- mode for Songbird Media Player. // Switch to -- PLAYER -- mode for Songbird Media Player.
if (config.isPlayerWindow) if (config.isPlayerWindow)
liberator.mode = modes.PLAYER; liberator.mode = modes.PLAYER;
@@ -156,19 +155,16 @@ const config = { //{{{
], ],
// FIXME: tab arg and media tab exception? // FIXME: tab arg and media tab exception?
stop: function (tab) stop: function (tab) {
{
SBGetBrowser().mCurrentBrowser.stop(); SBGetBrowser().mCurrentBrowser.stop();
}, },
init: function () init: function () {
{
// Adding a mode for Player // Adding a mode for Player
//modes.addMode("PLAYER"); // Player mode for songbird //modes.addMode("PLAYER"); // Player mode for songbird
// TODO: support 'nrformats'? -> probably not worth it --mst // TODO: support 'nrformats'? -> probably not worth it --mst
function incrementURL(count) function incrementURL(count) {
{
let matches = buffer.URL.match(/(.*?)(\d+)(\D*)$/); let matches = buffer.URL.match(/(.*?)(\d+)(\D*)$/);
if (!matches) if (!matches)
return void liberator.beep(); return void liberator.beep();
@@ -176,8 +172,7 @@ const config = { //{{{
let [, pre, number, post] = matches; let [, pre, number, post] = matches;
let newNumber = parseInt(number, 10) + count; let newNumber = parseInt(number, 10) + count;
let newNumberStr = String(newNumber > 0 ? newNumber : 0); let newNumberStr = String(newNumber > 0 ? newNumber : 0);
if (number.match(/^0/)) // add 0009<C-a> should become 0010 if (number.match(/^0/)) { // add 0009<C-a> should become 0010
{
while (newNumberStr.length < number.length) while (newNumberStr.length < number.length)
newNumberStr = "0" + newNumberStr; newNumberStr = "0" + newNumberStr;
} }
@@ -185,19 +180,16 @@ const config = { //{{{
liberator.open(pre + newNumberStr + post); liberator.open(pre + newNumberStr + post);
} }
function showServicePane(value) function showServicePane(value) {
{
const key = "splitter.servicepane_splitter.was_collapsed"; const key = "splitter.servicepane_splitter.was_collapsed";
gServicePane.open = value; gServicePane.open = value;
SBDataSetBoolValue(key, gServicePane.open); SBDataSetBoolValue(key, gServicePane.open);
} }
function openDisplayPane(id) function openDisplayPane(id) {
{
if (id == "servicepane") if (id == "servicepane")
showServicePane(true); showServicePane(true);
else else {
{
let pane = document.getElementById(id); let pane = document.getElementById(id);
let manager = Cc['@songbirdnest.com/Songbird/DisplayPane/Manager;1'].getService(Ci.sbIDisplayPaneManager); let manager = Cc['@songbirdnest.com/Songbird/DisplayPane/Manager;1'].getService(Ci.sbIDisplayPaneManager);
let paneinfo = manager.getPaneInfo(pane._lastURL.stringValue); let paneinfo = manager.getPaneInfo(pane._lastURL.stringValue);
@@ -209,8 +201,7 @@ const config = { //{{{
} }
} }
function closeDisplayPane(id) function closeDisplayPane(id) {
{
if (id == "servicepane") if (id == "servicepane")
showServicePane(false); showServicePane(false);
else else
@@ -270,8 +261,7 @@ const config = { //{{{
commands.add(["dpcl[ose]"], commands.add(["dpcl[ose]"],
"Close a display pane", "Close a display pane",
function (args) function (args) {
{
let arg = args.literalArg; let arg = args.literalArg;
if (arg in displayPanes) if (arg in displayPanes)
@@ -289,8 +279,7 @@ const config = { //{{{
// TODO: this should accept a second arg to specify content // TODO: this should accept a second arg to specify content
commands.add(["displayp[ane]", "dp[ane]", "dpope[n]"], commands.add(["displayp[ane]", "dp[ane]", "dpope[n]"],
"Open a display pane", "Open a display pane",
function (args) function (args) {
{
let arg = args.literalArg; let arg = args.literalArg;
if (arg in displayPanes) if (arg in displayPanes)
@@ -307,10 +296,8 @@ const config = { //{{{
commands.add(["pref[erences]", "prefs"], commands.add(["pref[erences]", "prefs"],
"Show " + config.hostApplication + " preferences", "Show " + config.hostApplication + " preferences",
function (args) function (args) {
{ if (args.bang) { // open Songbird settings GUI dialog
if (args.bang) // open Songbird settings GUI dialog
{
liberator.open("about:config", liberator.open("about:config",
(options["newtab"] && options.get("newtab").has("all", "prefs")) (options["newtab"] && options.get("newtab").has("all", "prefs"))
? liberator.NEW_TAB : liberator.CURRENT_TAB); ? liberator.NEW_TAB : liberator.CURRENT_TAB);
@@ -332,8 +319,7 @@ const config = { //{{{
"Set the 'work offline' option", "Set the 'work offline' option",
"boolean", true, "boolean", true,
{ {
setter: function (value) setter: function (value) {
{
const ioService = services.get("io"); const ioService = services.get("io");
ioService.offline = !value; ioService.offline = !value;
options.setPref("browser.offline", ioService.offline); options.setPref("browser.offline", ioService.offline);

View File

@@ -4,8 +4,8 @@
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
function Library() //{{{ function Library() { //{{{
{
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -14,8 +14,7 @@ function Library() //{{{
function toJSArray(enum) ArrayConverter.JSArray(enum) function toJSArray(enum) ArrayConverter.JSArray(enum)
function getArtistsArray() function getArtistsArray() {
{
return toJSArray(MAIN_LIBRARY.getDistinctValuesForProperty(SBProperties.artistName)); return toJSArray(MAIN_LIBRARY.getDistinctValuesForProperty(SBProperties.artistName));
} }
@@ -44,8 +43,7 @@ function Library() //{{{
* @param {param} artist The artist name. * @param {param} artist The artist name.
* @returns {string[]} * @returns {string[]}
*/ */
getAlbums: function getAlbums(artist) getAlbums: function getAlbums(artist) {
{
let albums = toJSArray(MAIN_LIBRARY.getItemsByProperty(SBProperties.artistName, artist)) let albums = toJSArray(MAIN_LIBRARY.getItemsByProperty(SBProperties.artistName, artist))
.map(function (track) track.getProperty(SBProperties.albumName)); .map(function (track) track.getProperty(SBProperties.albumName));
return util.Array.uniq(albums); return util.Array.uniq(albums);
@@ -59,8 +57,7 @@ function Library() //{{{
* @param {param} album The album name. * @param {param} album The album name.
* @returns {string[]} * @returns {string[]}
*/ */
getTracks: function getTracks(artist, album) getTracks: function getTracks(artist, album) {
{
const properties = Cc["@songbirdnest.com/Songbird/Properties/MutablePropertyArray;1"] const properties = Cc["@songbirdnest.com/Songbird/Properties/MutablePropertyArray;1"]
.createInstance(Ci.sbIMutablePropertyArray); .createInstance(Ci.sbIMutablePropertyArray);

View File

@@ -4,8 +4,8 @@
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
function Player() //{{{ function Player() { //{{{
{
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -26,22 +26,18 @@ function Player() //{{{
commandline.registerCallback("cancel", modes.SEARCH_VIEW_FORWARD, function () { player.onSearchCancel(); }); commandline.registerCallback("cancel", modes.SEARCH_VIEW_FORWARD, function () { player.onSearchCancel(); });
// interval (milliseconds) // interval (milliseconds)
function seek(interval, direction) function seek(interval, direction) {
{
let position = gMM.playbackControl ? gMM.playbackControl.position : 0; let position = gMM.playbackControl ? gMM.playbackControl.position : 0;
player.seekTo(position + (direction ? interval : -interval)); player.seekTo(position + (direction ? interval : -interval));
} }
function focusTrack(mediaItem) function focusTrack(mediaItem) {
{
SBGetBrowser().mediaTab.mediaPage.highlightItem(_SBGetCurrentView().getIndexForItem(mediaItem)); SBGetBrowser().mediaTab.mediaPage.highlightItem(_SBGetCurrentView().getIndexForItem(mediaItem));
} }
var mediaCoreListener = { var mediaCoreListener = {
onMediacoreEvent: function (event) onMediacoreEvent: function (event) {
{ switch (event.type) {
switch (event.type)
{
case Ci.sbIMediacoreEvent.BEFORE_TRACK_CHANGE: case Ci.sbIMediacoreEvent.BEFORE_TRACK_CHANGE:
liberator.log("Before track changed: " + event.data); liberator.log("Before track changed: " + event.data);
autocommands.trigger("TrackChangePre", { track: event.data }); autocommands.trigger("TrackChangePre", { track: event.data });
@@ -193,8 +189,7 @@ function Player() //{{{
["N"], "Find the previous track", ["N"], "Find the previous track",
function () { player.searchViewAgain(true);}); function () { player.searchViewAgain(true);});
for (let i in util.range(0, 6)) for (let i in util.range(0, 6)) {
{
let (rating = i) { let (rating = i) {
mappings.add([modes.PLAYER], mappings.add([modes.PLAYER],
["<C-" + rating + ">"], "Rate the current media item " + rating, ["<C-" + rating + ">"], "Rate the current media item " + rating,
@@ -208,15 +203,13 @@ function Player() //{{{
commands.add(["f[ilter]"], commands.add(["f[ilter]"],
"Filter tracks based on keywords {genre/artist/album/track}", "Filter tracks based on keywords {genre/artist/album/track}",
function (args) function (args) {
{
let library = LibraryUtils.mainLibrary; let library = LibraryUtils.mainLibrary;
let view = LibraryUtils.createStandardMediaListView(LibraryUtils.mainLibrary, args.literalArg); let view = LibraryUtils.createStandardMediaListView(LibraryUtils.mainLibrary, args.literalArg);
if (view.length == 0) if (view.length == 0)
liberator.echoerr("No Tracks matching the keywords"); liberator.echoerr("No Tracks matching the keywords");
else else {
{
SBGetBrowser().loadMediaList(LibraryUtils.mainLibrary, null, null, view, SBGetBrowser().loadMediaList(LibraryUtils.mainLibrary, null, null, view,
"chrome://songbird/content/mediapages/filtersPage.xul"); "chrome://songbird/content/mediapages/filtersPage.xul");
// TODO: make this focusTrack work ? // TODO: make this focusTrack work ?
@@ -231,19 +224,15 @@ function Player() //{{{
commands.add(["load"], commands.add(["load"],
"Load a playlist", "Load a playlist",
function (args) function (args) {
{
let arg = args.literalArg; let arg = args.literalArg;
if (arg) if (arg) {
{
// load the selected playlist/smart playlist // load the selected playlist/smart playlist
let playlists = player.getPlaylists(); let playlists = player.getPlaylists();
for ([i, list] in Iterator(playlists)) for ([i, list] in Iterator(playlists)) {
{ if (util.compareIgnoreCase(arg, list.name) == 0) {
if (util.compareIgnoreCase(arg, list.name) == 0)
{
SBGetBrowser().loadMediaList(playlists[i]); SBGetBrowser().loadMediaList(playlists[i]);
focusTrack(_SBGetCurrentView().getItemByIndex(0)); focusTrack(_SBGetCurrentView().getItemByIndex(0));
return; return;
@@ -252,8 +241,7 @@ function Player() //{{{
liberator.echoerr("E475: Invalid argument: " + arg); liberator.echoerr("E475: Invalid argument: " + arg);
} }
else else {
{
// load main library if there are no args // load main library if there are no args
_SBShowMainLibrary(); _SBShowMainLibrary();
} }
@@ -287,8 +275,7 @@ function Player() //{{{
commands.add(["see[k]"], commands.add(["see[k]"],
"Seek to a track position", "Seek to a track position",
function (args) function (args) {
{
let arg = args[0]; let arg = args[0];
// intentionally supports 999:99:99 // intentionally supports 999:99:99
@@ -297,14 +284,12 @@ function Player() //{{{
function ms(t, m) Math.abs(parseInt(t, 10) * { s: 1000, m: 60000, h: 3600000 }[m]) function ms(t, m) Math.abs(parseInt(t, 10) * { s: 1000, m: 60000, h: 3600000 }[m])
if (/:/.test(arg)) if (/:/.test(arg)) {
{
let [seconds, minutes, hours] = arg.split(":").reverse(); let [seconds, minutes, hours] = arg.split(":").reverse();
hours = hours || 0; hours = hours || 0;
var value = ms(seconds, "s") + ms(minutes, "m") + ms(hours, "h"); var value = ms(seconds, "s") + ms(minutes, "m") + ms(hours, "h");
} }
else else {
{
if (!/[smh]/.test(arg.substr(-1))) if (!/[smh]/.test(arg.substr(-1)))
arg += "s"; // default to seconds arg += "s"; // default to seconds
@@ -321,22 +306,18 @@ function Player() //{{{
commands.add(["mediav[iew]"], commands.add(["mediav[iew]"],
"Change the current media view", "Change the current media view",
function (args) function (args) {
{
// FIXME: is this a SB restriction? --djk // FIXME: is this a SB restriction? --djk
if (!gBrowser.currentMediaPage) if (!gBrowser.currentMediaPage)
return void liberator.echoerr("Exxx: Can only set the media view from the media tab"); // XXX return void liberator.echoerr("Exxx: Can only set the media view from the media tab"); // XXX
let arg = args[0]; let arg = args[0];
if (arg) if (arg) {
{
let pages = player.getMediaPages(); let pages = player.getMediaPages();
for ([, page] in Iterator(pages)) for ([, page] in Iterator(pages)) {
{ if (util.compareIgnoreCase(arg, page.contentTitle) == 0) {
if (util.compareIgnoreCase(arg, page.contentTitle) == 0)
{
player.loadMediaPage(page, gBrowser.currentMediaListView.mediaList, gBrowser.currentMediaListView); player.loadMediaPage(page, gBrowser.currentMediaListView.mediaList, gBrowser.currentMediaListView);
return; return;
} }
@@ -353,8 +334,7 @@ function Player() //{{{
commands.add(["sort[view]"], commands.add(["sort[view]"],
"Sort the current media view", "Sort the current media view",
function (args) function (args) {
{
player.sortBy(args, true); player.sortBy(args, true);
}); });
@@ -362,8 +342,7 @@ function Player() //{{{
// FIXME: use :add -q like cmus? (not very vim-like are it's multi-option commands) --djk // FIXME: use :add -q like cmus? (not very vim-like are it's multi-option commands) --djk
commands.add(["qu[eue]"], commands.add(["qu[eue]"],
"Queue tracks by artist/album/track", "Queue tracks by artist/album/track",
function (args) function (args) {
{
// Store the old view // Store the old view
// let prev_view = gMM.status.view; // let prev_view = gMM.status.view;
let library = LibraryUtils.mainLibrary; let library = LibraryUtils.mainLibrary;
@@ -372,8 +351,7 @@ function Player() //{{{
.createInstance(Ci.sbIMutablePropertyArray); .createInstance(Ci.sbIMutablePropertyArray);
// args // args
switch (args.length) switch (args.length) {
{
case 3: case 3:
customProps.appendProperty(SBProperties.trackName, args[2]); customProps.appendProperty(SBProperties.trackName, args[2]);
case 2: case 2:
@@ -396,8 +374,7 @@ function Player() //{{{
// TODO: maybe :vol! could toggle mute on/off? --djk // TODO: maybe :vol! could toggle mute on/off? --djk
commands.add(["vol[ume]"], commands.add(["vol[ume]"],
"Set the volume", "Set the volume",
function (args) function (args) {
{
let arg = args[0]; let arg = args[0];
if (!/^[+-]?\d+$/.test(arg)) if (!/^[+-]?\d+$/.test(arg))
@@ -421,18 +398,15 @@ function Player() //{{{
function map(list) list.map(function (i) [i, ""]); function map(list) list.map(function (i) [i, ""]);
let [artist, album] = [args[0], args[1]]; let [artist, album] = [args[0], args[1]];
if (args.completeArg == 0) if (args.completeArg == 0) {
{
context.title = ["Artists"]; context.title = ["Artists"];
context.completions = map(library.getArtists()); context.completions = map(library.getArtists());
} }
else if (args.completeArg == 1) else if (args.completeArg == 1) {
{
context.title = ["Albums by " + artist]; context.title = ["Albums by " + artist];
context.completions = map(library.getAlbums(artist)); context.completions = map(library.getAlbums(artist));
} }
else if (args.completeArg == 2) else if (args.completeArg == 2) {
{
context.title = ["Tracks from " + album + " by " + artist]; context.title = ["Tracks from " + album + " by " + artist];
context.completions = map(library.getTracks(artist, album)); context.completions = map(library.getTracks(artist, album));
} }
@@ -462,53 +436,44 @@ function Player() //{{{
* @property {string} The player volume as a percentage. * @property {string} The player volume as a percentage.
*/ */
get volume() gMM.volumeControl.volume, get volume() gMM.volumeControl.volume,
set volume(value) set volume(value) {
{
gMM.volumeControl.volume = value; gMM.volumeControl.volume = value;
}, },
// FIXME: can't be called from non-media tabs since 840e78 // FIXME: can't be called from non-media tabs since 840e78
play: function play() play: function play() {
{
// Check if there is any selection in place, else play first item of the visible view. // Check if there is any selection in place, else play first item of the visible view.
if (_SBGetCurrentView().selection.count != 0) if (_SBGetCurrentView().selection.count != 0) {
{
// Play the selection. // Play the selection.
gMM.sequencer.playView(_SBGetCurrentView(), _SBGetCurrentView().getIndexForItem(_SBGetCurrentView().selection.currentMediaItem)); gMM.sequencer.playView(_SBGetCurrentView(), _SBGetCurrentView().getIndexForItem(_SBGetCurrentView().selection.currentMediaItem));
focusTrack(gMM.sequencer.currentItem); focusTrack(gMM.sequencer.currentItem);
} }
else else {
{
gMM.sequencer.playView(SBGetBrowser().currentMediaListView, 0); gMM.sequencer.playView(SBGetBrowser().currentMediaListView, 0);
focusTrack(gMM.sequencer.currentItem); focusTrack(gMM.sequencer.currentItem);
} }
}, },
stop: function stop() stop: function stop() {
{
gMM.sequencer.stop(); gMM.sequencer.stop();
}, },
next: function next() next: function next() {
{
gSongbirdWindowController.doCommand("cmd_control_next"); gSongbirdWindowController.doCommand("cmd_control_next");
gSongbirdWindowController.doCommand("cmd_find_current_track"); gSongbirdWindowController.doCommand("cmd_find_current_track");
}, },
previous: function previous() previous: function previous() {
{
gSongbirdWindowController.doCommand("cmd_control_previous"); gSongbirdWindowController.doCommand("cmd_control_previous");
gSongbirdWindowController.doCommand("cmd_find_current_track"); gSongbirdWindowController.doCommand("cmd_find_current_track");
}, },
togglePlayPause: function togglePlayPause() togglePlayPause: function togglePlayPause() {
{
gSongbirdWindowController.doCommand("cmd_control_playpause"); gSongbirdWindowController.doCommand("cmd_control_playpause");
focusTrack(gMM.sequencer.currentItem); focusTrack(gMM.sequencer.currentItem);
}, },
toggleShuffle: function toggleShuffle() toggleShuffle: function toggleShuffle() {
{
if (gMM.sequencer.mode != gMM.sequencer.MODE_SHUFFLE) if (gMM.sequencer.mode != gMM.sequencer.MODE_SHUFFLE)
gMM.sequencer.mode = gMM.sequencer.MODE_SHUFFLE; gMM.sequencer.mode = gMM.sequencer.MODE_SHUFFLE;
else else
@@ -516,10 +481,8 @@ function Player() //{{{
}, },
// FIXME: not really toggling - good enough for now. // FIXME: not really toggling - good enough for now.
toggleRepeat: function toggleRepeat() toggleRepeat: function toggleRepeat() {
{ switch (gMM.sequencer.repeatMode) {
switch (gMM.sequencer.repeatMode)
{
case gMM.sequencer.MODE_REPEAT_NONE: case gMM.sequencer.MODE_REPEAT_NONE:
gMM.sequencer.repeatMode = gMM.sequencer.MODE_REPEAT_ONE; gMM.sequencer.repeatMode = gMM.sequencer.MODE_REPEAT_ONE;
break; break;
@@ -542,8 +505,7 @@ function Player() //{{{
* @param {number} interval The time interval (ms) to advance the * @param {number} interval The time interval (ms) to advance the
* current track. * current track.
*/ */
seekForward: function seekForward(interval) seekForward: function seekForward(interval) {
{
seek(interval, true); seek(interval, true);
}, },
@@ -554,8 +516,7 @@ function Player() //{{{
* @param {number} interval The time interval (ms) to rewind the * @param {number} interval The time interval (ms) to rewind the
* current track. * current track.
*/ */
seekBackward: function seekBackward(interval) seekBackward: function seekBackward(interval) {
{
seek(interval, false); seek(interval, false);
}, },
@@ -564,8 +525,7 @@ function Player() //{{{
* *
* @param {number} The new position (ms) in the track. * @param {number} The new position (ms) in the track.
*/ */
seekTo: function seekTo(position) seekTo: function seekTo(position) {
{
// FIXME: if not playing // FIXME: if not playing
if (!gMM.playbackControl) if (!gMM.playbackControl)
this.play(); this.play();
@@ -578,32 +538,27 @@ function Player() //{{{
// FIXME: 10% ? // FIXME: 10% ?
// I think just general increments of say 0.05 might be better --djk // I think just general increments of say 0.05 might be better --djk
increaseVolume: function increaseVolume() increaseVolume: function increaseVolume() {
{
gMM.volumeControl.volume = gMM.volumeControl.volume * 1.1; gMM.volumeControl.volume = gMM.volumeControl.volume * 1.1;
}, },
decreaseVolume: function decreaseVolume() decreaseVolume: function decreaseVolume() {
{
if (gMM.volumeControl.volume == 0) if (gMM.volumeControl.volume == 0)
gMM.volumeControl.volume = 0.1; gMM.volumeControl.volume = 0.1;
else else
gMM.volumeControl.volume = gMM.volumeControl.volume * 0.9; gMM.volumeControl.volume = gMM.volumeControl.volume * 0.9;
}, },
focusPlayingTrack :function focusPlayingTrack() focusPlayingTrack :function focusPlayingTrack() {
{
focusTrack(gMM.sequencer.currentItem); focusTrack(gMM.sequencer.currentItem);
}, },
listTracks: function listTracks(view) listTracks: function listTracks(view) {
{
//let myView = LibraryUtils.createStandardMediaListView(LibraryUtils.mainLibrary, args); //let myView = LibraryUtils.createStandardMediaListView(LibraryUtils.mainLibrary, args);
let length = view.length; let length = view.length;
let tracksList = []; let tracksList = [];
for (let i = 0; i < length; i++) for (let i = 0; i < length; i++) {
{
let mediaItem = view.getItemByIndex(i); let mediaItem = view.getItemByIndex(i);
let trackName = mediaItem.getProperty(SBProperties.trackName); let trackName = mediaItem.getProperty(SBProperties.trackName);
let albumName = mediaItem.getProperty(SBProperties.albumName); let albumName = mediaItem.getProperty(SBProperties.albumName);
@@ -615,8 +570,7 @@ function Player() //{{{
return tracksList; return tracksList;
}, },
searchView: function searchView(args) searchView: function searchView(args) {
{
let currentView = _SBGetCurrentView(); let currentView = _SBGetCurrentView();
let mediaItemList = currentView.mediaList; let mediaItemList = currentView.mediaList;
let search = _getSearchString(currentView); let search = _getSearchString(currentView);
@@ -631,8 +585,7 @@ function Player() //{{{
let mySearchView = LibraryUtils.createStandardMediaListView(mediaItemList, searchString); let mySearchView = LibraryUtils.createStandardMediaListView(mediaItemList, searchString);
if (mySearchView.length) if (mySearchView.length) {
{
lastSearchView = mySearchView; lastSearchView = mySearchView;
lastSearchIndex = 0; lastSearchIndex = 0;
focusTrack(mySearchView.getItemByIndex(lastSearchIndex)); focusTrack(mySearchView.getItemByIndex(lastSearchIndex));
@@ -641,29 +594,23 @@ function Player() //{{{
liberator.echoerr("E486 Pattern not found: " + searchString, commandline.FORCE_SINGLELINE); liberator.echoerr("E486 Pattern not found: " + searchString, commandline.FORCE_SINGLELINE);
}, },
searchViewAgain: function searchViewAgain(reverse) searchViewAgain: function searchViewAgain(reverse) {
{ function echo(str) {
function echo(str)
{
setTimeout(function () { setTimeout(function () {
commandline.echo(str, commandline.HL_WARNINGMSG, commandline.APPEND_TO_MESSAGES | commandline.FORCE_SINGLELINE); commandline.echo(str, commandline.HL_WARNINGMSG, commandline.APPEND_TO_MESSAGES | commandline.FORCE_SINGLELINE);
}, 0); }, 0);
} }
if (reverse) if (reverse) {
{ if (lastSearchIndex == 0) {
if (lastSearchIndex == 0)
{
lastSearchIndex = lastSearchView.length - 1; lastSearchIndex = lastSearchView.length - 1;
echo("Search hit TOP, continuing at BOTTOM"); echo("Search hit TOP, continuing at BOTTOM");
} }
else else
lastSearchIndex = lastSearchIndex - 1; lastSearchIndex = lastSearchIndex - 1;
} }
else else {
{ if (lastSearchIndex == (lastSearchView.length - 1)) {
if (lastSearchIndex == (lastSearchView.length - 1))
{
lastSearchIndex = 0; lastSearchIndex = 0;
echo("Search hit BOTTOM, continuing at TOP"); echo("Search hit BOTTOM, continuing at TOP");
} }
@@ -682,8 +629,7 @@ function Player() //{{{
* *
* @param {string} str The contents of the search dialog. * @param {string} str The contents of the search dialog.
*/ */
onSearchKeyPress: function (str) onSearchKeyPress: function (str) {
{
if (options["incsearch"]) if (options["incsearch"])
this.searchView(str); this.searchView(str);
}, },
@@ -693,28 +639,24 @@ function Player() //{{{
* *
* @param {string} str The contents of the search dialog. * @param {string} str The contents of the search dialog.
*/ */
onSearchSubmit: function (str) onSearchSubmit: function (str) {
{
this.searchView(str); this.searchView(str);
}, },
/** /**
* The search dialog cancel callback. * The search dialog cancel callback.
*/ */
onSearchCancel: function () onSearchCancel: function () {
{
// TODO: restore the view state if altered by an 'incsearch' search // TODO: restore the view state if altered by an 'incsearch' search
}, },
getPlaylists: function getPlaylists() getPlaylists: function getPlaylists() {
{
let mainLibrary = LibraryUtils.mainLibrary; let mainLibrary = LibraryUtils.mainLibrary;
let playlists = [mainLibrary]; let playlists = [mainLibrary];
let listener = { let listener = {
onEnumerationBegin: function () { }, onEnumerationBegin: function () { },
onEnumerationEnd: function () { }, onEnumerationEnd: function () { },
onEnumeratedItem: function (list, item) onEnumeratedItem: function (list, item) {
{
// FIXME: why are there null items and duplicates? // FIXME: why are there null items and duplicates?
if (!playlists.some(function (list) list.name == item.name) && item.name != null) if (!playlists.some(function (list) list.name == item.name) && item.name != null)
playlists.push(item); playlists.push(item);
@@ -728,42 +670,35 @@ function Player() //{{{
}, },
// Play track at 'row' in 'playlist' // Play track at 'row' in 'playlist'
playPlaylist: function playPlaylist(playlist, row) playPlaylist: function playPlaylist(playlist, row) {
{
gMM.sequencer.playView(playlist.createView(), row); gMM.sequencer.playView(playlist.createView(), row);
}, },
getMediaPages: function getMediaPages() getMediaPages: function getMediaPages() {
{
let list = gBrowser.currentMediaPage.mediaListView.mediaList; let list = gBrowser.currentMediaPage.mediaListView.mediaList;
let pages = services.get("mediaPageManager").getAvailablePages(list); let pages = services.get("mediaPageManager").getAvailablePages(list);
return ArrayConverter.JSArray(pages).map(function (page) page.QueryInterface(Ci.sbIMediaPageInfo)); return ArrayConverter.JSArray(pages).map(function (page) page.QueryInterface(Ci.sbIMediaPageInfo));
}, },
loadMediaPage: function loadMediaList(page, list, view) loadMediaPage: function loadMediaList(page, list, view) {
{
services.get("mediaPageManager").setPage(list, page); services.get("mediaPageManager").setPage(list, page);
gBrowser.loadMediaList(list, null, null, view, null); gBrowser.loadMediaList(list, null, null, view, null);
}, },
rateMediaItem: function rateMediaItem(rating) rateMediaItem: function rateMediaItem(rating) {
{
if (gMM.sequencer.currentItem) if (gMM.sequencer.currentItem)
gMM.sequencer.currentItem.setProperty(SBProperties.rating, rating); gMM.sequencer.currentItem.setProperty(SBProperties.rating, rating);
}, },
getUserViewable: function getUserViewable() getUserViewable: function getUserViewable() {
{
let propManager = services.get("propertyManager"); let propManager = services.get("propertyManager");
let propEnumerator = propManager.propertyIDs; let propEnumerator = propManager.propertyIDs;
let properties = []; let properties = [];
while (propEnumerator.hasMore()) while (propEnumerator.hasMore()) {
{
let propertyId = propEnumerator.getNext(); let propertyId = propEnumerator.getNext();
if (propManager.getPropertyInfo(propertyId).userViewable) if (propManager.getPropertyInfo(propertyId).userViewable) {
{
//liberator.dump("propertyId - " + propManager.getPropertyInfo(propertyId).id); //liberator.dump("propertyId - " + propManager.getPropertyInfo(propertyId).id);
properties.push(propManager.getPropertyInfo(propertyId).displayName); properties.push(propManager.getPropertyInfo(propertyId).displayName);
} }
@@ -772,13 +707,11 @@ function Player() //{{{
return properties; return properties;
}, },
sortBy: function sortBy(property, order) sortBy: function sortBy(property, order) {
{
let pa = Cc["@songbirdnest.com/Songbird/Properties/MutablePropertyArray;1"].createInstance(Ci.sbIMutablePropertyArray); let pa = Cc["@songbirdnest.com/Songbird/Properties/MutablePropertyArray;1"].createInstance(Ci.sbIMutablePropertyArray);
liberator.dump("Property: " + property); liberator.dump("Property: " + property);
switch (property.string) switch (property.string) {
{
case "#": case "#":
case "Title": case "Title":
pa.appendProperty(SBProperties.trackName, "a"); pa.appendProperty(SBProperties.trackName, "a");