mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2026-01-10 12:34:12 +01:00
Allow localization of command/mapping/option descriptions.
This commit is contained in:
@@ -852,7 +852,7 @@ var Events = Module("events", {
|
||||
|
||||
evt_obj.charCode = keyname.charCodeAt(0);
|
||||
}
|
||||
else if (set.has(this._pseudoKeys)) {
|
||||
else if (set.has(this._pseudoKeys, keyname)) {
|
||||
evt_obj.dactylString = "<" + this._key_key[keyname] + ">";
|
||||
}
|
||||
else if (/mouse$/.test(keyname)) { // mouse events
|
||||
|
||||
@@ -54,6 +54,8 @@ var Map = Class("Map", {
|
||||
|
||||
get toStringParams() [this.modes.map(function (m) m.name), this.names.map(String.quote)],
|
||||
|
||||
get identifier() [this.modes[0].name, this.hive.prefix + this.names[0]].join("."),
|
||||
|
||||
/** @property {number} A unique ID for this mapping. */
|
||||
id: null,
|
||||
/** @property {number[]} All of the modes for which this mapping applies. */
|
||||
@@ -61,7 +63,7 @@ var Map = Class("Map", {
|
||||
/** @property {function (number)} The function called to execute this mapping. */
|
||||
action: null,
|
||||
/** @property {string} This mapping's description, as shown in :listkeys. */
|
||||
description: "",
|
||||
description: Messages.Localized(""),
|
||||
|
||||
/** @property {boolean} Whether this mapping accepts an argument. */
|
||||
arg: false,
|
||||
|
||||
@@ -363,11 +363,11 @@ function set(ary) {
|
||||
* @param {string} key The key to add.
|
||||
* @returns boolean
|
||||
*/
|
||||
set.add = function (set, key) {
|
||||
set.add = curry(function set_add(set, key) {
|
||||
let res = this.has(set, key);
|
||||
set[key] = true;
|
||||
return res;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* Returns true if the given set contains the given key.
|
||||
*
|
||||
@@ -375,8 +375,8 @@ set.add = function (set, key) {
|
||||
* @param {string} key The key to check.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
set.has = function (set, key) hasOwnProperty.call(set, key) &&
|
||||
propertyIsEnumerable.call(set, key);
|
||||
set.has = curry(function set_has(set, key) hasOwnProperty.call(set, key) &&
|
||||
propertyIsEnumerable.call(set, key));
|
||||
/**
|
||||
* Returns a new set containing the members of the first argument which
|
||||
* do not exist in any of the other given arguments.
|
||||
@@ -384,13 +384,13 @@ set.has = function (set, key) hasOwnProperty.call(set, key) &&
|
||||
* @param {object} set The set.
|
||||
* @returns {object}
|
||||
*/
|
||||
set.subtract = function (set) {
|
||||
set.subtract = function set_subtract(set) {
|
||||
set = update({}, set);
|
||||
for (let i = 1; i < arguments.length; i++)
|
||||
for (let k in keys(arguments[i]))
|
||||
delete set[k];
|
||||
return set;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Removes an element from a set and returns true if the element was
|
||||
* previously contained.
|
||||
@@ -399,12 +399,67 @@ set.subtract = function (set) {
|
||||
* @param {string} key The key to remove.
|
||||
* @returns boolean
|
||||
*/
|
||||
set.remove = function (set, key) {
|
||||
set.remove = curry(function set_remove(set, key) {
|
||||
let res = set.has(set, key);
|
||||
delete set[key];
|
||||
return res;
|
||||
});
|
||||
|
||||
/**
|
||||
* Curries a function to the given number of arguments. Each
|
||||
* call of the resulting function returns a new function. When
|
||||
* a call does not contain enough arguments to satisfy the
|
||||
* required number, the resulting function is another curried
|
||||
* function with previous arguments accumulated.
|
||||
*
|
||||
* function foo(a, b, c) [a, b, c].join(" ");
|
||||
* curry(foo)(1, 2, 3) -> "1 2 3";
|
||||
* curry(foo)(4)(5, 6) -> "4 5 6";
|
||||
* curry(foo)(7)(8)(9) -> "7 8 9";
|
||||
*
|
||||
* @param {function} fn The function to curry.
|
||||
* @param {integer} length The number of arguments expected.
|
||||
* @default fn.length
|
||||
* @optional
|
||||
* @param {object} self The 'this' value for the returned function. When
|
||||
* omitted, the value of 'this' from the first call to the function is
|
||||
* preserved.
|
||||
* @optional
|
||||
*/
|
||||
function curry(fn, length, self, acc) {
|
||||
if (length == null)
|
||||
length = fn.length;
|
||||
if (length == 0)
|
||||
return fn;
|
||||
|
||||
// Close over function with 'this'
|
||||
function close(self, fn) function () fn.apply(self, Array.slice(arguments));
|
||||
|
||||
if (acc == null)
|
||||
acc = [];
|
||||
|
||||
return function curried() {
|
||||
let args = acc.concat(Array.slice(arguments));
|
||||
|
||||
// The curried result should preserve 'this'
|
||||
if (arguments.length == 0)
|
||||
return close(self || this, curried);
|
||||
|
||||
if (args.length >= length)
|
||||
return fn.apply(self || this, args);
|
||||
|
||||
return curry(fn, length, self || this, args);
|
||||
};
|
||||
}
|
||||
|
||||
if (curry.bind)
|
||||
var bind = function bind(func) func.bind.apply(func, Array.slice(arguments, bind.length));
|
||||
else
|
||||
var bind = function bind(func, self) {
|
||||
let args = Array.slice(arguments, bind.length);
|
||||
return function bound() func.apply(self, args.concat(Array.slice(arguments)));
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if both arguments are functions and
|
||||
* (targ() instanceof src) would also return true.
|
||||
@@ -538,61 +593,6 @@ function memoize(obj, key, getter) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Curries a function to the given number of arguments. Each
|
||||
* call of the resulting function returns a new function. When
|
||||
* a call does not contain enough arguments to satisfy the
|
||||
* required number, the resulting function is another curried
|
||||
* function with previous arguments accumulated.
|
||||
*
|
||||
* function foo(a, b, c) [a, b, c].join(" ");
|
||||
* curry(foo)(1, 2, 3) -> "1 2 3";
|
||||
* curry(foo)(4)(5, 6) -> "4 5 6";
|
||||
* curry(foo)(7)(8)(9) -> "7 8 9";
|
||||
*
|
||||
* @param {function} fn The function to curry.
|
||||
* @param {integer} length The number of arguments expected.
|
||||
* @default fn.length
|
||||
* @optional
|
||||
* @param {object} self The 'this' value for the returned function. When
|
||||
* omitted, the value of 'this' from the first call to the function is
|
||||
* preserved.
|
||||
* @optional
|
||||
*/
|
||||
function curry(fn, length, self, acc) {
|
||||
if (length == null)
|
||||
length = fn.length;
|
||||
if (length == 0)
|
||||
return fn;
|
||||
|
||||
// Close over function with 'this'
|
||||
function close(self, fn) function () fn.apply(self, Array.slice(arguments));
|
||||
|
||||
if (acc == null)
|
||||
acc = [];
|
||||
|
||||
return function curried() {
|
||||
let args = acc.concat(Array.slice(arguments));
|
||||
|
||||
// The curried result should preserve 'this'
|
||||
if (arguments.length == 0)
|
||||
return close(self || this, curried);
|
||||
|
||||
if (args.length >= length)
|
||||
return fn.apply(self || this, args);
|
||||
|
||||
return curry(fn, length, self || this, args);
|
||||
};
|
||||
}
|
||||
|
||||
if (curry.bind)
|
||||
var bind = function bind(func) func.bind.apply(func, Array.slice(arguments, bind.length));
|
||||
else
|
||||
var bind = function bind(func, self) {
|
||||
let args = Array.slice(arguments, bind.length);
|
||||
return function bound() func.apply(self, args.concat(Array.slice(arguments)));
|
||||
};
|
||||
|
||||
let sandbox = Cu.Sandbox(this);
|
||||
sandbox.__proto__ = this;
|
||||
/**
|
||||
|
||||
@@ -11,8 +11,8 @@ try {
|
||||
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
||||
defineModule("commands", {
|
||||
exports: ["ArgType", "Command", "Commands", "CommandOption", "Ex", "commands"],
|
||||
require: ["contexts", "util"],
|
||||
use: ["config", "messages", "options", "services", "template"]
|
||||
require: ["contexts", "messages", "util"],
|
||||
use: ["config", "options", "services", "template"]
|
||||
}, this);
|
||||
|
||||
/**
|
||||
@@ -132,10 +132,14 @@ var Command = Class("Command", {
|
||||
update(this, extraInfo);
|
||||
if (this.options)
|
||||
this.options = this.options.map(CommandOption.fromArray, CommandOption);
|
||||
for each (let option in this.options)
|
||||
option.localeName = ["command", this.name, option.names[0]];
|
||||
},
|
||||
|
||||
get toStringParams() [this.name, this.hive.name],
|
||||
|
||||
get identifier() this.hive.prefix + this.name,
|
||||
|
||||
get helpTag() ":" + this.name,
|
||||
|
||||
get lastCommand() this._lastCommand || commandline.command,
|
||||
@@ -224,7 +228,7 @@ var Command = Class("Command", {
|
||||
names: null,
|
||||
|
||||
/** @property {string} This command's description, as shown in :listcommands */
|
||||
description: "",
|
||||
description: Messages.Localized(""),
|
||||
/**
|
||||
* @property {function (Args)} The function called to execute this command.
|
||||
*/
|
||||
@@ -1078,7 +1082,10 @@ var Commands = Module("commands", {
|
||||
context.completions = compl;
|
||||
}
|
||||
complete.advance(args.completeStart);
|
||||
complete.keys = { text: "names", description: "description" };
|
||||
complete.keys = {
|
||||
text: "names",
|
||||
description: function (opt) messages.get(["command", params.name, opt.names[0], "description"].join("."), opt.description)
|
||||
};
|
||||
complete.title = ["Options"];
|
||||
if (completeOpts)
|
||||
complete.completions = completeOpts;
|
||||
|
||||
@@ -434,6 +434,8 @@ var Contexts = Module("contexts", {
|
||||
get persist() this.group.persist,
|
||||
set persist(val) this.group.persist = val,
|
||||
|
||||
prefix: Class.memoize(function () this.name === "builtin" ? "" : this.name + ":"),
|
||||
|
||||
get toStringParams() [this.name]
|
||||
})
|
||||
}, {
|
||||
|
||||
@@ -78,6 +78,48 @@ var Messages = Module("messages", {
|
||||
}
|
||||
|
||||
}, {
|
||||
Localized: Class("Localized", Class.Property, {
|
||||
init: function init(prop, obj) {
|
||||
let _prop = "localized_" + prop;
|
||||
if (this.initialized) {
|
||||
/*
|
||||
if (config.locale === "en-US")
|
||||
return { configurable: true, enumerable: true, value: null, writable: true };
|
||||
*/
|
||||
|
||||
obj[_prop] = this.default;
|
||||
return {
|
||||
get: function get() {
|
||||
let self = this;
|
||||
let value = this[_prop];
|
||||
|
||||
function getter(key, default_) function getter() messages.get([name, key].join("."), default_);
|
||||
|
||||
let name = [this.constructor.className.toLowerCase(), this.identifier || this.name, prop].join(".");
|
||||
if (!isObject(value))
|
||||
value = messages.get(name, value)
|
||||
else if (isArray(value))
|
||||
// Deprecated
|
||||
iter(value).forEach(function ([k, v]) {
|
||||
if (isArray(v))
|
||||
memoize(v, 1, getter(v[0], v[1]));
|
||||
else
|
||||
memoize(value, k, getter(k, v));
|
||||
});
|
||||
else
|
||||
iter(value).forEach(function ([k, v]) {
|
||||
memoize(value, k, function () messages.get([name, k].join("."), v));
|
||||
});
|
||||
|
||||
return Class.replaceProperty(this, prop, value);
|
||||
},
|
||||
set: function set(val) this[_prop] = val
|
||||
}
|
||||
}
|
||||
this.default = prop;
|
||||
this.initialized = true;
|
||||
}
|
||||
})
|
||||
}, {
|
||||
javascript: function initJavascript(dactyl, modules, window) {
|
||||
modules.JavaScript.setCompleter([this._, this.get, this.format], [
|
||||
|
||||
@@ -11,7 +11,7 @@ try {
|
||||
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
||||
defineModule("options", {
|
||||
exports: ["Option", "Options", "ValueError", "options"],
|
||||
require: ["storage"],
|
||||
require: ["messages", "storage"],
|
||||
use: ["commands", "completion", "prefs", "services", "styles", "template", "util"]
|
||||
}, this);
|
||||
|
||||
@@ -65,6 +65,11 @@ var Option = Class("Option", {
|
||||
|
||||
this._op = Option.ops[this.type];
|
||||
|
||||
// Need to trigger setter
|
||||
if (extraInfo && "values" in extraInfo)
|
||||
this.values = extraInfo.values;
|
||||
delete extraInfo.values;
|
||||
|
||||
if (extraInfo)
|
||||
update(this, extraInfo);
|
||||
|
||||
@@ -92,6 +97,11 @@ var Option = Class("Option", {
|
||||
this.globalValue = this.defaultValue;
|
||||
},
|
||||
|
||||
/**
|
||||
* @property {string} This option's description, as shown in :listoptions.
|
||||
*/
|
||||
description: Messages.Localized(""),
|
||||
|
||||
get helpTag() "'" + this.name + "'",
|
||||
|
||||
initValue: function initValue() {
|
||||
@@ -291,11 +301,6 @@ var Option = Class("Option", {
|
||||
*/
|
||||
scope: 1, // Option.SCOPE_GLOBAL // XXX set to BOTH by default someday? - kstep
|
||||
|
||||
/**
|
||||
* @property {string} This option's description, as shown in :listoptions.
|
||||
*/
|
||||
description: "",
|
||||
|
||||
cleanupValue: null,
|
||||
|
||||
/**
|
||||
@@ -311,7 +316,7 @@ var Option = Class("Option", {
|
||||
* @property {[[string, string]]} This option's possible values.
|
||||
* @see CompletionContext
|
||||
*/
|
||||
values: null,
|
||||
values: Messages.Localized(null),
|
||||
|
||||
/**
|
||||
* @property {function(host, values)} A function which should return a list
|
||||
@@ -679,7 +684,7 @@ var Option = Class("Option", {
|
||||
*/
|
||||
validateCompleter: function validateCompleter(values) {
|
||||
if (this.values)
|
||||
var acceptable = this.values;
|
||||
var acceptable = this.values.array || this.values;
|
||||
else {
|
||||
let context = CompletionContext("");
|
||||
acceptable = context.fork("", 0, this, this.completer);
|
||||
@@ -688,7 +693,10 @@ var Option = Class("Option", {
|
||||
}
|
||||
if (this.type === "regexpmap" || this.type === "sitemap")
|
||||
return Array.concat(values).every(function (re) acceptable.some(function (item) item[0] == re.result));
|
||||
return Array.concat(values).every(function (value) acceptable.some(function (item) item[0] == value));
|
||||
|
||||
if (isArray(acceptable))
|
||||
acceptable = set(acceptable.map(function ([k]) k));
|
||||
return Array.concat(values).every(set.has(acceptable));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ var Overlay = Module("Overlay", {
|
||||
defineModule.time("load", null, function _load() {
|
||||
["addons",
|
||||
"base",
|
||||
"io",
|
||||
"commands",
|
||||
"completion",
|
||||
"config",
|
||||
@@ -168,7 +169,6 @@ var Overlay = Module("Overlay", {
|
||||
"downloads",
|
||||
"finder",
|
||||
"highlight",
|
||||
"io",
|
||||
"javascript",
|
||||
"messages",
|
||||
"options",
|
||||
|
||||
Reference in New Issue
Block a user