mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-20 03:47:58 +01:00
Prepare for merge with testing branch.
This commit is contained in:
@@ -83,7 +83,7 @@ const AutoCommands = Module("autocommands", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let list = template.commandOutput(
|
let list = template.commandOutput(commandline.command,
|
||||||
<table>
|
<table>
|
||||||
<tr highlight="Title">
|
<tr highlight="Title">
|
||||||
<td colspan="2">----- Auto Commands -----</td>
|
<td colspan="2">----- Auto Commands -----</td>
|
||||||
@@ -257,8 +257,6 @@ const AutoCommands = Module("autocommands", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
completion: function () {
|
completion: function () {
|
||||||
JavaScript.setCompleter(this.get, [function () Iterator(config.autocommands)]);
|
|
||||||
|
|
||||||
completion.autocmdEvent = function autocmdEvent(context) {
|
completion.autocmdEvent = function autocmdEvent(context) {
|
||||||
context.completions = Iterator(config.autocommands);
|
context.completions = Iterator(config.autocommands);
|
||||||
};
|
};
|
||||||
@@ -268,6 +266,9 @@ const AutoCommands = Module("autocommands", {
|
|||||||
context.completions = [item for (item in events.getMacros())];
|
context.completions = [item for (item in events.getMacros())];
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
javascript: function () {
|
||||||
|
JavaScript.setCompleter(this.get, [function () Iterator(config.autocommands)]);
|
||||||
|
},
|
||||||
options: function () {
|
options: function () {
|
||||||
options.add(["eventignore", "ei"],
|
options.add(["eventignore", "ei"],
|
||||||
"List of autocommand event names which should be ignored",
|
"List of autocommand event names which should be ignored",
|
||||||
|
|||||||
@@ -9,14 +9,6 @@ const Ci = Components.interfaces;
|
|||||||
const Cr = Components.results;
|
const Cr = Components.results;
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
|
|
||||||
function array(obj) {
|
|
||||||
if (isgenerator(obj))
|
|
||||||
obj = [k for (k in obj)];
|
|
||||||
else if (obj.length)
|
|
||||||
obj = Array.slice(obj);
|
|
||||||
return util.Array(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
function allkeys(obj) {
|
function allkeys(obj) {
|
||||||
let ret = {};
|
let ret = {};
|
||||||
try {
|
try {
|
||||||
@@ -45,7 +37,7 @@ function allkeys(obj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function debuggerProperties(obj) {
|
function debuggerProperties(obj) {
|
||||||
if (modules.services && options["jsdebugger"]) {
|
if (modules.services && services.get("debugger").isOn) {
|
||||||
let ret = {};
|
let ret = {};
|
||||||
services.get("debugger").wrapValue(obj).getProperties(ret, {});
|
services.get("debugger").wrapValue(obj).getProperties(ret, {});
|
||||||
return ret.value;
|
return ret.value;
|
||||||
@@ -125,9 +117,9 @@ function iter(obj) {
|
|||||||
}
|
}
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
})();
|
})();
|
||||||
if (isinstance(obj, [HTMLCollection, NodeList]))
|
if (isinstance(obj, [Ci.nsIDOMHTMLCollection, Ci.nsIDOMNodeList]))
|
||||||
return util.Array.iteritems(obj);
|
return array.iteritems(obj);
|
||||||
if (obj instanceof NamedNodeMap)
|
if (obj instanceof Ci.nsIDOMNamedNodeMap)
|
||||||
return (function () {
|
return (function () {
|
||||||
for (let i = 0; i < obj.length; i++)
|
for (let i = 0; i < obj.length; i++)
|
||||||
yield [obj.name, obj];
|
yield [obj.name, obj];
|
||||||
@@ -208,6 +200,13 @@ function call(fn) {
|
|||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function memoize(obj, key, getter) {
|
||||||
|
obj.__defineGetter__(key, function () {
|
||||||
|
delete obj[key];
|
||||||
|
return obj[key] = getter(obj, key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Curries a function to the given number of arguments. Each
|
* Curries a function to the given number of arguments. Each
|
||||||
* call of the resulting function returns a new function. When
|
* call of the resulting function returns a new function. When
|
||||||
@@ -312,13 +311,8 @@ function update(target) {
|
|||||||
* @param {Object} overrides @optional
|
* @param {Object} overrides @optional
|
||||||
*/
|
*/
|
||||||
function extend(subclass, superclass, overrides) {
|
function extend(subclass, superclass, overrides) {
|
||||||
subclass.prototype = {};
|
subclass.prototype = { __proto__: superclass.prototype };
|
||||||
update(subclass.prototype, overrides);
|
update(subclass.prototype, overrides);
|
||||||
// This is unduly expensive. Unfortunately necessary since
|
|
||||||
// we apparently can't rely on the presence of the
|
|
||||||
// debugger to enumerate properties when we have
|
|
||||||
// __iterators__ attached to prototypes.
|
|
||||||
subclass.prototype.__proto__ = superclass.prototype;
|
|
||||||
|
|
||||||
subclass.superclass = superclass.prototype;
|
subclass.superclass = superclass.prototype;
|
||||||
subclass.prototype.constructor = subclass;
|
subclass.prototype.constructor = subclass;
|
||||||
@@ -421,8 +415,10 @@ Class.prototype = {
|
|||||||
*/
|
*/
|
||||||
setTimeout: function (callback, timeout) {
|
setTimeout: function (callback, timeout) {
|
||||||
const self = this;
|
const self = this;
|
||||||
function target() callback.call(self);
|
let notify = { notify: function notify(timer) { callback.call(self) } };
|
||||||
return window.setTimeout(target, timeout);
|
let timer = services.create("timer");
|
||||||
|
timer.initWithCallback(notify, timeout, timer.TYPE_ONE_SHOT);
|
||||||
|
return timer;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -493,4 +489,136 @@ for (let k in values(["concat", "every", "filter", "forEach", "indexOf", "join",
|
|||||||
"map", "reduce", "reduceRight", "reverse", "slice", "some", "sort"]))
|
"map", "reduce", "reduceRight", "reverse", "slice", "some", "sort"]))
|
||||||
StructBase.prototype[k] = Array.prototype[k];
|
StructBase.prototype[k] = Array.prototype[k];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array utility methods.
|
||||||
|
*/
|
||||||
|
const array = Class("util.Array", Array, {
|
||||||
|
init: function (ary) {
|
||||||
|
if (isgenerator(ary))
|
||||||
|
ary = [k for (k in ary)];
|
||||||
|
else if (ary.length)
|
||||||
|
ary = Array.slice(ary);
|
||||||
|
|
||||||
|
return {
|
||||||
|
__proto__: ary,
|
||||||
|
__iterator__: function () this.iteritems(),
|
||||||
|
__noSuchMethod__: function (meth, args) {
|
||||||
|
var res = array[meth].apply(null, [this.__proto__].concat(args));
|
||||||
|
|
||||||
|
if (array.isinstance(res))
|
||||||
|
return array(res);
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
toString: function () this.__proto__.toString(),
|
||||||
|
concat: function () this.__proto__.concat.apply(this.__proto__, arguments),
|
||||||
|
map: function () this.__noSuchMethod__("map", Array.slice(arguments))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
isinstance: function isinstance(obj) {
|
||||||
|
return Object.prototype.toString.call(obj) == "[object Array]";
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array to an object. As in lisp, an assoc is an
|
||||||
|
* array of key-value pairs, which maps directly to an object,
|
||||||
|
* as such:
|
||||||
|
* [["a", "b"], ["c", "d"]] -> { a: "b", c: "d" }
|
||||||
|
*
|
||||||
|
* @param {Array[]} assoc
|
||||||
|
* @... {string} 0 - Key
|
||||||
|
* @... 1 - Value
|
||||||
|
*/
|
||||||
|
toObject: function toObject(assoc) {
|
||||||
|
let obj = {};
|
||||||
|
assoc.forEach(function ([k, v]) { obj[k] = v; });
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compacts an array, removing all elements that are null or undefined:
|
||||||
|
* ["foo", null, "bar", undefined] -> ["foo", "bar"]
|
||||||
|
*
|
||||||
|
* @param {Array} ary
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
compact: function compact(ary) ary.filter(function (item) item != null),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flattens an array, such that all elements of the array are
|
||||||
|
* joined into a single array:
|
||||||
|
* [["foo", ["bar"]], ["baz"], "quux"] -> ["foo", ["bar"], "baz", "quux"]
|
||||||
|
*
|
||||||
|
* @param {Array} ary
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
flatten: function flatten(ary) ary.length ? Array.concat.apply([], ary) : [],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an Iterator for an array's values.
|
||||||
|
*
|
||||||
|
* @param {Array} ary
|
||||||
|
* @returns {Iterator(Object)}
|
||||||
|
*/
|
||||||
|
itervalues: function itervalues(ary) {
|
||||||
|
let length = ary.length;
|
||||||
|
for (let i = 0; i < length; i++)
|
||||||
|
yield ary[i];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an Iterator for an array's indices and values.
|
||||||
|
*
|
||||||
|
* @param {Array} ary
|
||||||
|
* @returns {Iterator([{number}, {Object}])}
|
||||||
|
*/
|
||||||
|
iteritems: function iteritems(ary) {
|
||||||
|
let length = ary.length;
|
||||||
|
for (let i = 0; i < length; i++)
|
||||||
|
yield [i, ary[i]];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters out all duplicates from an array. If
|
||||||
|
* <b>unsorted</b> is false, the array is sorted before
|
||||||
|
* duplicates are removed.
|
||||||
|
*
|
||||||
|
* @param {Array} ary
|
||||||
|
* @param {boolean} unsorted
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
uniq: function uniq(ary, unsorted) {
|
||||||
|
let ret = [];
|
||||||
|
if (unsorted) {
|
||||||
|
for (let [, item] in Iterator(ary))
|
||||||
|
if (ret.indexOf(item) == -1)
|
||||||
|
ret.push(item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (let [, item] in Iterator(ary.sort())) {
|
||||||
|
if (item != last || !ret.length)
|
||||||
|
ret.push(item);
|
||||||
|
var last = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zips the contents of two arrays. The resulting array is twice the
|
||||||
|
* length of ary1, with any shortcomings of ary2 replaced with null
|
||||||
|
* strings.
|
||||||
|
*
|
||||||
|
* @param {Array} ary1
|
||||||
|
* @param {Array} ary2
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
zip: function zip(ary1, ary2) {
|
||||||
|
let res = []
|
||||||
|
for(let [i, item] in Iterator(ary1))
|
||||||
|
res.push(item, i in ary2 ? ary2[i] : "");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// vim: set fdm=marker sw=4 ts=4 et:
|
// vim: set fdm=marker sw=4 ts=4 et:
|
||||||
|
|||||||
@@ -464,7 +464,7 @@ const Bookmarks = Module("bookmarks", {
|
|||||||
args.completeFilter = have.pop();
|
args.completeFilter = have.pop();
|
||||||
|
|
||||||
let prefix = filter.substr(0, filter.length - args.completeFilter.length);
|
let prefix = filter.substr(0, filter.length - args.completeFilter.length);
|
||||||
let tags = util.Array.uniq(util.Array.flatten([b.tags for ([k, b] in Iterator(this._cache.bookmarks))]));
|
let tags = array.uniq(util.Array.flatten([b.tags for ([k, b] in Iterator(this._cache.bookmarks))]));
|
||||||
|
|
||||||
return [[prefix + tag, tag] for ([i, tag] in Iterator(tags)) if (have.indexOf(tag) < 0)];
|
return [[prefix + tag, tag] for ([i, tag] in Iterator(tags)) if (have.indexOf(tag) < 0)];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1003,7 +1003,7 @@ const Buffer = Module("buffer", {
|
|||||||
|
|
||||||
let values = ZoomManager.zoomValues;
|
let values = ZoomManager.zoomValues;
|
||||||
let cur = values.indexOf(ZoomManager.snap(ZoomManager.zoom));
|
let cur = values.indexOf(ZoomManager.snap(ZoomManager.zoom));
|
||||||
let i = util.Math.constrain(cur + steps, 0, values.length - 1);
|
let i = Math.constrain(cur + steps, 0, values.length - 1);
|
||||||
|
|
||||||
if (i == cur && fullZoom == ZoomManager.useFullZoom)
|
if (i == cur && fullZoom == ZoomManager.useFullZoom)
|
||||||
dactyl.beep();
|
dactyl.beep();
|
||||||
@@ -1286,7 +1286,7 @@ const Buffer = Module("buffer", {
|
|||||||
level = buffer.textZoom + parseInt(arg, 10);
|
level = buffer.textZoom + parseInt(arg, 10);
|
||||||
|
|
||||||
// relative args shouldn't take us out of range
|
// relative args shouldn't take us out of range
|
||||||
level = util.Math.constrain(level, Buffer.ZOOM_MIN, Buffer.ZOOM_MAX);
|
level = Math.constrain(level, Buffer.ZOOM_MIN, Buffer.ZOOM_MAX);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dactyl.assert(false, "E488: Trailing characters");
|
dactyl.assert(false, "E488: Trailing characters");
|
||||||
@@ -1519,14 +1519,14 @@ const Buffer = Module("buffer", {
|
|||||||
let xpath = ["input", "textarea[not(@disabled) and not(@readonly)]"];
|
let xpath = ["input", "textarea[not(@disabled) and not(@readonly)]"];
|
||||||
|
|
||||||
let elements = [m for (m in util.evaluateXPath(xpath))].filter(function (elem) {
|
let elements = [m for (m in util.evaluateXPath(xpath))].filter(function (elem) {
|
||||||
if (elem.readOnly || elem instanceof HTMLInputElement && set.has(Events.editableInputs, elem.type))
|
if (elem.readOnly || elem instanceof HTMLInputElement && !set.has(Events.editableInputs, elem.type))
|
||||||
return false;
|
return false;
|
||||||
let computedStyle = util.computedStyle(elem);
|
let computedStyle = util.computedStyle(elem);
|
||||||
return computedStyle.visibility != "hidden" && computedStyle.display != "none";
|
return computedStyle.visibility != "hidden" && computedStyle.display != "none";
|
||||||
});
|
});
|
||||||
|
|
||||||
dactyl.assert(elements.length > 0);
|
dactyl.assert(elements.length > 0);
|
||||||
let elem = elements[util.Math.constrain(count, 1, elements.length) - 1];
|
let elem = elements[Math.constrain(count, 1, elements.length) - 1];
|
||||||
buffer.focusElement(elem);
|
buffer.focusElement(elem);
|
||||||
util.scrollIntoView(elem);
|
util.scrollIntoView(elem);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,26 +131,24 @@ const CommandLine = Module("commandline", {
|
|||||||
this._startHints = false; // whether we're waiting to start hints mode
|
this._startHints = false; // whether we're waiting to start hints mode
|
||||||
this._lastSubstring = "";
|
this._lastSubstring = "";
|
||||||
|
|
||||||
// the containing box for the this._promptWidget and this._commandWidget
|
this.widgets = {
|
||||||
this._commandlineWidget = document.getElementById("dactyl-commandline");
|
commandline: document.getElementById("dactyl-commandline"),
|
||||||
// the prompt for the current command, for example : or /. Can be blank
|
prompt: document.getElementById("dactyl-commandline-prompt"),
|
||||||
this._promptWidget = document.getElementById("dactyl-commandline-prompt");
|
command: document.getElementById("dactyl-commandline-command"),
|
||||||
// the command bar which contains the current command
|
|
||||||
this._commandWidget = document.getElementById("dactyl-commandline-command");
|
|
||||||
|
|
||||||
this._messageBox = document.getElementById("dactyl-message");
|
message: document.getElementById("dactyl-message"),
|
||||||
|
|
||||||
this._commandWidget.inputField.QueryInterface(Ci.nsIDOMNSEditableElement);
|
multilineOutput: document.getElementById("dactyl-multiline-output"),
|
||||||
this._messageBox.inputField.QueryInterface(Ci.nsIDOMNSEditableElement);
|
multilineInput: document.getElementById("dactyl-multiline-input"),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.widgets.command.inputField.QueryInterface(Ci.nsIDOMNSEditableElement);
|
||||||
|
this.widgets.message.inputField.QueryInterface(Ci.nsIDOMNSEditableElement);
|
||||||
|
|
||||||
// the widget used for multiline output
|
// the widget used for multiline output
|
||||||
this._multilineOutputWidget = document.getElementById("dactyl-multiline-output");
|
this._outputContainer = this.widgets.multilineOutput.parentNode;
|
||||||
this._outputContainer = this._multilineOutputWidget.parentNode;
|
|
||||||
|
|
||||||
this._multilineOutputWidget.contentDocument.body.id = "dactyl-multiline-output-content";
|
this.widgets.multilineOutput.contentDocument.body.id = "dactyl-multiline-output-content";
|
||||||
|
|
||||||
// the widget used for multiline intput
|
|
||||||
this._multilineInputWidget = document.getElementById("dactyl-multiline-input");
|
|
||||||
|
|
||||||
// we need to save the mode which were in before opening the command line
|
// we need to save the mode which were in before opening the command line
|
||||||
// this is then used if we focus the command line again without the "official"
|
// this is then used if we focus the command line again without the "official"
|
||||||
@@ -208,7 +206,7 @@ const CommandLine = Module("commandline", {
|
|||||||
* Highlight the messageBox according to <b>group</b>.
|
* Highlight the messageBox according to <b>group</b>.
|
||||||
*/
|
*/
|
||||||
_setHighlightGroup: function (group) {
|
_setHighlightGroup: function (group) {
|
||||||
this._messageBox.setAttributeNS(NS.uri, "highlight", group);
|
this.widgets.message.setAttributeNS(NS.uri, "highlight", group);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,10 +224,10 @@ const CommandLine = Module("commandline", {
|
|||||||
* @param {string} highlightGroup
|
* @param {string} highlightGroup
|
||||||
*/
|
*/
|
||||||
_setPrompt: function (val, highlightGroup) {
|
_setPrompt: function (val, highlightGroup) {
|
||||||
this._promptWidget.value = val;
|
this.widgets.prompt.value = val;
|
||||||
this._promptWidget.size = val.length;
|
this.widgets.prompt.size = val.length;
|
||||||
this._promptWidget.collapsed = (val == "");
|
this.widgets.prompt.collapsed = (val == "");
|
||||||
this._promptWidget.setAttributeNS(NS.uri, "highlight", highlightGroup || commandline.HL_NORMAL);
|
this.widgets.prompt.setAttributeNS(NS.uri, "highlight", highlightGroup || commandline.HL_NORMAL);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -239,9 +237,9 @@ const CommandLine = Module("commandline", {
|
|||||||
* @param {string} cmd
|
* @param {string} cmd
|
||||||
*/
|
*/
|
||||||
_setCommand: function (cmd) {
|
_setCommand: function (cmd) {
|
||||||
this._commandWidget.value = cmd;
|
this.widgets.command.value = cmd;
|
||||||
this._commandWidget.selectionStart = cmd.length;
|
this.widgets.command.selectionStart = cmd.length;
|
||||||
this._commandWidget.selectionEnd = cmd.length;
|
this.widgets.command.selectionEnd = cmd.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -254,14 +252,14 @@ const CommandLine = Module("commandline", {
|
|||||||
*/
|
*/
|
||||||
_echoLine: function (str, highlightGroup, forceSingle) {
|
_echoLine: function (str, highlightGroup, forceSingle) {
|
||||||
this._setHighlightGroup(highlightGroup);
|
this._setHighlightGroup(highlightGroup);
|
||||||
this._messageBox.value = str;
|
this.widgets.message.value = str;
|
||||||
|
|
||||||
dactyl.triggerObserver("echoLine", str, highlightGroup, forceSingle);
|
dactyl.triggerObserver("echoLine", str, highlightGroup, forceSingle);
|
||||||
|
|
||||||
if (!this._commandShown())
|
if (!this._commandShown())
|
||||||
commandline.hide();
|
commandline.hide();
|
||||||
|
|
||||||
let field = this._messageBox.inputField;
|
let field = this.widgets.message.inputField;
|
||||||
if (!forceSingle && field.editor.rootElement.scrollWidth > field.scrollWidth)
|
if (!forceSingle && field.editor.rootElement.scrollWidth > field.scrollWidth)
|
||||||
this._echoMultiline(<span highlight="Message">{str}</span>, highlightGroup);
|
this._echoMultiline(<span highlight="Message">{str}</span>, highlightGroup);
|
||||||
},
|
},
|
||||||
@@ -274,8 +272,8 @@ const CommandLine = Module("commandline", {
|
|||||||
*/
|
*/
|
||||||
// TODO: resize upon a window resize
|
// TODO: resize upon a window resize
|
||||||
_echoMultiline: function (str, highlightGroup) {
|
_echoMultiline: function (str, highlightGroup) {
|
||||||
let doc = this._multilineOutputWidget.contentDocument;
|
let doc = this.widgets.multilineOutput.contentDocument;
|
||||||
let win = this._multilineOutputWidget.contentWindow;
|
let win = this.widgets.multilineOutput.contentWindow;
|
||||||
|
|
||||||
dactyl.triggerObserver("echoMultiline", str, highlightGroup);
|
dactyl.triggerObserver("echoMultiline", str, highlightGroup);
|
||||||
|
|
||||||
@@ -316,9 +314,9 @@ const CommandLine = Module("commandline", {
|
|||||||
* Ensure that the multiline input widget is the correct size.
|
* Ensure that the multiline input widget is the correct size.
|
||||||
*/
|
*/
|
||||||
_autosizeMultilineInputWidget: function () {
|
_autosizeMultilineInputWidget: function () {
|
||||||
let lines = this._multilineInputWidget.value.split("\n").length - 1;
|
let lines = this.widgets.multilineInput.value.split("\n").length - 1;
|
||||||
|
|
||||||
this._multilineInputWidget.setAttribute("rows", Math.max(lines, 1));
|
this.widgets.multilineInput.setAttribute("rows", Math.max(lines, 1));
|
||||||
},
|
},
|
||||||
|
|
||||||
HL_NORMAL: "Normal",
|
HL_NORMAL: "Normal",
|
||||||
@@ -386,15 +384,15 @@ const CommandLine = Module("commandline", {
|
|||||||
try {
|
try {
|
||||||
// The long path is because of complications with the
|
// The long path is because of complications with the
|
||||||
// completion preview.
|
// completion preview.
|
||||||
return this._commandWidget.inputField.editor.rootElement.firstChild.textContent;
|
return this.widgets.command.inputField.editor.rootElement.firstChild.textContent;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
return this._commandWidget.value;
|
return this.widgets.command.value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
set command(cmd) this._commandWidget.value = cmd,
|
set command(cmd) this.widgets.command.value = cmd,
|
||||||
|
|
||||||
get message() this._messageBox.value,
|
get message() this.widgets.message.value,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the command line. The main mode is set to
|
* Open the command line. The main mode is set to
|
||||||
@@ -416,14 +414,14 @@ const CommandLine = Module("commandline", {
|
|||||||
|
|
||||||
this._setPrompt(this._currentPrompt);
|
this._setPrompt(this._currentPrompt);
|
||||||
this._setCommand(this._currentCommand);
|
this._setCommand(this._currentCommand);
|
||||||
this._commandlineWidget.collapsed = false;
|
this.widgets.commandline.collapsed = false;
|
||||||
|
|
||||||
modes.set(modes.COMMAND_LINE, this._currentExtendedMode);
|
modes.set(modes.COMMAND_LINE, this._currentExtendedMode);
|
||||||
|
|
||||||
this._commandWidget.focus();
|
this.widgets.command.focus();
|
||||||
|
|
||||||
this._history = CommandLine.History(this._commandWidget.inputField, (modes.extended == modes.EX) ? "command" : "search");
|
this._history = CommandLine.History(this.widgets.command.inputField, (modes.extended == modes.EX) ? "command" : "search");
|
||||||
this._completions = CommandLine.Completions(this._commandWidget.inputField);
|
this._completions = CommandLine.Completions(this.widgets.command.inputField);
|
||||||
|
|
||||||
// open the completion list automatically if wanted
|
// open the completion list automatically if wanted
|
||||||
if (cmd.length)
|
if (cmd.length)
|
||||||
@@ -450,7 +448,7 @@ const CommandLine = Module("commandline", {
|
|||||||
statusline.updateProgress(""); // we may have a "match x of y" visible
|
statusline.updateProgress(""); // we may have a "match x of y" visible
|
||||||
dactyl.focusContent(false);
|
dactyl.focusContent(false);
|
||||||
|
|
||||||
this._multilineInputWidget.collapsed = true;
|
this.widgets.multilineInput.collapsed = true;
|
||||||
this._completionList.hide();
|
this._completionList.hide();
|
||||||
|
|
||||||
if (!this._keepCommand || this._silent || this._quiet) {
|
if (!this._keepCommand || this._silent || this._quiet) {
|
||||||
@@ -470,7 +468,7 @@ const CommandLine = Module("commandline", {
|
|||||||
* are under it.
|
* are under it.
|
||||||
*/
|
*/
|
||||||
hide: function hide() {
|
hide: function hide() {
|
||||||
this._commandlineWidget.collapsed = true;
|
this.widgets.commandline.collapsed = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -509,7 +507,7 @@ const CommandLine = Module("commandline", {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// The DOM isn't threadsafe. It must only be accessed from the main thread.
|
// The DOM isn't threadsafe. It must only be accessed from the main thread.
|
||||||
dactyl.callInMainThread(function () {
|
util.callInMainThread(function () {
|
||||||
if ((flags & this.DISALLOW_MULTILINE) && !this._outputContainer.collapsed)
|
if ((flags & this.DISALLOW_MULTILINE) && !this._outputContainer.collapsed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -518,7 +516,7 @@ const CommandLine = Module("commandline", {
|
|||||||
|
|
||||||
// TODO: this is all a bit convoluted - clean up.
|
// TODO: this is all a bit convoluted - clean up.
|
||||||
// assume that FORCE_MULTILINE output is fully styled
|
// assume that FORCE_MULTILINE output is fully styled
|
||||||
if (!(flags & this.FORCE_MULTILINE) && !single && (!this._outputContainer.collapsed || this._messageBox.value == this._lastEcho)) {
|
if (!(flags & this.FORCE_MULTILINE) && !single && (!this._outputContainer.collapsed || this.widgets.message.value == this._lastEcho)) {
|
||||||
highlightGroup += " Message";
|
highlightGroup += " Message";
|
||||||
action = this._echoMultiline;
|
action = this._echoMultiline;
|
||||||
}
|
}
|
||||||
@@ -529,9 +527,9 @@ const CommandLine = Module("commandline", {
|
|||||||
if (single)
|
if (single)
|
||||||
this._lastEcho = null;
|
this._lastEcho = null;
|
||||||
else {
|
else {
|
||||||
if (this._messageBox.value == this._lastEcho)
|
if (this.widgets.message.value == this._lastEcho)
|
||||||
this._echoMultiline(<span highlight="Message">{this._lastEcho}</span>,
|
this._echoMultiline(<span highlight="Message">{this._lastEcho}</span>,
|
||||||
this._messageBox.getAttributeNS(NS.uri, "highlight"));
|
this.widgets.message.getAttributeNS(NS.uri, "highlight"));
|
||||||
this._lastEcho = (action == this._echoLine) && str;
|
this._lastEcho = (action == this._echoLine) && str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,10 +569,10 @@ const CommandLine = Module("commandline", {
|
|||||||
|
|
||||||
this._setPrompt(prompt, extra.promptHighlight || this.HL_QUESTION);
|
this._setPrompt(prompt, extra.promptHighlight || this.HL_QUESTION);
|
||||||
this._setCommand(extra.default || "");
|
this._setCommand(extra.default || "");
|
||||||
this._commandlineWidget.collapsed = false;
|
this.widgets.commandline.collapsed = false;
|
||||||
this._commandWidget.focus();
|
this.widgets.command.focus();
|
||||||
|
|
||||||
this._completions = CommandLine.Completions(this._commandWidget.inputField);
|
this._completions = CommandLine.Completions(this.widgets.command.inputField);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -588,7 +586,7 @@ const CommandLine = Module("commandline", {
|
|||||||
// FIXME: Buggy, especially when pasting. Shouldn't use a RegExp.
|
// FIXME: Buggy, especially when pasting. Shouldn't use a RegExp.
|
||||||
inputMultiline: function inputMultiline(untilRegexp, callbackFunc) {
|
inputMultiline: function inputMultiline(untilRegexp, callbackFunc) {
|
||||||
// Kludge.
|
// Kludge.
|
||||||
let cmd = !this._commandWidget.collapsed && this.command;
|
let cmd = !this.widgets.command.collapsed && this.command;
|
||||||
modes.push(modes.COMMAND_LINE, modes.INPUT_MULTILINE);
|
modes.push(modes.COMMAND_LINE, modes.INPUT_MULTILINE);
|
||||||
if (cmd != false)
|
if (cmd != false)
|
||||||
this._echoLine(cmd, this.HL_NORMAL);
|
this._echoLine(cmd, this.HL_NORMAL);
|
||||||
@@ -597,11 +595,11 @@ const CommandLine = Module("commandline", {
|
|||||||
this._multilineRegexp = untilRegexp;
|
this._multilineRegexp = untilRegexp;
|
||||||
this._multilineCallback = callbackFunc;
|
this._multilineCallback = callbackFunc;
|
||||||
|
|
||||||
this._multilineInputWidget.collapsed = false;
|
this.widgets.multilineInput.collapsed = false;
|
||||||
this._multilineInputWidget.value = "";
|
this.widgets.multilineInput.value = "";
|
||||||
this._autosizeMultilineInputWidget();
|
this._autosizeMultilineInputWidget();
|
||||||
|
|
||||||
this.setTimeout(function () { this._multilineInputWidget.focus(); }, 10);
|
this.setTimeout(function () { this.widgets.multilineInput.focus(); }, 10);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -619,12 +617,12 @@ const CommandLine = Module("commandline", {
|
|||||||
if (event.type == "blur") {
|
if (event.type == "blur") {
|
||||||
// prevent losing focus, there should be a better way, but it just didn't work otherwise
|
// prevent losing focus, there should be a better way, but it just didn't work otherwise
|
||||||
this.setTimeout(function () {
|
this.setTimeout(function () {
|
||||||
if (this._commandShown() && event.originalTarget == this._commandWidget.inputField)
|
if (this._commandShown() && event.originalTarget == this.widgets.command.inputField)
|
||||||
this._commandWidget.inputField.focus();
|
this.widgets.command.inputField.focus();
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
else if (event.type == "focus") {
|
else if (event.type == "focus") {
|
||||||
if (!this._commandShown() && event.target == this._commandWidget.inputField) {
|
if (!this._commandShown() && event.target == this.widgets.command.inputField) {
|
||||||
event.target.blur();
|
event.target.blur();
|
||||||
dactyl.beep();
|
dactyl.beep();
|
||||||
}
|
}
|
||||||
@@ -703,22 +701,22 @@ const CommandLine = Module("commandline", {
|
|||||||
if (event.type == "keypress") {
|
if (event.type == "keypress") {
|
||||||
let key = events.toString(event);
|
let key = events.toString(event);
|
||||||
if (events.isAcceptKey(key)) {
|
if (events.isAcceptKey(key)) {
|
||||||
let text = this._multilineInputWidget.value.substr(0, this._multilineInputWidget.selectionStart);
|
let text = this.widgets.multilineInput.value.substr(0, this.widgets.multilineInput.selectionStart);
|
||||||
if (text.match(this._multilineRegexp)) {
|
if (text.match(this._multilineRegexp)) {
|
||||||
text = text.replace(this._multilineRegexp, "");
|
text = text.replace(this._multilineRegexp, "");
|
||||||
modes.pop();
|
modes.pop();
|
||||||
this._multilineInputWidget.collapsed = true;
|
this.widgets.multilineInput.collapsed = true;
|
||||||
this._multilineCallback.call(this, text);
|
this._multilineCallback.call(this, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (events.isCancelKey(key)) {
|
else if (events.isCancelKey(key)) {
|
||||||
modes.pop();
|
modes.pop();
|
||||||
this._multilineInputWidget.collapsed = true;
|
this.widgets.multilineInput.collapsed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event.type == "blur") {
|
else if (event.type == "blur") {
|
||||||
if (modes.extended & modes.INPUT_MULTILINE)
|
if (modes.extended & modes.INPUT_MULTILINE)
|
||||||
this.setTimeout(function () { this._multilineInputWidget.inputField.focus(); }, 0);
|
this.setTimeout(function () { this.widgets.multilineInput.inputField.focus(); }, 0);
|
||||||
}
|
}
|
||||||
else if (event.type == "input")
|
else if (event.type == "input")
|
||||||
this._autosizeMultilineInputWidget();
|
this._autosizeMultilineInputWidget();
|
||||||
@@ -735,7 +733,7 @@ const CommandLine = Module("commandline", {
|
|||||||
// FIXME: if 'more' is set and the MOW is not scrollable we should still
|
// FIXME: if 'more' is set and the MOW is not scrollable we should still
|
||||||
// allow a down motion after an up rather than closing
|
// allow a down motion after an up rather than closing
|
||||||
onMultilineOutputEvent: function onMultilineOutputEvent(event) {
|
onMultilineOutputEvent: function onMultilineOutputEvent(event) {
|
||||||
let win = this._multilineOutputWidget.contentWindow;
|
let win = this.widgets.multilineOutput.contentWindow;
|
||||||
|
|
||||||
let showMoreHelpPrompt = false;
|
let showMoreHelpPrompt = false;
|
||||||
let showMorePrompt = false;
|
let showMorePrompt = false;
|
||||||
@@ -934,7 +932,7 @@ const CommandLine = Module("commandline", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getSpaceNeeded: function getSpaceNeeded() {
|
getSpaceNeeded: function getSpaceNeeded() {
|
||||||
let rect = this._commandlineWidget.getBoundingClientRect();
|
let rect = this.widgets.commandline.getBoundingClientRect();
|
||||||
let offset = rect.bottom - window.innerHeight;
|
let offset = rect.bottom - window.innerHeight;
|
||||||
return Math.max(0, offset);
|
return Math.max(0, offset);
|
||||||
},
|
},
|
||||||
@@ -953,7 +951,7 @@ const CommandLine = Module("commandline", {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let win = this._multilineOutputWidget.contentWindow;
|
let win = this.widgets.multilineOutput.contentWindow;
|
||||||
function isScrollable() !win.scrollMaxY == 0;
|
function isScrollable() !win.scrollMaxY == 0;
|
||||||
function atEnd() win.scrollY / win.scrollMaxY >= 1;
|
function atEnd() win.scrollY / win.scrollMaxY >= 1;
|
||||||
|
|
||||||
@@ -975,12 +973,12 @@ const CommandLine = Module("commandline", {
|
|||||||
if (!open && this._outputContainer.collapsed)
|
if (!open && this._outputContainer.collapsed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let doc = this._multilineOutputWidget.contentDocument;
|
let doc = this.widgets.multilineOutput.contentDocument;
|
||||||
|
|
||||||
let availableHeight = config.outputHeight;
|
let availableHeight = config.outputHeight;
|
||||||
if (!this._outputContainer.collapsed)
|
if (!this._outputContainer.collapsed)
|
||||||
availableHeight += parseFloat(this._outputContainer.height);
|
availableHeight += parseFloat(this._outputContainer.height);
|
||||||
doc.body.style.minWidth = this._commandlineWidget.scrollWidth + "px";
|
doc.body.style.minWidth = this.widgets.commandline.scrollWidth + "px";
|
||||||
this._outputContainer.height = Math.min(doc.height, availableHeight) + "px";
|
this._outputContainer.height = Math.min(doc.height, availableHeight) + "px";
|
||||||
doc.body.style.minWidth = "";
|
doc.body.style.minWidth = "";
|
||||||
this._outputContainer.collapsed = false;
|
this._outputContainer.collapsed = false;
|
||||||
@@ -1086,7 +1084,7 @@ const CommandLine = Module("commandline", {
|
|||||||
while (true) {
|
while (true) {
|
||||||
this.index += diff;
|
this.index += diff;
|
||||||
if (this.index < 0 || this.index > this.store.length) {
|
if (this.index < 0 || this.index > this.store.length) {
|
||||||
this.index = util.Math.constrain(this.index, 0, this.store.length);
|
this.index = Math.constrain(this.index, 0, this.store.length);
|
||||||
dactyl.beep();
|
dactyl.beep();
|
||||||
// I don't know why this kludge is needed. It
|
// I don't know why this kludge is needed. It
|
||||||
// prevents the caret from moving to the end of
|
// prevents the caret from moving to the end of
|
||||||
@@ -1146,8 +1144,8 @@ const CommandLine = Module("commandline", {
|
|||||||
// Change the completion text.
|
// Change the completion text.
|
||||||
// The second line is a hack to deal with some substring
|
// The second line is a hack to deal with some substring
|
||||||
// preview corner cases.
|
// preview corner cases.
|
||||||
commandline._commandWidget.value = this.prefix + completion + this.suffix;
|
commandline.widgets.command.value = this.prefix + completion + this.suffix;
|
||||||
this.editor.selection.focusNode.textContent = commandline._commandWidget.value;
|
this.editor.selection.focusNode.textContent = commandline.widgets.command.value;
|
||||||
|
|
||||||
// Reset the caret to one position after the completion.
|
// Reset the caret to one position after the completion.
|
||||||
this.caret = this.prefix.length + completion.length;
|
this.caret = this.prefix.length + completion.length;
|
||||||
@@ -1155,8 +1153,8 @@ const CommandLine = Module("commandline", {
|
|||||||
|
|
||||||
get caret() this.editor.selection.focusOffset,
|
get caret() this.editor.selection.focusOffset,
|
||||||
set caret(offset) {
|
set caret(offset) {
|
||||||
commandline._commandWidget.selectionStart = offset;
|
commandline.widgets.command.selectionStart = offset;
|
||||||
commandline._commandWidget.selectionEnd = offset;
|
commandline.widgets.command.selectionEnd = offset;
|
||||||
},
|
},
|
||||||
|
|
||||||
get start() this.context.allItems.start,
|
get start() this.context.allItems.start,
|
||||||
@@ -1236,9 +1234,9 @@ const CommandLine = Module("commandline", {
|
|||||||
}
|
}
|
||||||
else if (this.removeSubstring) {
|
else if (this.removeSubstring) {
|
||||||
let str = this.removeSubstring;
|
let str = this.removeSubstring;
|
||||||
let cmd = commandline._commandWidget.value;
|
let cmd = commandline.widgets.command.value;
|
||||||
if (cmd.substr(cmd.length - str.length) == str)
|
if (cmd.substr(cmd.length - str.length) == str)
|
||||||
commandline._commandWidget.value = cmd.substr(0, cmd.length - str.length);
|
commandline.widgets.command.value = cmd.substr(0, cmd.length - str.length);
|
||||||
}
|
}
|
||||||
delete this.removeSubstring;
|
delete this.removeSubstring;
|
||||||
},
|
},
|
||||||
@@ -1289,7 +1287,7 @@ const CommandLine = Module("commandline", {
|
|||||||
idx = null;
|
idx = null;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
idx = util.Math.constrain(idx, 0, this.items.length - 1);
|
idx = Math.constrain(idx, 0, this.items.length - 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1310,7 +1308,7 @@ const CommandLine = Module("commandline", {
|
|||||||
for (let [, context] in Iterator(list)) {
|
for (let [, context] in Iterator(list)) {
|
||||||
function done() !(idx >= n + context.items.length || idx == -2 && !context.items.length);
|
function done() !(idx >= n + context.items.length || idx == -2 && !context.items.length);
|
||||||
while (context.incomplete && !done())
|
while (context.incomplete && !done())
|
||||||
dactyl.threadYield(false, true);
|
util.threadYield(false, true);
|
||||||
|
|
||||||
if (done())
|
if (done())
|
||||||
break;
|
break;
|
||||||
@@ -1369,7 +1367,7 @@ const CommandLine = Module("commandline", {
|
|||||||
if (this.type.list)
|
if (this.type.list)
|
||||||
this.itemList.show();
|
this.itemList.show();
|
||||||
|
|
||||||
this.wildIndex = util.Math.constrain(this.wildIndex + 1, 0, this.wildtypes.length - 1);
|
this.wildIndex = Math.constrain(this.wildIndex + 1, 0, this.wildtypes.length - 1);
|
||||||
this.preview();
|
this.preview();
|
||||||
|
|
||||||
commandline._statusTimer.tell();
|
commandline._statusTimer.tell();
|
||||||
@@ -1651,7 +1649,7 @@ const ItemList = Class("ItemList", {
|
|||||||
let off = 0;
|
let off = 0;
|
||||||
let end = this._startIndex + options["maxitems"];
|
let end = this._startIndex + options["maxitems"];
|
||||||
function getRows(context) {
|
function getRows(context) {
|
||||||
function fix(n) util.Math.constrain(n, 0, len);
|
function fix(n) Math.constrain(n, 0, len);
|
||||||
let len = context.items.length;
|
let len = context.items.length;
|
||||||
let start = off;
|
let start = off;
|
||||||
end -= !!context.message + context.incomplete;
|
end -= !!context.message + context.incomplete;
|
||||||
|
|||||||
@@ -858,23 +858,7 @@ const Commands = Module("commands", {
|
|||||||
return [len - str.length, arg, quote];
|
return [len - str.length, arg, quote];
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
mappings: function () {
|
|
||||||
mappings.add(config.browserModes,
|
|
||||||
["@:"], "Repeat the last Ex command",
|
|
||||||
function (count) {
|
|
||||||
if (commands.repeat) {
|
|
||||||
for (let i in util.interruptibleRange(0, Math.max(count, 1), 100))
|
|
||||||
dactyl.execute(commands.repeat);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dactyl.echoerr("E30: No previous command line");
|
|
||||||
},
|
|
||||||
{ count: true });
|
|
||||||
},
|
|
||||||
|
|
||||||
completion: function () {
|
completion: function () {
|
||||||
JavaScript.setCompleter(this.get, [function () ([c.name, c.description] for (c in commands))]);
|
|
||||||
|
|
||||||
completion.command = function command(context) {
|
completion.command = function command(context) {
|
||||||
context.title = ["Command"];
|
context.title = ["Command"];
|
||||||
context.keys = { text: "longNames", description: "description" };
|
context.keys = { text: "longNames", description: "description" };
|
||||||
@@ -1105,6 +1089,22 @@ const Commands = Module("commands", {
|
|||||||
argCount: "1",
|
argCount: "1",
|
||||||
completer: function (context) completion.userCommand(context)
|
completer: function (context) completion.userCommand(context)
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
javascript: function () {
|
||||||
|
JavaScript.setCompleter(this.get, [function () ([c.name, c.description] for (c in commands))]);
|
||||||
|
},
|
||||||
|
mappings: function () {
|
||||||
|
mappings.add(config.browserModes,
|
||||||
|
["@:"], "Repeat the last Ex command",
|
||||||
|
function (count) {
|
||||||
|
if (commands.repeat) {
|
||||||
|
for (let i in util.interruptibleRange(0, Math.max(count, 1), 100))
|
||||||
|
dactyl.execute(commands.repeat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dactyl.echoerr("E30: No previous command line");
|
||||||
|
},
|
||||||
|
{ count: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ const CompletionContext = Class("CompletionContext", {
|
|||||||
this._completions = items;
|
this._completions = items;
|
||||||
let self = this;
|
let self = this;
|
||||||
if (this.updateAsync && !this.noUpdate)
|
if (this.updateAsync && !this.noUpdate)
|
||||||
dactyl.callInMainThread(function () { self.onUpdate.call(self); });
|
util.callInMainThread(function () { self.onUpdate.call(self); });
|
||||||
},
|
},
|
||||||
|
|
||||||
get createRow() this._createRow || template.completionRow, // XXX
|
get createRow() this._createRow || template.completionRow, // XXX
|
||||||
@@ -326,7 +326,7 @@ const CompletionContext = Class("CompletionContext", {
|
|||||||
this.cache.backgroundLock = lock;
|
this.cache.backgroundLock = lock;
|
||||||
this.incomplete = true;
|
this.incomplete = true;
|
||||||
let thread = this.getCache("backgroundThread", dactyl.newThread);
|
let thread = this.getCache("backgroundThread", dactyl.newThread);
|
||||||
dactyl.callAsync(thread, this, function () {
|
util.callAsync(thread, this, function () {
|
||||||
if (this.cache.backgroundLock != lock)
|
if (this.cache.backgroundLock != lock)
|
||||||
return;
|
return;
|
||||||
let items = this.generate();
|
let items = this.generate();
|
||||||
@@ -609,7 +609,7 @@ const CompletionContext = Class("CompletionContext", {
|
|||||||
wait: function wait(interruptable, timeout) {
|
wait: function wait(interruptable, timeout) {
|
||||||
let end = Date.now() + timeout;
|
let end = Date.now() + timeout;
|
||||||
while (this.incomplete && (!timeout || Date.now() > end))
|
while (this.incomplete && (!timeout || Date.now() > end))
|
||||||
dactyl.threadYield(false, interruptable);
|
util.threadYield(false, interruptable);
|
||||||
return this.incomplete;
|
return this.incomplete;
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
@@ -668,7 +668,7 @@ const Completion = Module("completion", {
|
|||||||
context = context.contexts["/list"];
|
context = context.contexts["/list"];
|
||||||
context.wait();
|
context.wait();
|
||||||
|
|
||||||
let list = template.commandOutput(
|
let list = template.commandOutput(commandline.command,
|
||||||
<div highlight="Completions">
|
<div highlight="Completions">
|
||||||
{ template.map(context.contextList.filter(function (c) c.hasItems),
|
{ template.map(context.contextList.filter(function (c) c.hasItems),
|
||||||
function (context)
|
function (context)
|
||||||
@@ -765,7 +765,7 @@ const Completion = Module("completion", {
|
|||||||
commands.add(["contexts"],
|
commands.add(["contexts"],
|
||||||
"List the completion contexts used during completion of an ex command",
|
"List the completion contexts used during completion of an ex command",
|
||||||
function (args) {
|
function (args) {
|
||||||
commandline.echo(template.commandOutput(
|
commandline.echo(template.commandOutput(commandline.command,
|
||||||
<div highlight="Completions">
|
<div highlight="Completions">
|
||||||
{ template.completionRow(["Context", "Title"], "CompTitle") }
|
{ template.completionRow(["Context", "Title"], "CompTitle") }
|
||||||
{ template.map(completion.contextList || [], function (item) template.completionRow(item, "CompItem")) }
|
{ template.map(completion.contextList || [], function (item) template.completionRow(item, "CompItem")) }
|
||||||
|
|||||||
@@ -7,6 +7,15 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const ConfigBase = Class(ModuleBase, {
|
const ConfigBase = Class(ModuleBase, {
|
||||||
|
/**
|
||||||
|
* Called on dactyl startup to allow for any arbitrary application-specific
|
||||||
|
* initialization code. Must call superclass's init function.
|
||||||
|
*/
|
||||||
|
init: function () {
|
||||||
|
highlight.styleableChrome = this.styleableChrome;
|
||||||
|
highlight.loadCSS(this.CSS);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {[["string", "string"]]} A sequence of names and descriptions
|
* @property {[["string", "string"]]} A sequence of names and descriptions
|
||||||
* of the autocommands available in this application. Primarily used
|
* of the autocommands available in this application. Primarily used
|
||||||
@@ -14,8 +23,8 @@ const ConfigBase = Class(ModuleBase, {
|
|||||||
*/
|
*/
|
||||||
autocommands: [],
|
autocommands: [],
|
||||||
|
|
||||||
browser: window.gBrowser,
|
get browser() window.gBrowser,
|
||||||
tabbrowser: window.gBrowser,
|
get tabbrowser() window.gBrowser,
|
||||||
|
|
||||||
get browserModes() [modes.NORMAL],
|
get browserModes() [modes.NORMAL],
|
||||||
|
|
||||||
@@ -55,12 +64,6 @@ const ConfigBase = Class(ModuleBase, {
|
|||||||
*/
|
*/
|
||||||
hostApplication: null,
|
hostApplication: null,
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {function} Called on dactyl startup to allow for any
|
|
||||||
* arbitrary application-specific initialization code.
|
|
||||||
*/
|
|
||||||
init: function () {},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {Object} A map between key names for key events should be ignored,
|
* @property {Object} A map between key names for key events should be ignored,
|
||||||
* and a mask of the modes in which they should be ignored.
|
* and a mask of the modes in which they should be ignored.
|
||||||
@@ -102,8 +105,229 @@ const ConfigBase = Class(ModuleBase, {
|
|||||||
* @property {string} The leaf name of any temp files created by
|
* @property {string} The leaf name of any temp files created by
|
||||||
* {@link io.createTempFile}.
|
* {@link io.createTempFile}.
|
||||||
*/
|
*/
|
||||||
get tempFile() this.name.toLowerCase() + ".tmp"
|
get tempFile() this.name.toLowerCase() + ".tmp",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constant
|
||||||
|
* @property {string} The default highlighting rules. They have the
|
||||||
|
* form:
|
||||||
|
* rule ::= selector space space+ css
|
||||||
|
* selector ::= group
|
||||||
|
* | group "," css-selector
|
||||||
|
* | group "," css-selector "," scope
|
||||||
|
* group ::= groupname
|
||||||
|
* | groupname css-selector
|
||||||
|
*/
|
||||||
|
// <css>
|
||||||
|
CSS: <![CDATA[
|
||||||
|
Boolean color: red;
|
||||||
|
Function color: navy;
|
||||||
|
Null color: blue;
|
||||||
|
Number color: blue;
|
||||||
|
Object color: maroon;
|
||||||
|
String color: green;
|
||||||
|
|
||||||
|
Key font-weight: bold;
|
||||||
|
|
||||||
|
Enabled color: blue;
|
||||||
|
Disabled color: red;
|
||||||
|
|
||||||
|
Normal color: black; background: white;
|
||||||
|
ErrorMsg color: white; background: red; font-weight: bold;
|
||||||
|
InfoMsg color: black; background: white;
|
||||||
|
ModeMsg color: black; background: white;
|
||||||
|
MoreMsg color: green; background: white;
|
||||||
|
WarningMsg color: red; background: white;
|
||||||
|
Message white-space: normal; min-width: 100%; padding-left: 2em; text-indent: -2em; display: block;
|
||||||
|
NonText color: blue; min-height: 16px; padding-left: 2px;
|
||||||
|
Preview color: gray;
|
||||||
|
|
||||||
|
CmdLine,>* font-family: monospace; padding: 1px;
|
||||||
|
CmdOutput white-space: pre;
|
||||||
|
|
||||||
|
CompGroup
|
||||||
|
CompGroup:not(:first-of-type) margin-top: .5em;
|
||||||
|
CompTitle color: magenta; background: white; font-weight: bold;
|
||||||
|
CompTitle>* padding: 0 .5ex;
|
||||||
|
CompMsg font-style: italic; margin-left: 16px;
|
||||||
|
CompItem
|
||||||
|
CompItem[selected] background: yellow;
|
||||||
|
CompItem>* padding: 0 .5ex;
|
||||||
|
CompIcon width: 16px; min-width: 16px; display: inline-block; margin-right: .5ex;
|
||||||
|
CompIcon>img max-width: 16px; max-height: 16px; vertical-align: middle;
|
||||||
|
CompResult width: 45%; overflow: hidden;
|
||||||
|
CompDesc color: gray; width: 50%;
|
||||||
|
CompLess text-align: center; height: 0; line-height: .5ex; padding-top: 1ex;
|
||||||
|
CompLess::after content: "\2303" /* Unicode up arrowhead */
|
||||||
|
CompMore text-align: center; height: .5ex; line-height: .5ex; margin-bottom: -.5ex;
|
||||||
|
CompMore::after content: "\2304" /* Unicode down arrowhead */
|
||||||
|
|
||||||
|
Gradient height: 1px; margin-bottom: -1px; margin-top: -1px;
|
||||||
|
GradientLeft background-color: magenta;
|
||||||
|
GradientRight background-color: white;
|
||||||
|
|
||||||
|
Indicator color: blue;
|
||||||
|
Filter font-weight: bold;
|
||||||
|
|
||||||
|
Keyword color: red;
|
||||||
|
Tag color: blue;
|
||||||
|
|
||||||
|
LineNr color: orange; background: white;
|
||||||
|
Question color: green; background: white; font-weight: bold;
|
||||||
|
|
||||||
|
StatusLine color: white; background: black;
|
||||||
|
StatusLineBroken color: black; background: #FFa0a0 /* light-red */
|
||||||
|
StatusLineSecure color: black; background: #a0a0FF /* light-blue */
|
||||||
|
StatusLineExtended color: black; background: #a0FFa0 /* light-green */
|
||||||
|
|
||||||
|
TabClose,.tab-close-button
|
||||||
|
TabIcon,.tab-icon
|
||||||
|
TabText,.tab-text
|
||||||
|
TabNumber font-weight: bold; margin: 0px; padding-right: .3ex;
|
||||||
|
TabIconNumber {
|
||||||
|
font-weight: bold;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: black -1px 0 1px, black 0 1px 1px, black 1px 0 1px, black 0 -1px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
Title color: magenta; background: white; font-weight: bold;
|
||||||
|
URL text-decoration: none; color: green; background: inherit;
|
||||||
|
URL:hover text-decoration: underline; cursor: pointer;
|
||||||
|
|
||||||
|
FrameIndicator,,* {
|
||||||
|
background-color: red;
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: 999;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bell border: none; background-color: black;
|
||||||
|
Hint,,* {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: white;
|
||||||
|
background-color: red;
|
||||||
|
border-color: ButtonShadow;
|
||||||
|
border-width: 0px;
|
||||||
|
border-style: solid;
|
||||||
|
padding: 0px 1px 0px 1px;
|
||||||
|
}
|
||||||
|
Hint::after,,* content: attr(number);
|
||||||
|
HintElem,,* background-color: yellow; color: black;
|
||||||
|
HintActive,,* background-color: #88FF00; color: black;
|
||||||
|
HintImage,,* opacity: .5;
|
||||||
|
|
||||||
|
Help font-size: 8pt; line-height: 1.4em; font-family: -moz-fixed;
|
||||||
|
|
||||||
|
HelpArg color: #6A97D4;
|
||||||
|
HelpOptionalArg color: #6A97D4;
|
||||||
|
|
||||||
|
HelpBody display: block; margin: 1em auto; max-width: 100ex;
|
||||||
|
HelpBorder,*,dactyl://help/* border-color: silver; border-width: 0px; border-style: solid;
|
||||||
|
HelpCode display: block; white-space: pre; margin-left: 2em; font-family: Terminus, Fixed, monospace;
|
||||||
|
|
||||||
|
HelpDefault margin-right: 1ex; white-space: pre;
|
||||||
|
|
||||||
|
HelpDescription display: block;
|
||||||
|
HelpEm,html|em,dactyl://help/* font-weight: bold; font-style: normal;
|
||||||
|
|
||||||
|
HelpEx display: inline-block; color: #527BBD; font-weight: bold;
|
||||||
|
|
||||||
|
HelpExample display: block; margin: 1em 0;
|
||||||
|
HelpExample::before content: "Example: "; font-weight: bold;
|
||||||
|
|
||||||
|
HelpInfo display: block; width: 20em; margin-left: auto;
|
||||||
|
HelpInfoLabel display: inline-block; width: 6em; color: magenta; font-weight: bold; vertical-align: text-top;
|
||||||
|
HelpInfoValue display: inline-block; width: 14em; text-decoration: none; vertical-align: text-top;
|
||||||
|
|
||||||
|
HelpItem display: block; margin: 1em 1em 1em 10em; clear: both;
|
||||||
|
|
||||||
|
HelpKey color: #102663;
|
||||||
|
|
||||||
|
HelpLink,html|a,dactyl://help/* text-decoration: none;
|
||||||
|
HelpLink[href]:hover text-decoration: underline;
|
||||||
|
|
||||||
|
HelpList,html|ul,dactyl://help/* display: block; list-style: outside disc;
|
||||||
|
HelpOrderedList,html|ol,dactyl://help/* display: block; list-style: outside decimal;
|
||||||
|
HelpListItem,html|li,dactyl://help/* display: list-item;
|
||||||
|
|
||||||
|
HelpNote color: red; font-weight: bold;
|
||||||
|
|
||||||
|
HelpOpt color: #106326;
|
||||||
|
HelpOptInfo display: inline-block; margin-bottom: 1ex;
|
||||||
|
|
||||||
|
HelpParagraph,html|p,dactyl://help/* display: block; margin: 1em 0em;
|
||||||
|
HelpParagraph:first-child margin-top: 0;
|
||||||
|
HelpSpec display: block; margin-left: -10em; float: left; clear: left; color: #527BBD;
|
||||||
|
|
||||||
|
HelpString display: inline-block; color: green; font-weight: normal; vertical-align: text-top;
|
||||||
|
HelpString::before content: '"';
|
||||||
|
HelpString::after content: '"';
|
||||||
|
HelpString[delim]::before content: attr(delim);
|
||||||
|
HelpString[delim]::after content: attr(delim);
|
||||||
|
|
||||||
|
HelpHead,html|h1,dactyl://help/* {
|
||||||
|
display: block;
|
||||||
|
margin: 1em 0;
|
||||||
|
padding-bottom: .2ex;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
font-size: 2em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #527BBD;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
HelpSubhead,html|h2,dactyl://help/* {
|
||||||
|
display: block;
|
||||||
|
margin: 1em 0;
|
||||||
|
padding-bottom: .2ex;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #527BBD;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
HelpSubsubhead,html|h3,dactyl://help/* {
|
||||||
|
display: block;
|
||||||
|
margin: 1em 0;
|
||||||
|
padding-bottom: .2ex;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #527BBD;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
HelpTOC
|
||||||
|
HelpTOC>ol ol margin-left: -1em;
|
||||||
|
|
||||||
|
HelpTab,html|dl,dactyl://help/* display: table; width: 100%; margin: 1em 0; border-bottom-width: 1px; border-top-width: 1px; padding: .5ex 0; table-layout: fixed;
|
||||||
|
HelpTabColumn,html|column,dactyl://help/* display: table-column;
|
||||||
|
HelpTabColumn:first-child width: 25%;
|
||||||
|
HelpTabTitle,html|dt,dactyl://help/* display: table-cell; padding: .1ex 1ex; font-weight: bold;
|
||||||
|
HelpTabDescription,html|dd,dactyl://help/* display: table-cell; padding: .1ex 1ex; border-width: 0px;
|
||||||
|
HelpTabRow,html|dl>html|tr,dactyl://help/* display: table-row;
|
||||||
|
|
||||||
|
HelpTag display: inline-block; color: #527BBD; margin-left: 1ex; font-size: 8pt; font-weight: bold;
|
||||||
|
HelpTags display: block; float: right; clear: right;
|
||||||
|
HelpTopic color: #102663;
|
||||||
|
HelpType margin-right: 2ex;
|
||||||
|
|
||||||
|
HelpWarning color: red; font-weight: bold;
|
||||||
|
|
||||||
|
Logo
|
||||||
|
|
||||||
|
Search,,* {
|
||||||
|
font-size: inherit;
|
||||||
|
padding: 0;
|
||||||
|
color: black;
|
||||||
|
background-color: yellow;
|
||||||
|
}
|
||||||
|
]]>.toString()
|
||||||
});
|
});
|
||||||
|
|
||||||
// vim: set fdm=marker sw=4 ts=4 et:
|
// vim: set fdm=marker sw=4 ts=4 et:
|
||||||
|
|||||||
@@ -38,13 +38,6 @@ const Storage = Module("storage", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function Runnable(self, func, args) {
|
|
||||||
return {
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRunnable]),
|
|
||||||
run: function () { func.apply(self, args || []); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const FailedAssertion = Class("FailedAssertion", Error, {
|
const FailedAssertion = Class("FailedAssertion", Error, {
|
||||||
init: function (message) {
|
init: function (message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
@@ -92,40 +85,6 @@ const Dactyl = Module("dactyl", {
|
|||||||
/** @property {Element} The currently focused element. */
|
/** @property {Element} The currently focused element. */
|
||||||
get focus() document.commandDispatcher.focusedElement,
|
get focus() document.commandDispatcher.focusedElement,
|
||||||
|
|
||||||
get extensions() {
|
|
||||||
const rdf = services.get("rdf");
|
|
||||||
const extensionManager = services.get("extensionManager");
|
|
||||||
|
|
||||||
let extensions = extensionManager.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION, {});
|
|
||||||
|
|
||||||
function getRdfProperty(item, property) {
|
|
||||||
let resource = rdf.GetResource("urn:mozilla:item:" + item.id);
|
|
||||||
let value = "";
|
|
||||||
|
|
||||||
if (resource) {
|
|
||||||
let target = extensionManager.datasource.GetTarget(resource,
|
|
||||||
rdf.GetResource("http://www.mozilla.org/2004/em-rdf#" + property), true);
|
|
||||||
if (target && target instanceof Ci.nsIRDFLiteral)
|
|
||||||
value = target.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//const Extension = Struct("id", "name", "description", "icon", "enabled", "version");
|
|
||||||
return extensions.map(function (e) ({
|
|
||||||
id: e.id,
|
|
||||||
name: e.name,
|
|
||||||
description: getRdfProperty(e, "description"),
|
|
||||||
enabled: getRdfProperty(e, "isDisabled") != "true",
|
|
||||||
icon: e.iconURL,
|
|
||||||
options: getRdfProperty(e, "optionsURL"),
|
|
||||||
version: e.version
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
getExtension: function (name) this.extensions.filter(function (e) e.name == name)[0],
|
|
||||||
|
|
||||||
// Global constants
|
// Global constants
|
||||||
CURRENT_TAB: [],
|
CURRENT_TAB: [],
|
||||||
NEW_TAB: [],
|
NEW_TAB: [],
|
||||||
@@ -183,7 +142,7 @@ const Dactyl = Module("dactyl", {
|
|||||||
beep: function () {
|
beep: function () {
|
||||||
// FIXME: popups clear the command line
|
// FIXME: popups clear the command line
|
||||||
if (options["visualbell"]) {
|
if (options["visualbell"]) {
|
||||||
dactyl.callInMainThread(function () {
|
util.callInMainThread(function () {
|
||||||
// flash the visual bell
|
// flash the visual bell
|
||||||
let popup = document.getElementById("dactyl-visualbell");
|
let popup = document.getElementById("dactyl-visualbell");
|
||||||
let win = config.visualbellWindow;
|
let win = config.visualbellWindow;
|
||||||
@@ -204,45 +163,6 @@ const Dactyl = Module("dactyl", {
|
|||||||
return false; // so you can do: if (...) return dactyl.beep();
|
return false; // so you can do: if (...) return dactyl.beep();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new thread.
|
|
||||||
*/
|
|
||||||
newThread: function () services.get("threadManager").newThread(0),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls a function asynchronously on a new thread.
|
|
||||||
*
|
|
||||||
* @param {nsIThread} thread The thread to call the function on. If no
|
|
||||||
* thread is specified a new one is created.
|
|
||||||
* @optional
|
|
||||||
* @param {Object} self The 'this' object used when executing the
|
|
||||||
* function.
|
|
||||||
* @param {function} func The function to execute.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
callAsync: function (thread, self, func) {
|
|
||||||
thread = thread || services.get("threadManager").newThread(0);
|
|
||||||
thread.dispatch(Runnable(self, func, Array.slice(arguments, 3)), thread.DISPATCH_NORMAL);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls a function synchronously on a new thread.
|
|
||||||
*
|
|
||||||
* NOTE: Be sure to call GUI related methods like alert() or dump()
|
|
||||||
* ONLY in the main thread.
|
|
||||||
*
|
|
||||||
* @param {nsIThread} thread The thread to call the function on. If no
|
|
||||||
* thread is specified a new one is created.
|
|
||||||
* @optional
|
|
||||||
* @param {function} func The function to execute.
|
|
||||||
*/
|
|
||||||
callFunctionInThread: function (thread, func) {
|
|
||||||
thread = thread || services.get("threadManager").newThread(0);
|
|
||||||
|
|
||||||
// DISPATCH_SYNC is necessary, otherwise strange things will happen
|
|
||||||
thread.dispatch(Runnable(null, func, Array.slice(arguments, 2)), thread.DISPATCH_SYNC);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints a message to the console. If <b>msg</b> is an object it is
|
* Prints a message to the console. If <b>msg</b> is an object it is
|
||||||
* pretty printed.
|
* pretty printed.
|
||||||
@@ -488,18 +408,6 @@ const Dactyl = Module("dactyl", {
|
|||||||
*/
|
*/
|
||||||
has: function (feature) config.features.indexOf(feature) >= 0,
|
has: function (feature) config.features.indexOf(feature) >= 0,
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the host application has the specified extension
|
|
||||||
* installed.
|
|
||||||
*
|
|
||||||
* @param {string} name The extension name.
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
hasExtension: function (name) {
|
|
||||||
let extensions = services.get("extensionManager").getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION, {});
|
|
||||||
return extensions.some(function (e) e.name == name);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URL of the specified help <b>topic</b> if it exists.
|
* Returns the URL of the specified help <b>topic</b> if it exists.
|
||||||
*
|
*
|
||||||
@@ -622,6 +530,99 @@ const Dactyl = Module("dactyl", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
exportHelp: function (path) {
|
||||||
|
const FILE = io.File(path);
|
||||||
|
const PATH = FILE.leafName.replace(/\..*/, "") + "/";
|
||||||
|
const TIME = Date.now();
|
||||||
|
|
||||||
|
dactyl.initHelp();
|
||||||
|
let zip = services.create("zipWriter");
|
||||||
|
zip.open(FILE, File.MODE_CREATE | File.MODE_WRONLY | File.MODE_TRUNCATE);
|
||||||
|
function addURIEntry(file, uri)
|
||||||
|
zip.addEntryChannel(PATH + file, TIME, 9,
|
||||||
|
services.get("io").newChannel(uri, null, null), false);
|
||||||
|
function addDataEntry(file, data) // Inideal to an extreme.
|
||||||
|
addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data));
|
||||||
|
|
||||||
|
let empty = util.Array.toObject(
|
||||||
|
"area base basefont br col frame hr img input isindex link meta param"
|
||||||
|
.split(" ").map(Array.concat));
|
||||||
|
|
||||||
|
let chrome = {};
|
||||||
|
for (let [file,] in Iterator(services.get("dactyl:").FILE_MAP)) {
|
||||||
|
dactyl.open("dactyl://help/" + file);
|
||||||
|
dactyl.modules.events.waitForPageLoad();
|
||||||
|
let data = [
|
||||||
|
'<?xml version="1.0" encoding="UTF-8"?>\n',
|
||||||
|
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n',
|
||||||
|
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
|
||||||
|
];
|
||||||
|
function fix(node) {
|
||||||
|
switch(node.nodeType) {
|
||||||
|
case Node.ELEMENT_NODE:
|
||||||
|
if (node instanceof HTMLScriptElement)
|
||||||
|
return;
|
||||||
|
|
||||||
|
data.push("<"); data.push(node.localName);
|
||||||
|
if (node instanceof HTMLHtmlElement)
|
||||||
|
data.push(" xmlns=" + XHTML.uri.quote());
|
||||||
|
|
||||||
|
for (let { name: name, value: value } in util.Array.itervalues(node.attributes)) {
|
||||||
|
if (name == "dactyl:highlight") {
|
||||||
|
name = "class";
|
||||||
|
value = "hl-" + value;
|
||||||
|
}
|
||||||
|
if (name == "href") {
|
||||||
|
if (value.indexOf("dactyl://help-tag/") == 0)
|
||||||
|
value = services.get("io").newChannel(value, null, null).originalURI.path.substr(1);
|
||||||
|
if (!/[#\/]/.test(value))
|
||||||
|
value += ".xhtml";
|
||||||
|
}
|
||||||
|
if (name == "src" && value.indexOf(":") > 0) {
|
||||||
|
chrome[value] = value.replace(/.*\//, "");;
|
||||||
|
value = value.replace(/.*\//, "");
|
||||||
|
}
|
||||||
|
data.push(" ");
|
||||||
|
data.push(name);
|
||||||
|
data.push('="');
|
||||||
|
data.push(<>{value}</>.toXMLString());
|
||||||
|
data.push('"')
|
||||||
|
}
|
||||||
|
if (node.localName in empty)
|
||||||
|
data.push(" />");
|
||||||
|
else {
|
||||||
|
data.push(">");
|
||||||
|
if (node instanceof HTMLHeadElement)
|
||||||
|
data.push(<link rel="stylesheet" type="text/css" href="help.css"/>.toXMLString());
|
||||||
|
Array.map(node.childNodes, arguments.callee);
|
||||||
|
data.push("</"); data.push(node.localName); data.push(">");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Node.TEXT_NODE:
|
||||||
|
data.push(<>{node.textContent}</>.toXMLString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fix(content.document.documentElement);
|
||||||
|
addDataEntry(file + ".xhtml", data.join(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = [h.selector.replace(/^\[.*?=(.*?)\]/, ".hl-$1").replace(/html\|/, "") +
|
||||||
|
"\t{" + h.value + "}"
|
||||||
|
for (h in highlight) if (/^Help|^Logo/.test(h.class))];
|
||||||
|
|
||||||
|
data = data.join("\n");
|
||||||
|
addDataEntry("help.css", data.replace(/chrome:[^ ")]+\//g, ""));
|
||||||
|
|
||||||
|
let re = /(chrome:[^ ");]+\/)([^ ");]+)/g;
|
||||||
|
while ((m = re.exec(data)))
|
||||||
|
chrome[m[0]] = m[2];
|
||||||
|
|
||||||
|
for (let [uri, leaf] in Iterator(chrome))
|
||||||
|
addURIEntry(leaf, uri);
|
||||||
|
|
||||||
|
zip.close();
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the help page containing the specified <b>topic</b> if it
|
* Opens the help page containing the specified <b>topic</b> if it
|
||||||
* exists.
|
* exists.
|
||||||
@@ -1016,34 +1017,6 @@ const Dactyl = Module("dactyl", {
|
|||||||
return commands.parseArgs(cmdline, options, "*");
|
return commands.parseArgs(cmdline, options, "*");
|
||||||
},
|
},
|
||||||
|
|
||||||
sleep: function (delay) {
|
|
||||||
let mainThread = services.get("threadManager").mainThread;
|
|
||||||
|
|
||||||
let end = Date.now() + delay;
|
|
||||||
while (Date.now() < end)
|
|
||||||
mainThread.processNextEvent(true);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
callInMainThread: function (callback, self) {
|
|
||||||
let mainThread = services.get("threadManager").mainThread;
|
|
||||||
if (!services.get("threadManager").isMainThread)
|
|
||||||
mainThread.dispatch(Runnable(self, callback), mainThread.DISPATCH_NORMAL);
|
|
||||||
else
|
|
||||||
callback.call(self);
|
|
||||||
},
|
|
||||||
|
|
||||||
threadYield: function (flush, interruptable) {
|
|
||||||
let mainThread = services.get("threadManager").mainThread;
|
|
||||||
dactyl.interrupted = false;
|
|
||||||
do {
|
|
||||||
mainThread.processNextEvent(!flush);
|
|
||||||
if (dactyl.interrupted)
|
|
||||||
throw new Error("Interrupted");
|
|
||||||
}
|
|
||||||
while (flush === true && mainThread.hasPendingEvents());
|
|
||||||
},
|
|
||||||
|
|
||||||
variableReference: function (string) {
|
variableReference: function (string) {
|
||||||
if (!string)
|
if (!string)
|
||||||
return [null, null, null];
|
return [null, null, null];
|
||||||
@@ -1097,7 +1070,7 @@ const Dactyl = Module("dactyl", {
|
|||||||
|
|
||||||
// return the platform normalized to Vim values
|
// return the platform normalized to Vim values
|
||||||
getPlatformFeature: function () {
|
getPlatformFeature: function () {
|
||||||
let platform = navigator.platform;
|
let platform = services.get("runtime").OS;
|
||||||
return /^Mac/.test(platform) ? "MacUnix" : platform == "Win32" ? "Win32" : "Unix";
|
return /^Mac/.test(platform) ? "MacUnix" : platform == "Win32" ? "Win32" : "Unix";
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1521,7 +1494,6 @@ const Dactyl = Module("dactyl", {
|
|||||||
literal: 0
|
literal: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: maybe indicate pending status too?
|
|
||||||
commands.add(["extens[ions]", "exts"],
|
commands.add(["extens[ions]", "exts"],
|
||||||
"List available extensions",
|
"List available extensions",
|
||||||
function (args) {
|
function (args) {
|
||||||
@@ -1558,8 +1530,6 @@ const Dactyl = Module("dactyl", {
|
|||||||
},
|
},
|
||||||
{ argCount: "?" });
|
{ argCount: "?" });
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
commands.add(["exu[sage]"],
|
commands.add(["exu[sage]"],
|
||||||
"List all Ex commands with a short description",
|
"List all Ex commands with a short description",
|
||||||
function (args) { Dactyl.showHelpIndex("ex-cmd-index", commands, args.bang); }, {
|
function (args) { Dactyl.showHelpIndex("ex-cmd-index", commands, args.bang); }, {
|
||||||
@@ -1726,7 +1696,7 @@ const Dactyl = Module("dactyl", {
|
|||||||
else
|
else
|
||||||
totalUnits = "msec";
|
totalUnits = "msec";
|
||||||
|
|
||||||
let str = template.commandOutput(
|
let str = template.commandOutput(commandline.command,
|
||||||
<table>
|
<table>
|
||||||
<tr highlight="Title" align="left">
|
<tr highlight="Title" align="left">
|
||||||
<th colspan="3">Code execution summary</th>
|
<th colspan="3">Code execution summary</th>
|
||||||
@@ -1797,7 +1767,8 @@ const Dactyl = Module("dactyl", {
|
|||||||
if (args.bang)
|
if (args.bang)
|
||||||
dactyl.open("about:");
|
dactyl.open("about:");
|
||||||
else
|
else
|
||||||
dactyl.echo(template.commandOutput(<>{config.name} {dactyl.version} running on:<br/>{navigator.userAgent}</>));
|
dactyl.echo(template.commandOutput(commandline.command,
|
||||||
|
<>{config.name} {dactyl.version} running on:<br/>{navigator.userAgent}</>));
|
||||||
}, {
|
}, {
|
||||||
argCount: "0",
|
argCount: "0",
|
||||||
bang: true
|
bang: true
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ const Editor = Module("editor", {
|
|||||||
dactyl.assert(args.length >= 1, "No editor specified");
|
dactyl.assert(args.length >= 1, "No editor specified");
|
||||||
|
|
||||||
args.push(path);
|
args.push(path);
|
||||||
dactyl.callFunctionInThread(null, io.run, io.expandPath(args.shift()), args, true);
|
util.callInThread(null, io.run, io.expandPath(args.shift()), args, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: clean up with 2 functions for textboxes and currentEditor?
|
// TODO: clean up with 2 functions for textboxes and currentEditor?
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
try { __dactyl_eval_result = eval(__dactyl_eval_string);
|
try { __dactyl_eval_result = eval(__dactyl_eval_string); }
|
||||||
}
|
catch (e) { __dactyl_eval_error = e; }
|
||||||
catch (e) {
|
|
||||||
__dactyl_eval_error = e;
|
|
||||||
}
|
|
||||||
// IMPORTANT: The eval statement *must* remain on the first line
|
// IMPORTANT: The eval statement *must* remain on the first line
|
||||||
// in order for line numbering in any errors to remain correct.
|
// in order for line numbering in any errors to remain correct.
|
||||||
|
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ const Events = Module("events", {
|
|||||||
commandline.quiet = quiet;
|
commandline.quiet = quiet;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dactyl.threadYield(1, true);
|
util.threadYield(1, true);
|
||||||
|
|
||||||
for (let [, evt_obj] in Iterator(events.fromString(keys))) {
|
for (let [, evt_obj] in Iterator(events.fromString(keys))) {
|
||||||
let elem = dactyl.focus || window.content;
|
let elem = dactyl.focus || window.content;
|
||||||
@@ -614,7 +614,7 @@ const Events = Module("events", {
|
|||||||
*/
|
*/
|
||||||
waitForPageLoad: function () {
|
waitForPageLoad: function () {
|
||||||
//dactyl.dump("start waiting in loaded state: " + buffer.loaded);
|
//dactyl.dump("start waiting in loaded state: " + buffer.loaded);
|
||||||
dactyl.threadYield(true); // clear queue
|
util.threadYield(true); // clear queue
|
||||||
|
|
||||||
if (buffer.loaded == 1)
|
if (buffer.loaded == 1)
|
||||||
return true;
|
return true;
|
||||||
@@ -624,7 +624,7 @@ const Events = Module("events", {
|
|||||||
let end = start + (maxWaitTime * 1000); // maximum time to wait - TODO: add option
|
let end = start + (maxWaitTime * 1000); // maximum time to wait - TODO: add option
|
||||||
let now;
|
let now;
|
||||||
while (now = Date.now(), now < end) {
|
while (now = Date.now(), now < end) {
|
||||||
dactyl.threadYield();
|
util.threadYield();
|
||||||
//if ((now - start) % 1000 < 10)
|
//if ((now - start) % 1000 < 10)
|
||||||
// dactyl.dump("waited: " + (now - start) + " ms");
|
// dactyl.dump("waited: " + (now - start) + " ms");
|
||||||
|
|
||||||
@@ -632,7 +632,7 @@ const Events = Module("events", {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (buffer.loaded > 0) {
|
if (buffer.loaded > 0) {
|
||||||
dactyl.sleep(250);
|
util.sleep(250);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -799,7 +799,7 @@ const Events = Module("events", {
|
|||||||
|
|
||||||
let urlbar = document.getElementById("urlbar");
|
let urlbar = document.getElementById("urlbar");
|
||||||
if (elem == null && urlbar && urlbar.inputField == this._lastFocus)
|
if (elem == null && urlbar && urlbar.inputField == this._lastFocus)
|
||||||
dactyl.threadYield(true);
|
util.threadYield(true);
|
||||||
|
|
||||||
if (dactyl.mode & (modes.EMBED | modes.INSERT | modes.TEXTAREA | modes.VISUAL))
|
if (dactyl.mode & (modes.EMBED | modes.INSERT | modes.TEXTAREA | modes.VISUAL))
|
||||||
modes.reset();
|
modes.reset();
|
||||||
@@ -837,7 +837,7 @@ const Events = Module("events", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key == "<C-c>")
|
if (key == "<C-c>")
|
||||||
dactyl.interrupted = true;
|
util.interrupted = true;
|
||||||
|
|
||||||
// feedingKeys needs to be separate from interrupted so
|
// feedingKeys needs to be separate from interrupted so
|
||||||
// we can differentiate between a recorded <C-c>
|
// we can differentiate between a recorded <C-c>
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ const Hints = Module("hints", {
|
|||||||
hints.escNumbers = false;
|
hints.escNumbers = false;
|
||||||
|
|
||||||
if (this._activeTimeout)
|
if (this._activeTimeout)
|
||||||
clearTimeout(this._activeTimeout);
|
this._activeTimeout.cancel();
|
||||||
this._activeTimeout = null;
|
this._activeTimeout = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -504,7 +504,7 @@ const Hints = Module("hints", {
|
|||||||
|
|
||||||
// clear any timeout which might be active after pressing a number
|
// clear any timeout which might be active after pressing a number
|
||||||
if (this._activeTimeout) {
|
if (this._activeTimeout) {
|
||||||
clearTimeout(this._activeTimeout);
|
this._activeTimeout.cancel();
|
||||||
this._activeTimeout = null;
|
this._activeTimeout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,7 +728,7 @@ const Hints = Module("hints", {
|
|||||||
this._generate(win);
|
this._generate(win);
|
||||||
|
|
||||||
// get all keys from the input queue
|
// get all keys from the input queue
|
||||||
dactyl.threadYield(true);
|
util.threadYield(true);
|
||||||
|
|
||||||
this._canUpdate = true;
|
this._canUpdate = true;
|
||||||
this._showHints();
|
this._showHints();
|
||||||
@@ -761,7 +761,7 @@ const Hints = Module("hints", {
|
|||||||
|
|
||||||
// clear any timeout which might be active after pressing a number
|
// clear any timeout which might be active after pressing a number
|
||||||
if (this._activeTimeout) {
|
if (this._activeTimeout) {
|
||||||
clearTimeout(this._activeTimeout);
|
this._activeTimeout.cancel();
|
||||||
this._activeTimeout = null;
|
this._activeTimeout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -864,123 +864,88 @@ const Hints = Module("hints", {
|
|||||||
|
|
||||||
//}}}
|
//}}}
|
||||||
}, {
|
}, {
|
||||||
indexOf: (function () {
|
get translitTable() function () {
|
||||||
const table = [
|
const table = {};
|
||||||
[0x00c0, 0x00c6, ["A"]],
|
[
|
||||||
[0x00c7, 0x00c7, ["C"]],
|
[0x00c0, 0x00c6, ["A"]], [0x00c7, 0x00c7, ["C"]],
|
||||||
[0x00c8, 0x00cb, ["E"]],
|
[0x00c8, 0x00cb, ["E"]], [0x00cc, 0x00cf, ["I"]],
|
||||||
[0x00cc, 0x00cf, ["I"]],
|
[0x00d1, 0x00d1, ["N"]], [0x00d2, 0x00d6, ["O"]],
|
||||||
[0x00d1, 0x00d1, ["N"]],
|
[0x00d8, 0x00d8, ["O"]], [0x00d9, 0x00dc, ["U"]],
|
||||||
[0x00d2, 0x00d6, ["O"]],
|
[0x00dd, 0x00dd, ["Y"]], [0x00e0, 0x00e6, ["a"]],
|
||||||
[0x00d8, 0x00d8, ["O"]],
|
[0x00e7, 0x00e7, ["c"]], [0x00e8, 0x00eb, ["e"]],
|
||||||
[0x00d9, 0x00dc, ["U"]],
|
[0x00ec, 0x00ef, ["i"]], [0x00f1, 0x00f1, ["n"]],
|
||||||
[0x00dd, 0x00dd, ["Y"]],
|
[0x00f2, 0x00f6, ["o"]], [0x00f8, 0x00f8, ["o"]],
|
||||||
[0x00e0, 0x00e6, ["a"]],
|
[0x00f9, 0x00fc, ["u"]], [0x00fd, 0x00fd, ["y"]],
|
||||||
[0x00e7, 0x00e7, ["c"]],
|
[0x00ff, 0x00ff, ["y"]], [0x0100, 0x0105, ["A", "a"]],
|
||||||
[0x00e8, 0x00eb, ["e"]],
|
[0x0106, 0x010d, ["C", "c"]], [0x010e, 0x0111, ["D", "d"]],
|
||||||
[0x00ec, 0x00ef, ["i"]],
|
[0x0112, 0x011b, ["E", "e"]], [0x011c, 0x0123, ["G", "g"]],
|
||||||
[0x00f1, 0x00f1, ["n"]],
|
[0x0124, 0x0127, ["H", "h"]], [0x0128, 0x0130, ["I", "i"]],
|
||||||
[0x00f2, 0x00f6, ["o"]],
|
[0x0132, 0x0133, ["IJ", "ij"]], [0x0134, 0x0135, ["J", "j"]],
|
||||||
[0x00f8, 0x00f8, ["o"]],
|
[0x0136, 0x0136, ["K", "k"]], [0x0139, 0x0142, ["L", "l"]],
|
||||||
[0x00f9, 0x00fc, ["u"]],
|
[0x0143, 0x0148, ["N", "n"]], [0x0149, 0x0149, ["n"]],
|
||||||
[0x00fd, 0x00fd, ["y"]],
|
[0x014c, 0x0151, ["O", "o"]], [0x0152, 0x0153, ["OE", "oe"]],
|
||||||
[0x00ff, 0x00ff, ["y"]],
|
[0x0154, 0x0159, ["R", "r"]], [0x015a, 0x0161, ["S", "s"]],
|
||||||
[0x0100, 0x0105, ["A", "a"]],
|
[0x0162, 0x0167, ["T", "t"]], [0x0168, 0x0173, ["U", "u"]],
|
||||||
[0x0106, 0x010d, ["C", "c"]],
|
[0x0174, 0x0175, ["W", "w"]], [0x0176, 0x0178, ["Y", "y", "Y"]],
|
||||||
[0x010e, 0x0111, ["D", "d"]],
|
[0x0179, 0x017e, ["Z", "z"]], [0x0180, 0x0183, ["b", "B", "B", "b"]],
|
||||||
[0x0112, 0x011b, ["E", "e"]],
|
[0x0187, 0x0188, ["C", "c"]], [0x0189, 0x0189, ["D"]],
|
||||||
[0x011c, 0x0123, ["G", "g"]],
|
|
||||||
[0x0124, 0x0127, ["H", "h"]],
|
|
||||||
[0x0128, 0x0130, ["I", "i"]],
|
|
||||||
[0x0132, 0x0133, ["IJ", "ij"]],
|
|
||||||
[0x0134, 0x0135, ["J", "j"]],
|
|
||||||
[0x0136, 0x0136, ["K", "k"]],
|
|
||||||
[0x0139, 0x0142, ["L", "l"]],
|
|
||||||
[0x0143, 0x0148, ["N", "n"]],
|
|
||||||
[0x0149, 0x0149, ["n"]],
|
|
||||||
[0x014c, 0x0151, ["O", "o"]],
|
|
||||||
[0x0152, 0x0153, ["OE", "oe"]],
|
|
||||||
[0x0154, 0x0159, ["R", "r"]],
|
|
||||||
[0x015a, 0x0161, ["S", "s"]],
|
|
||||||
[0x0162, 0x0167, ["T", "t"]],
|
|
||||||
[0x0168, 0x0173, ["U", "u"]],
|
|
||||||
[0x0174, 0x0175, ["W", "w"]],
|
|
||||||
[0x0176, 0x0178, ["Y", "y", "Y"]],
|
|
||||||
[0x0179, 0x017e, ["Z", "z"]],
|
|
||||||
[0x0180, 0x0183, ["b", "B", "B", "b"]],
|
|
||||||
[0x0187, 0x0188, ["C", "c"]],
|
|
||||||
[0x0189, 0x0189, ["D"]],
|
|
||||||
[0x018a, 0x0192, ["D", "D", "d", "F", "f"]],
|
[0x018a, 0x0192, ["D", "D", "d", "F", "f"]],
|
||||||
[0x0193, 0x0194, ["G"]],
|
[0x0193, 0x0194, ["G"]],
|
||||||
[0x0197, 0x019b, ["I", "K", "k", "l", "l"]],
|
[0x0197, 0x019b, ["I", "K", "k", "l", "l"]],
|
||||||
[0x019d, 0x01a1, ["N", "n", "O", "O", "o"]],
|
[0x019d, 0x01a1, ["N", "n", "O", "O", "o"]],
|
||||||
[0x01a4, 0x01a5, ["P", "p"]],
|
[0x01a4, 0x01a5, ["P", "p"]], [0x01ab, 0x01ab, ["t"]],
|
||||||
[0x01ab, 0x01ab, ["t"]],
|
|
||||||
[0x01ac, 0x01b0, ["T", "t", "T", "U", "u"]],
|
[0x01ac, 0x01b0, ["T", "t", "T", "U", "u"]],
|
||||||
[0x01b2, 0x01d2, ["V", "Y", "y", "Z", "z", "D", "L", "N", "A", "a", "I", "i", "O", "o"]],
|
[0x01b2, 0x01d2, ["V", "Y", "y", "Z", "z", "D", "L", "N", "A", "a",
|
||||||
[0x01d3, 0x01dc, ["U", "u"]],
|
"I", "i", "O", "o"]],
|
||||||
[0x01de, 0x01e1, ["A", "a"]],
|
[0x01d3, 0x01dc, ["U", "u"]], [0x01de, 0x01e1, ["A", "a"]],
|
||||||
[0x01e2, 0x01e3, ["AE", "ae"]],
|
[0x01e2, 0x01e3, ["AE", "ae"]],
|
||||||
[0x01e4, 0x01ed, ["G", "g", "G", "g", "K", "k", "O", "o", "O", "o"]],
|
[0x01e4, 0x01ed, ["G", "g", "G", "g", "K", "k", "O", "o", "O", "o"]],
|
||||||
[0x01f0, 0x01f5, ["j", "D", "G", "g"]],
|
[0x01f0, 0x01f5, ["j", "D", "G", "g"]],
|
||||||
[0x01fa, 0x01fb, ["A", "a"]],
|
[0x01fa, 0x01fb, ["A", "a"]], [0x01fc, 0x01fd, ["AE", "ae"]],
|
||||||
[0x01fc, 0x01fd, ["AE", "ae"]],
|
[0x01fe, 0x0217, ["O", "o", "A", "a", "A", "a", "E", "e", "E", "e",
|
||||||
[0x01fe, 0x0217, ["O", "o", "A", "a", "A", "a", "E", "e", "E", "e", "I", "i", "I", "i", "O", "o", "O", "o", "R", "r", "R", "r", "U", "u", "U", "u"]],
|
"I", "i", "I", "i", "O", "o", "O", "o", "R", "r", "R", "r", "U",
|
||||||
|
"u", "U", "u"]],
|
||||||
[0x0253, 0x0257, ["b", "c", "d", "d"]],
|
[0x0253, 0x0257, ["b", "c", "d", "d"]],
|
||||||
[0x0260, 0x0269, ["g", "h", "h", "i", "i"]],
|
[0x0260, 0x0269, ["g", "h", "h", "i", "i"]],
|
||||||
[0x026b, 0x0273, ["l", "l", "l", "l", "m", "n", "n"]],
|
[0x026b, 0x0273, ["l", "l", "l", "l", "m", "n", "n"]],
|
||||||
[0x027c, 0x028b, ["r", "r", "r", "r", "s", "t", "u", "u", "v"]],
|
[0x027c, 0x028b, ["r", "r", "r", "r", "s", "t", "u", "u", "v"]],
|
||||||
[0x0290, 0x0291, ["z"]],
|
[0x0290, 0x0291, ["z"]], [0x029d, 0x02a0, ["j", "q"]],
|
||||||
[0x029d, 0x02a0, ["j", "q"]],
|
|
||||||
[0x1e00, 0x1e09, ["A", "a", "B", "b", "B", "b", "B", "b", "C", "c"]],
|
[0x1e00, 0x1e09, ["A", "a", "B", "b", "B", "b", "B", "b", "C", "c"]],
|
||||||
[0x1e0a, 0x1e13, ["D", "d"]],
|
[0x1e0a, 0x1e13, ["D", "d"]], [0x1e14, 0x1e1d, ["E", "e"]],
|
||||||
[0x1e14, 0x1e1d, ["E", "e"]],
|
[0x1e1e, 0x1e21, ["F", "f", "G", "g"]], [0x1e22, 0x1e2b, ["H", "h"]],
|
||||||
[0x1e1e, 0x1e21, ["F", "f", "G", "g"]],
|
[0x1e2c, 0x1e8f, ["I", "i", "I", "i", "K", "k", "K", "k", "K", "k",
|
||||||
[0x1e22, 0x1e2b, ["H", "h"]],
|
"L", "l", "L", "l", "L", "l", "L", "l", "M", "m", "M", "m", "M",
|
||||||
[0x1e2c, 0x1e8f, ["I", "i", "I", "i", "K", "k", "K", "k", "K", "k", "L", "l", "L", "l", "L", "l", "L", "l", "M", "m", "M", "m", "M", "m", "N", "n", "N", "n", "N", "n", "N", "n", "O", "o", "O", "o", "O", "o", "O", "o", "P", "p", "P", "p", "R", "r", "R", "r", "R", "r", "R", "r", "S", "s", "S", "s", "S", "s", "S", "s", "S", "s", "T", "t", "T", "t", "T", "t", "T", "t", "U", "u", "U", "u", "U", "u", "U", "u", "U", "u", "V", "v", "V", "v", "W", "w", "W", "w", "W", "w", "W", "w", "W", "w", "X", "x", "X", "x", "Y", "y"]],
|
"m", "N", "n", "N", "n", "N", "n", "N", "n", "O", "o", "O", "o",
|
||||||
|
"O", "o", "O", "o", "P", "p", "P", "p", "R", "r", "R", "r", "R",
|
||||||
|
"r", "R", "r", "S", "s", "S", "s", "S", "s", "S", "s", "S", "s",
|
||||||
|
"T", "t", "T", "t", "T", "t", "T", "t", "U", "u", "U", "u", "U",
|
||||||
|
"u", "U", "u", "U", "u", "V", "v", "V", "v", "W", "w", "W", "w",
|
||||||
|
"W", "w", "W", "w", "W", "w", "X", "x", "X", "x", "Y", "y"]],
|
||||||
[0x1e90, 0x1e9a, ["Z", "z", "Z", "z", "Z", "z", "h", "t", "w", "y", "a"]],
|
[0x1e90, 0x1e9a, ["Z", "z", "Z", "z", "Z", "z", "h", "t", "w", "y", "a"]],
|
||||||
[0x1ea0, 0x1eb7, ["A", "a"]],
|
[0x1ea0, 0x1eb7, ["A", "a"]], [0x1eb8, 0x1ec7, ["E", "e"]],
|
||||||
[0x1eb8, 0x1ec7, ["E", "e"]],
|
[0x1ec8, 0x1ecb, ["I", "i"]], [0x1ecc, 0x1ee3, ["O", "o"]],
|
||||||
[0x1ec8, 0x1ecb, ["I", "i"]],
|
[0x1ee4, 0x1ef1, ["U", "u"]], [0x1ef2, 0x1ef9, ["Y", "y"]],
|
||||||
[0x1ecc, 0x1ee3, ["O", "o"]],
|
[0x2071, 0x2071, ["i"]], [0x207f, 0x207f, ["n"]],
|
||||||
[0x1ee4, 0x1ef1, ["U", "u"]],
|
[0x249c, 0x24b5, "a"], [0x24b6, 0x24cf, "A"],
|
||||||
[0x1ef2, 0x1ef9, ["Y", "y"]],
|
|
||||||
[0x2071, 0x2071, ["i"]],
|
|
||||||
[0x207f, 0x207f, ["n"]],
|
|
||||||
[0x249c, 0x24b5, "a"],
|
|
||||||
[0x24b6, 0x24cf, "A"],
|
|
||||||
[0x24d0, 0x24e9, "a"],
|
[0x24d0, 0x24e9, "a"],
|
||||||
[0xfb00, 0xfb06, ["ff", "fi", "fl", "ffi", "ffl", "st", "st"]],
|
[0xfb00, 0xfb06, ["ff", "fi", "fl", "ffi", "ffl", "st", "st"]],
|
||||||
[0xff21, 0xff3a, "A"],
|
[0xff21, 0xff3a, "A"], [0xff41, 0xff5a, "a"],
|
||||||
[0xff41, 0xff5a, "a"],
|
].forEach(function (start, stop, val) {
|
||||||
].map(function (a) {
|
if (typeof a[2] != "string")
|
||||||
if (typeof a[2] == "string")
|
for (i=start; i <= stop; i++)
|
||||||
a[3] = function (chr) String.fromCharCode(this[2].charCodeAt(0) + chr - this[0]);
|
table[String.fromCharCode(i)] = val[(i - start) % val.length];
|
||||||
else
|
else {
|
||||||
a[3] = function (chr) this[2][(chr - this[0]) % this[2].length];
|
let n = val.charCodeAt(0);
|
||||||
return a;
|
for (i=start; i <= stop; i++)
|
||||||
|
table[String.fromCharCode(i)] = String.fromCharCode(n + i - start);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function translate(chr) {
|
delete this.translitTable;
|
||||||
var m, c = chr.charCodeAt(0);
|
return this.translitTable = table;
|
||||||
var n = table.length;
|
},
|
||||||
var i = 0;
|
indexOf: function indexOf(dest, src) {
|
||||||
while (n) {
|
let table = this.translitTable;
|
||||||
m = Math.floor(n / 2);
|
|
||||||
var t = table[i + m];
|
|
||||||
if (c >= t[0] && c <= t[1])
|
|
||||||
return t[3](c);
|
|
||||||
if (c < t[0] || m == 0)
|
|
||||||
n = m;
|
|
||||||
else {
|
|
||||||
i += m;
|
|
||||||
n = n - m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return chr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return function indexOf(dest, src) {
|
|
||||||
var end = dest.length - src.length;
|
var end = dest.length - src.length;
|
||||||
if (src.length == 0)
|
if (src.length == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -988,7 +953,8 @@ const Hints = Module("hints", {
|
|||||||
for (var i = 0; i < end; i++) {
|
for (var i = 0; i < end; i++) {
|
||||||
var j = i;
|
var j = i;
|
||||||
for (var k = 0; k < src.length;) {
|
for (var k = 0; k < src.length;) {
|
||||||
var s = translate(dest[j++]);
|
var s = dest[j++];
|
||||||
|
s = table[s] || s;
|
||||||
for (var l = 0; l < s.length; l++, k++) {
|
for (var l = 0; l < s.length; l++, k++) {
|
||||||
if (s[l] != src[k])
|
if (s[l] != src[k])
|
||||||
continue outer;
|
continue outer;
|
||||||
@@ -998,8 +964,7 @@ const Hints = Module("hints", {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
},
|
||||||
})(),
|
|
||||||
|
|
||||||
Mode: Struct("prompt", "action", "tags")
|
Mode: Struct("prompt", "action", "tags")
|
||||||
}, {
|
}, {
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const History = Module("history", {
|
|||||||
if (current == start && steps < 0 || current == end && steps > 0)
|
if (current == start && steps < 0 || current == end && steps > 0)
|
||||||
dactyl.beep();
|
dactyl.beep();
|
||||||
else {
|
else {
|
||||||
let index = util.Math.constrain(current + steps, start, end);
|
let index = Math.constrain(current + steps, start, end);
|
||||||
window.getWebNavigation().gotoIndex(index);
|
window.getWebNavigation().gotoIndex(index);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -612,7 +612,6 @@ lookup:
|
|||||||
dactyl.echomsg("Cannot source a directory: " + filename.quote(), 0);
|
dactyl.echomsg("Cannot source a directory: " + filename.quote(), 0);
|
||||||
else
|
else
|
||||||
dactyl.echomsg("could not source: " + filename.quote(), 1);
|
dactyl.echomsg("could not source: " + filename.quote(), 1);
|
||||||
|
|
||||||
dactyl.echoerr("E484: Can't open file " + filename);
|
dactyl.echoerr("E484: Can't open file " + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,7 +620,6 @@ lookup:
|
|||||||
|
|
||||||
dactyl.echomsg("sourcing " + filename.quote(), 2);
|
dactyl.echomsg("sourcing " + filename.quote(), 2);
|
||||||
|
|
||||||
let str = file.read();
|
|
||||||
let uri = services.get("io").newFileURI(file);
|
let uri = services.get("io").newFileURI(file);
|
||||||
|
|
||||||
// handle pure JavaScript files specially
|
// handle pure JavaScript files specially
|
||||||
@@ -643,6 +641,7 @@ lookup:
|
|||||||
else {
|
else {
|
||||||
let heredoc = "";
|
let heredoc = "";
|
||||||
let heredocEnd = null; // the string which ends the heredoc
|
let heredocEnd = null; // the string which ends the heredoc
|
||||||
|
let str = file.read();
|
||||||
let lines = str.split(/\r\n|[\r\n]/);
|
let lines = str.split(/\r\n|[\r\n]/);
|
||||||
|
|
||||||
function execute(args) { command.execute(args, special, count, { setFrom: file }); }
|
function execute(args) { command.execute(args, special, count, { setFrom: file }); }
|
||||||
@@ -968,7 +967,8 @@ lookup:
|
|||||||
let output = io.system(arg);
|
let output = io.system(arg);
|
||||||
|
|
||||||
commandline.command = "!" + arg;
|
commandline.command = "!" + arg;
|
||||||
commandline.echo(template.commandOutput(<span highlight="CmdOutput">{output}</span>));
|
commandline.echo(template.commandOutput(commandline.command,
|
||||||
|
<span highlight="CmdOutput">{output}</span>));
|
||||||
|
|
||||||
autocommands.trigger("ShellCmdPost", {});
|
autocommands.trigger("ShellCmdPost", {});
|
||||||
}, {
|
}, {
|
||||||
@@ -979,12 +979,6 @@ lookup:
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
completion: function () {
|
completion: function () {
|
||||||
JavaScript.setCompleter([this.File, File.expandPath],
|
|
||||||
[function (context, obj, args) {
|
|
||||||
context.quote[2] = "";
|
|
||||||
completion.file(context, true);
|
|
||||||
}]);
|
|
||||||
|
|
||||||
completion.charset = function (context) {
|
completion.charset = function (context) {
|
||||||
context.anchored = false;
|
context.anchored = false;
|
||||||
context.generate = function () {
|
context.generate = function () {
|
||||||
@@ -1070,6 +1064,14 @@ lookup:
|
|||||||
completion.file(context, full);
|
completion.file(context, full);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
javascript: function () {
|
||||||
|
JavaScript.setCompleter([this.File, File.expandPath],
|
||||||
|
[function (context, obj, args) {
|
||||||
|
context.quote[2] = "";
|
||||||
|
completion.file(context, true);
|
||||||
|
}]);
|
||||||
|
|
||||||
|
},
|
||||||
options: function () {
|
options: function () {
|
||||||
var shell, shellcmdflag;
|
var shell, shellcmdflag;
|
||||||
if (dactyl.has("Win32")) {
|
if (dactyl.has("Win32")) {
|
||||||
|
|||||||
@@ -127,6 +127,13 @@ const Mappings = Module("mappings", {
|
|||||||
init: function () {
|
init: function () {
|
||||||
this._main = []; // default mappings
|
this._main = []; // default mappings
|
||||||
this._user = []; // user created mappings
|
this._user = []; // user created mappings
|
||||||
|
|
||||||
|
dactyl.registerObserver("mode-add", function (mode) {
|
||||||
|
if (!(mode.mask in this._user || mode.mask in this._main)) {
|
||||||
|
this._main[mode.mask] = [];
|
||||||
|
this._user[mode.mask] = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_addMap: function (map) {
|
_addMap: function (map) {
|
||||||
@@ -189,13 +196,6 @@ const Mappings = Module("mappings", {
|
|||||||
*/
|
*/
|
||||||
getUserIterator: function (mode) this._mappingsIterator(mode, this._user),
|
getUserIterator: function (mode) this._mappingsIterator(mode, this._user),
|
||||||
|
|
||||||
addMode: function (mode) {
|
|
||||||
if (!(mode in this._user || mode in this._main)) {
|
|
||||||
this._main[mode] = [];
|
|
||||||
this._user[mode] = [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new default key mapping.
|
* Adds a new default key mapping.
|
||||||
*
|
*
|
||||||
@@ -477,6 +477,17 @@ const Mappings = Module("mappings", {
|
|||||||
[mode.disp.toLowerCase()]);
|
[mode.disp.toLowerCase()]);
|
||||||
},
|
},
|
||||||
completion: function () {
|
completion: function () {
|
||||||
|
completion.userMapping = function userMapping(context, args, modes) {
|
||||||
|
// FIXME: have we decided on a 'standard' way to handle this clash? --djk
|
||||||
|
modes = modes || [modules.modes.NORMAL];
|
||||||
|
|
||||||
|
if (args.completeArg == 0) {
|
||||||
|
let maps = [[m.names[0], ""] for (m in mappings.getUserIterator(modes))];
|
||||||
|
context.completions = maps;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
javascript: function () {
|
||||||
JavaScript.setCompleter(this.get,
|
JavaScript.setCompleter(this.get,
|
||||||
[
|
[
|
||||||
null,
|
null,
|
||||||
@@ -489,16 +500,6 @@ const Mappings = Module("mappings", {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
completion.userMapping = function userMapping(context, args, modes) {
|
|
||||||
// FIXME: have we decided on a 'standard' way to handle this clash? --djk
|
|
||||||
modes = modes || [modules.modes.NORMAL];
|
|
||||||
|
|
||||||
if (args.completeArg == 0) {
|
|
||||||
let maps = [[m.names[0], ""] for (m in mappings.getUserIterator(modes))];
|
|
||||||
context.completions = maps;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
modes: function () {
|
modes: function () {
|
||||||
for (let mode in modes) {
|
for (let mode in modes) {
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ const Modes = Module("modes", {
|
|||||||
options = extended;
|
options = extended;
|
||||||
extended = false;
|
extended = false;
|
||||||
}
|
}
|
||||||
this._modeMap[name] = this._modeMap[this[name]] = util.extend({
|
let mode = util.extend({
|
||||||
extended: extended,
|
extended: extended,
|
||||||
count: true,
|
count: true,
|
||||||
input: false,
|
input: false,
|
||||||
@@ -147,11 +147,12 @@ const Modes = Module("modes", {
|
|||||||
name: name,
|
name: name,
|
||||||
disp: disp
|
disp: disp
|
||||||
}, options);
|
}, options);
|
||||||
this._modeMap[name].display = this._modeMap[name].display || function () disp;
|
mode.display = mode.display || function () disp;
|
||||||
|
this._modeMap[name] = mode;
|
||||||
|
this._modeMap[this[name]] = mode;
|
||||||
if (!extended)
|
if (!extended)
|
||||||
this._mainModes.push(this[name]);
|
this._mainModes.push(this[name]);
|
||||||
if ("mappings" in modules)
|
dactyl.triggerObserver("mode-add", mode);
|
||||||
mappings.addMode(this[name]);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getMode: function (name) this._modeMap[name],
|
getMode: function (name) this._modeMap[name],
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ window.addEventListener("load", function () {
|
|||||||
set.add(seen, module.name);
|
set.add(seen, module.name);
|
||||||
|
|
||||||
for (let dep in values(module.requires))
|
for (let dep in values(module.requires))
|
||||||
load(Module.constructors[dep], module.name);
|
load(Module.constructors[dep], module.name, dep);
|
||||||
|
|
||||||
dump("Load" + (isstring(prereq) ? " " + prereq + " dependency: " : ": ") + module.name);
|
dump("Load" + (isstring(prereq) ? " " + prereq + " dependency: " : ": ") + module.name);
|
||||||
modules[module.name] = module();
|
modules[module.name] = module();
|
||||||
|
|||||||
@@ -1269,10 +1269,6 @@ const Options = Module("options", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
completion: function () {
|
completion: function () {
|
||||||
JavaScript.setCompleter(this.get, [function () ([o.name, o.description] for (o in options))]);
|
|
||||||
JavaScript.setCompleter([this.getPref, this.safeSetPref, this.setPref, this.resetPref, this.invertPref],
|
|
||||||
[function () options.allPrefs().map(function (pref) [pref, ""])]);
|
|
||||||
|
|
||||||
completion.option = function option(context, scope) {
|
completion.option = function option(context, scope) {
|
||||||
context.title = ["Option"];
|
context.title = ["Option"];
|
||||||
context.keys = { text: "names", description: "description" };
|
context.keys = { text: "names", description: "description" };
|
||||||
@@ -1350,6 +1346,11 @@ const Options = Module("options", {
|
|||||||
context.keys = { text: function (item) item, description: function (item) options.getPref(item) };
|
context.keys = { text: function (item) item, description: function (item) options.getPref(item) };
|
||||||
context.completions = options.allPrefs();
|
context.completions = options.allPrefs();
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
javascript: function () {
|
||||||
|
JavaScript.setCompleter(this.get, [function () ([o.name, o.description] for (o in options))]);
|
||||||
|
JavaScript.setCompleter([this.getPref, this.safeSetPref, this.setPref, this.resetPref, this.invertPref],
|
||||||
|
[function () options.allPrefs().map(function (pref) [pref, ""])]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -29,16 +29,19 @@ const Services = Module("services", {
|
|||||||
this.add("environment", "@mozilla.org/process/environment;1", Ci.nsIEnvironment);
|
this.add("environment", "@mozilla.org/process/environment;1", Ci.nsIEnvironment);
|
||||||
this.add("extensionManager", "@mozilla.org/extensions/manager;1", Ci.nsIExtensionManager);
|
this.add("extensionManager", "@mozilla.org/extensions/manager;1", Ci.nsIExtensionManager);
|
||||||
this.add("favicon", "@mozilla.org/browser/favicon-service;1", Ci.nsIFaviconService);
|
this.add("favicon", "@mozilla.org/browser/favicon-service;1", Ci.nsIFaviconService);
|
||||||
this.add("history", "@mozilla.org/browser/global-history;2", [Ci.nsIGlobalHistory3, Ci.nsINavHistoryService, Ci.nsIBrowserHistory]);
|
this.add("history", "@mozilla.org/browser/global-history;2", [Ci.nsIBrowserHistory, Ci.nsIGlobalHistory3, Ci.nsINavHistoryService]);
|
||||||
this.add("io", "@mozilla.org/network/io-service;1", Ci.nsIIOService);
|
this.add("io", "@mozilla.org/network/io-service;1", Ci.nsIIOService);
|
||||||
this.add("json", "@mozilla.org/dom/json;1", Ci.nsIJSON, "createInstance");
|
this.add("json", "@mozilla.org/dom/json;1", Ci.nsIJSON, "createInstance");
|
||||||
this.add("livemark", "@mozilla.org/browser/livemark-service;2", Ci.nsILivemarkService);
|
this.add("livemark", "@mozilla.org/browser/livemark-service;2", Ci.nsILivemarkService);
|
||||||
this.add("observer", "@mozilla.org/observer-service;1", Ci.nsIObserverService);
|
this.add("observer", "@mozilla.org/observer-service;1", Ci.nsIObserverService);
|
||||||
this.add("pref", "@mozilla.org/preferences-service;1", [Ci.nsIPrefService, Ci.nsIPrefBranch, Ci.nsIPrefBranch2]);
|
this.add("pref", "@mozilla.org/preferences-service;1", [Ci.nsIPrefBranch, Ci.nsIPrefBranch2, Ci.nsIPrefService]);
|
||||||
this.add("profile", "@mozilla.org/toolkit/profile-service;1", Ci.nsIToolkitProfileService);
|
this.add("profile", "@mozilla.org/toolkit/profile-service;1", Ci.nsIToolkitProfileService);
|
||||||
|
this.add("runtime", "@mozilla.org/xre/runtime;1", [Ci.nsIXULAppInfo, Ci.nsIXULRuntime]);
|
||||||
this.add("rdf", "@mozilla.org/rdf/rdf-service;1", Ci.nsIRDFService);
|
this.add("rdf", "@mozilla.org/rdf/rdf-service;1", Ci.nsIRDFService);
|
||||||
this.add("sessionStore", "@mozilla.org/browser/sessionstore;1", Ci.nsISessionStore);
|
this.add("sessionStore", "@mozilla.org/browser/sessionstore;1", Ci.nsISessionStore);
|
||||||
|
this.add("stylesheet", "@mozilla.org/content/style-sheet-service;1", Ci.nsIStyleSheetService);
|
||||||
this.add("subscriptLoader", "@mozilla.org/moz/jssubscript-loader;1", Ci.mozIJSSubScriptLoader);
|
this.add("subscriptLoader", "@mozilla.org/moz/jssubscript-loader;1", Ci.mozIJSSubScriptLoader);
|
||||||
|
this.add("tagging", "@mozilla.org/browser/tagging-service;1", Ci.nsITaggingService);
|
||||||
this.add("threadManager", "@mozilla.org/thread-manager;1", Ci.nsIThreadManager);
|
this.add("threadManager", "@mozilla.org/thread-manager;1", Ci.nsIThreadManager);
|
||||||
this.add("windowMediator", "@mozilla.org/appshell/window-mediator;1", Ci.nsIWindowMediator);
|
this.add("windowMediator", "@mozilla.org/appshell/window-mediator;1", Ci.nsIWindowMediator);
|
||||||
this.add("windowWatcher", "@mozilla.org/embedcomp/window-watcher;1", Ci.nsIWindowWatcher);
|
this.add("windowWatcher", "@mozilla.org/embedcomp/window-watcher;1", Ci.nsIWindowWatcher);
|
||||||
@@ -48,6 +51,8 @@ const Services = Module("services", {
|
|||||||
this.addClass("file:", "@mozilla.org/network/protocol;1?name=file", Ci.nsIFileProtocolHandler);
|
this.addClass("file:", "@mozilla.org/network/protocol;1?name=file", Ci.nsIFileProtocolHandler);
|
||||||
this.addClass("find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind);
|
this.addClass("find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind);
|
||||||
this.addClass("process", "@mozilla.org/process/util;1", Ci.nsIProcess);
|
this.addClass("process", "@mozilla.org/process/util;1", Ci.nsIProcess);
|
||||||
|
this.addClass("timer", "@mozilla.org/timer;1", Ci.nsITimer);
|
||||||
|
this.addClass("xmlhttp", "@mozilla.org/xmlextras/xmlhttprequest;1", Ci.nsIXMLHttpRequest);
|
||||||
this.addClass("zipWriter", "@mozilla.org/zipwriter;1", Ci.nsIZipWriter);
|
this.addClass("zipWriter", "@mozilla.org/zipwriter;1", Ci.nsIZipWriter);
|
||||||
|
|
||||||
if (!this.get("extensionManager"))
|
if (!this.get("extensionManager"))
|
||||||
@@ -81,7 +86,11 @@ const Services = Module("services", {
|
|||||||
* the service.
|
* the service.
|
||||||
*/
|
*/
|
||||||
add: function (name, class_, ifaces, meth) {
|
add: function (name, class_, ifaces, meth) {
|
||||||
return this.services[name] = this._create(class_, ifaces, meth);
|
const self = this;
|
||||||
|
this.services.__defineGetter__(name, function () {
|
||||||
|
delete this[name];
|
||||||
|
return this[name] = self._create(class_, ifaces, meth);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,11 +120,9 @@ const Services = Module("services", {
|
|||||||
*/
|
*/
|
||||||
create: function (name) this.classes[name]()
|
create: function (name) this.classes[name]()
|
||||||
}, {
|
}, {
|
||||||
}, {
|
javascript: function (dactyl, modules) {
|
||||||
completion: function () {
|
|
||||||
JavaScript.setCompleter(this.get, [function () services.services]);
|
JavaScript.setCompleter(this.get, [function () services.services]);
|
||||||
JavaScript.setCompleter(this.create, [function () [[c, ""] for (c in services.classes)]]);
|
JavaScript.setCompleter(this.create, [function () [[c, ""] for (c in services.classes)]]);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -819,7 +819,7 @@ const Tabs = Module("tabs", {
|
|||||||
|
|
||||||
let last = browser.mTabs.length - 1;
|
let last = browser.mTabs.length - 1;
|
||||||
|
|
||||||
browser.moveTabTo(dummy, util.Math.constrain(tabIndex || last, 0, last));
|
browser.moveTabTo(dummy, Math.constrain(tabIndex || last, 0, last));
|
||||||
browser.selectedTab = dummy; // required
|
browser.selectedTab = dummy; // required
|
||||||
browser.swapBrowsersAndCloseOther(dummy, config.tabbrowser.mCurrentTab);
|
browser.swapBrowsersAndCloseOther(dummy, config.tabbrowser.mCurrentTab);
|
||||||
}, {
|
}, {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const Template = Module("template", {
|
|||||||
|
|
||||||
map: function map(iter, func, sep, interruptable) {
|
map: function map(iter, func, sep, interruptable) {
|
||||||
if (iter.length) // FIXME: Kludge?
|
if (iter.length) // FIXME: Kludge?
|
||||||
iter = util.Array.itervalues(iter);
|
iter = array.itervalues(iter);
|
||||||
let ret = <></>;
|
let ret = <></>;
|
||||||
let n = 0;
|
let n = 0;
|
||||||
for each (let i in Iterator(iter)) {
|
for each (let i in Iterator(iter)) {
|
||||||
@@ -22,7 +22,7 @@ const Template = Module("template", {
|
|||||||
if (sep && n++)
|
if (sep && n++)
|
||||||
ret += sep;
|
ret += sep;
|
||||||
if (interruptable && n % interruptable == 0)
|
if (interruptable && n % interruptable == 0)
|
||||||
dactyl.threadYield(true, true);
|
util.threadYield(true, true);
|
||||||
ret += val;
|
ret += val;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -93,7 +93,8 @@ const Template = Module("template", {
|
|||||||
<table width="100%" style="height: 100%">
|
<table width="100%" style="height: 100%">
|
||||||
<tr>
|
<tr>
|
||||||
{ template.map(util.range(0, 100), function (i)
|
{ template.map(util.range(0, 100), function (i)
|
||||||
<td highlight={left} style={"opacity: " + (1 - i / 100)}/>) }
|
<td highlight={left} style={"opacity: " + (1 - i / 100)}
|
||||||
|
/>) }
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>,
|
</div>,
|
||||||
@@ -118,6 +119,7 @@ const Template = Module("template", {
|
|||||||
// Using /foo*(:?)/ instead.
|
// Using /foo*(:?)/ instead.
|
||||||
if (processStrings)
|
if (processStrings)
|
||||||
return <span highlight="Function">{str.replace(/\{(.|\n)*(?:)/g, "{ ... }")}</span>;
|
return <span highlight="Function">{str.replace(/\{(.|\n)*(?:)/g, "{ ... }")}</span>;
|
||||||
|
<>}</>; /* Vim */
|
||||||
return <>{arg}</>;
|
return <>{arg}</>;
|
||||||
case "undefined":
|
case "undefined":
|
||||||
return <span highlight="Null">{arg}</span>;
|
return <span highlight="Null">{arg}</span>;
|
||||||
@@ -190,8 +192,8 @@ const Template = Module("template", {
|
|||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
|
|
||||||
commandOutput: function generic(xml) {
|
commandOutput: function generic(command, xml) {
|
||||||
return <>:{commandline.command}<br/>{xml}</>;
|
return <>:{command}<br/>{xml}</>;
|
||||||
},
|
},
|
||||||
|
|
||||||
genericTable: function genericTable(items, format) {
|
genericTable: function genericTable(items, format) {
|
||||||
|
|||||||
@@ -15,7 +15,16 @@ default xml namespace = XHTML;
|
|||||||
|
|
||||||
const Util = Module("util", {
|
const Util = Module("util", {
|
||||||
init: function () {
|
init: function () {
|
||||||
this.Array = Util.Array;
|
this.Array = array;
|
||||||
|
},
|
||||||
|
|
||||||
|
get activeWindow() services.get("windowWatcher").activeWindow,
|
||||||
|
callInMainThread: function (callback, self) {
|
||||||
|
let mainThread = services.get("threadManager").mainThread;
|
||||||
|
if (!services.get("threadManager").isMainThread)
|
||||||
|
mainThread.dispatch({ run: callback.call(self) }, mainThread.DISPATCH_NORMAL);
|
||||||
|
else
|
||||||
|
callback.call(self);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,7 +34,7 @@ const Util = Module("util", {
|
|||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
cloneObject: function cloneObject(obj) {
|
cloneObject: function cloneObject(obj) {
|
||||||
if (obj instanceof Array)
|
if (isarray(obj))
|
||||||
return obj.slice();
|
return obj.slice();
|
||||||
let newObj = {};
|
let newObj = {};
|
||||||
for (let [k, v] in Iterator(obj))
|
for (let [k, v] in Iterator(obj))
|
||||||
@@ -62,7 +71,7 @@ const Util = Module("util", {
|
|||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
computedStyle: function computedStyle(node) {
|
computedStyle: function computedStyle(node) {
|
||||||
while (node instanceof Text && node.parentNode)
|
while (node instanceof Ci.nsIDOMText && node.parentNode)
|
||||||
node = node.parentNode;
|
node = node.parentNode;
|
||||||
return node.ownerDocument.defaultView.getComputedStyle(node, null);
|
return node.ownerDocument.defaultView.getComputedStyle(node, null);
|
||||||
},
|
},
|
||||||
@@ -151,13 +160,7 @@ const Util = Module("util", {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
escapeHTML: function escapeHTML(str) {
|
escapeHTML: function escapeHTML(str) {
|
||||||
// XXX: the following code is _much_ slower than a simple .replace()
|
return str.replace(/&/g, "&").replace(/</g, "<");
|
||||||
// :history display went down from 2 to 1 second after changing
|
|
||||||
//
|
|
||||||
// var e = window.content.document.createElement("div");
|
|
||||||
// e.appendChild(window.content.document.createTextNode(str));
|
|
||||||
// return e.innerHTML;
|
|
||||||
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -185,6 +188,48 @@ const Util = Module("util", {
|
|||||||
return delimiter + str.replace(/([\\'"])/g, "\\$1").replace("\n", "\\n", "g").replace("\t", "\\t", "g") + delimiter;
|
return delimiter + str.replace(/([\\'"])/g, "\\$1").replace("\n", "\\n", "g").replace("\t", "\\t", "g") + delimiter;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates an XPath expression in the current or provided
|
||||||
|
* document. It provides the xhtml, xhtml2 and dactyl XML
|
||||||
|
* namespaces. The result may be used as an iterator.
|
||||||
|
*
|
||||||
|
* @param {string} expression The XPath expression to evaluate.
|
||||||
|
* @param {Document} doc The document to evaluate the expression in.
|
||||||
|
* @default The current document.
|
||||||
|
* @param {Node} elem The context element.
|
||||||
|
* @default <b>doc</b>
|
||||||
|
* @param {boolean} asIterator Whether to return the results as an
|
||||||
|
* XPath iterator.
|
||||||
|
*/
|
||||||
|
evaluateXPath: function (expression, doc, elem, asIterator) {
|
||||||
|
if (!doc)
|
||||||
|
doc = content.document;
|
||||||
|
if (!elem)
|
||||||
|
elem = doc;
|
||||||
|
if (isarray(expression))
|
||||||
|
expression = util.makeXPath(expression);
|
||||||
|
|
||||||
|
let result = doc.evaluate(expression, elem,
|
||||||
|
function lookupNamespaceURI(prefix) {
|
||||||
|
return {
|
||||||
|
xul: XUL.uri,
|
||||||
|
xhtml: XHTML.uri,
|
||||||
|
xhtml2: "http://www.w3.org/2002/06/xhtml2",
|
||||||
|
dactyl: NS.uri
|
||||||
|
}[prefix] || null;
|
||||||
|
},
|
||||||
|
asIterator ? Ci.nsIDOMXPathResult.ORDERED_NODE_ITERATOR_TYPE : Ci.nsIDOMXPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
__proto__: result,
|
||||||
|
__iterator__: asIterator
|
||||||
|
? function () { let elem; while ((elem = this.iterateNext())) yield elem; }
|
||||||
|
: function () { for (let i = 0; i < this.snapshotLength; i++) yield this.snapshotItem(i); }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
extend: function extend(dest) {
|
extend: function extend(dest) {
|
||||||
Array.slice(arguments, 1).filter(util.identity).forEach(function (src) {
|
Array.slice(arguments, 1).filter(util.identity).forEach(function (src) {
|
||||||
for (let [k, v] in Iterator(src)) {
|
for (let [k, v] in Iterator(src)) {
|
||||||
@@ -201,38 +246,6 @@ const Util = Module("util", {
|
|||||||
return dest;
|
return dest;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an XPath union expression constructed from the specified node
|
|
||||||
* tests. An expression is built with node tests for both the null and
|
|
||||||
* XHTML namespaces. See {@link Buffer#evaluateXPath}.
|
|
||||||
*
|
|
||||||
* @param nodes {Array(string)}
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
makeXPath: function makeXPath(nodes) {
|
|
||||||
return util.Array(nodes).map(util.debrace).flatten()
|
|
||||||
.map(function (node) [node, "xhtml:" + node]).flatten()
|
|
||||||
.map(function (node) "//" + node).join(" | ");
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Memoize the lookup of a property in an object.
|
|
||||||
*
|
|
||||||
* @param {object} obj The object to alter.
|
|
||||||
* @param {string} key The name of the property to memoize.
|
|
||||||
* @param {function} getter A function of zero to two arguments which
|
|
||||||
* will return the property's value. <b>obj</b> is
|
|
||||||
* passed as the first argument, <b>key</b> as the
|
|
||||||
* second.
|
|
||||||
*/
|
|
||||||
memoize: function memoize(obj, key, getter) {
|
|
||||||
obj.__defineGetter__(key, function () {
|
|
||||||
delete obj[key];
|
|
||||||
obj[key] = getter(obj, key);
|
|
||||||
return obj[key];
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the selection controller for the given window.
|
* Returns the selection controller for the given window.
|
||||||
*
|
*
|
||||||
@@ -247,37 +260,6 @@ const Util = Module("util", {
|
|||||||
.getInterface(Ci.nsISelectionDisplay)
|
.getInterface(Ci.nsISelectionDisplay)
|
||||||
.QueryInterface(Ci.nsISelectionController),
|
.QueryInterface(Ci.nsISelectionController),
|
||||||
|
|
||||||
/**
|
|
||||||
* Split a string on literal occurrences of a marker.
|
|
||||||
*
|
|
||||||
* Specifically this ignores occurrences preceded by a backslash, or
|
|
||||||
* contained within 'single' or "double" quotes.
|
|
||||||
*
|
|
||||||
* It assumes backslash escaping on strings, and will thus not count quotes
|
|
||||||
* that are preceded by a backslash or within other quotes as starting or
|
|
||||||
* ending quoted sections of the string.
|
|
||||||
*
|
|
||||||
* @param {string} str
|
|
||||||
* @param {RegExp} marker
|
|
||||||
*/
|
|
||||||
splitLiteral: function splitLiteral(str, marker) {
|
|
||||||
let results = [];
|
|
||||||
let resep = RegExp(/^(([^\\'"]|\\.|'([^\\']|\\.)*'|"([^\\"]|\\.)*")*?)/.source + marker.source);
|
|
||||||
let cont = true;
|
|
||||||
|
|
||||||
while (cont) {
|
|
||||||
cont = false;
|
|
||||||
str = str.replace(resep, function (match, before) {
|
|
||||||
results.push(before);
|
|
||||||
cont = true;
|
|
||||||
return "";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
results.push(str);
|
|
||||||
return results;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts <b>bytes</b> to a pretty printed data size string.
|
* Converts <b>bytes</b> to a pretty printed data size string.
|
||||||
*
|
*
|
||||||
@@ -319,99 +301,6 @@ const Util = Module("util", {
|
|||||||
return strNum[0] + " " + unitVal[unitIndex];
|
return strNum[0] + " " + unitVal[unitIndex];
|
||||||
},
|
},
|
||||||
|
|
||||||
exportHelp: function (path) {
|
|
||||||
const FILE = io.File(path);
|
|
||||||
const PATH = FILE.leafName.replace(/\..*/, "") + "/";
|
|
||||||
const TIME = Date.now();
|
|
||||||
|
|
||||||
dactyl.initHelp();
|
|
||||||
let zip = services.create("zipWriter");
|
|
||||||
zip.open(FILE, File.MODE_CREATE | File.MODE_WRONLY | File.MODE_TRUNCATE);
|
|
||||||
function addURIEntry(file, uri)
|
|
||||||
zip.addEntryChannel(PATH + file, TIME, 9,
|
|
||||||
services.get("io").newChannel(uri, null, null), false);
|
|
||||||
function addDataEntry(file, data) // Inideal to an extreme.
|
|
||||||
addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data));
|
|
||||||
|
|
||||||
let empty = util.Array.toObject(
|
|
||||||
"area base basefont br col frame hr img input isindex link meta param"
|
|
||||||
.split(" ").map(Array.concat));
|
|
||||||
|
|
||||||
let chrome = {};
|
|
||||||
for (let [file,] in Iterator(services.get("dactyl:").FILE_MAP)) {
|
|
||||||
dactyl.open("dactyl://help/" + file);
|
|
||||||
events.waitForPageLoad();
|
|
||||||
let data = [
|
|
||||||
'<?xml version="1.0" encoding="UTF-8"?>\n',
|
|
||||||
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n',
|
|
||||||
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
|
|
||||||
];
|
|
||||||
function fix(node) {
|
|
||||||
switch(node.nodeType) {
|
|
||||||
case Node.ELEMENT_NODE:
|
|
||||||
if (node instanceof HTMLScriptElement)
|
|
||||||
return;
|
|
||||||
|
|
||||||
data.push("<"); data.push(node.localName);
|
|
||||||
if (node instanceof HTMLHtmlElement)
|
|
||||||
data.push(" xmlns=" + XHTML.uri.quote());
|
|
||||||
|
|
||||||
for (let { name: name, value: value } in util.Array.itervalues(node.attributes)) {
|
|
||||||
if (name == "dactyl:highlight") {
|
|
||||||
name = "class";
|
|
||||||
value = "hl-" + value;
|
|
||||||
}
|
|
||||||
if (name == "href") {
|
|
||||||
if (value.indexOf("dactyl://help-tag/") == 0)
|
|
||||||
value = services.get("io").newChannel(value, null, null).originalURI.path.substr(1);
|
|
||||||
if (!/[#\/]/.test(value))
|
|
||||||
value += ".xhtml";
|
|
||||||
}
|
|
||||||
if (name == "src" && value.indexOf(":") > 0) {
|
|
||||||
chrome[value] = value.replace(/.*\//, "");;
|
|
||||||
value = value.replace(/.*\//, "");
|
|
||||||
}
|
|
||||||
data.push(" ");
|
|
||||||
data.push(name);
|
|
||||||
data.push('="');
|
|
||||||
data.push(<>{value}</>.toXMLString());
|
|
||||||
data.push('"')
|
|
||||||
}
|
|
||||||
if (node.localName in empty)
|
|
||||||
data.push(" />");
|
|
||||||
else {
|
|
||||||
data.push(">");
|
|
||||||
if (node instanceof HTMLHeadElement)
|
|
||||||
data.push(<link rel="stylesheet" type="text/css" href="help.css"/>.toXMLString());
|
|
||||||
Array.map(node.childNodes, arguments.callee);
|
|
||||||
data.push("</"); data.push(node.localName); data.push(">");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Node.TEXT_NODE:
|
|
||||||
data.push(<>{node.textContent}</>.toXMLString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fix(content.document.documentElement);
|
|
||||||
addDataEntry(file + ".xhtml", data.join(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = [h.selector.replace(/^\[.*?=(.*?)\]/, ".hl-$1").replace(/html\|/, "") +
|
|
||||||
"\t{" + h.value + "}"
|
|
||||||
for (h in highlight) if (/^Help|^Logo/.test(h.class))];
|
|
||||||
|
|
||||||
data = data.join("\n");
|
|
||||||
addDataEntry("help.css", data.replace(/chrome:[^ ")]+\//g, ""));
|
|
||||||
|
|
||||||
let re = /(chrome:[^ ");]+\/)([^ ");]+)/g;
|
|
||||||
while ((m = re.exec(data)))
|
|
||||||
chrome[m[0]] = m[2];
|
|
||||||
|
|
||||||
for (let [uri, leaf] in Iterator(chrome))
|
|
||||||
addURIEntry(leaf, uri);
|
|
||||||
|
|
||||||
zip.close();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a synchronous or asynchronous HTTP request to <b>url</b> and
|
* Sends a synchronous or asynchronous HTTP request to <b>url</b> and
|
||||||
* returns the XMLHttpRequest object. If <b>callback</b> is specified the
|
* returns the XMLHttpRequest object. If <b>callback</b> is specified the
|
||||||
@@ -424,7 +313,7 @@ const Util = Module("util", {
|
|||||||
*/
|
*/
|
||||||
httpGet: function httpGet(url, callback) {
|
httpGet: function httpGet(url, callback) {
|
||||||
try {
|
try {
|
||||||
let xmlhttp = new XMLHttpRequest();
|
let xmlhttp = services.create("xmlhttp");
|
||||||
xmlhttp.mozBackgroundRequest = true;
|
xmlhttp.mozBackgroundRequest = true;
|
||||||
if (callback) {
|
if (callback) {
|
||||||
xmlhttp.onreadystatechange = function () {
|
xmlhttp.onreadystatechange = function () {
|
||||||
@@ -437,53 +326,11 @@ const Util = Module("util", {
|
|||||||
return xmlhttp;
|
return xmlhttp;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
dactyl.log("Error opening " + url + ": " + e, 1);
|
dactyl.log("Error opening " + String.quote(url) + ": " + e, 1);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates an XPath expression in the current or provided
|
|
||||||
* document. It provides the xhtml, xhtml2 and dactyl XML
|
|
||||||
* namespaces. The result may be used as an iterator.
|
|
||||||
*
|
|
||||||
* @param {string} expression The XPath expression to evaluate.
|
|
||||||
* @param {Document} doc The document to evaluate the expression in.
|
|
||||||
* @default The current document.
|
|
||||||
* @param {Node} elem The context element.
|
|
||||||
* @default <b>doc</b>
|
|
||||||
* @param {boolean} asIterator Whether to return the results as an
|
|
||||||
* XPath iterator.
|
|
||||||
*/
|
|
||||||
evaluateXPath: function (expression, doc, elem, asIterator) {
|
|
||||||
if (!doc)
|
|
||||||
doc = window.content.document;
|
|
||||||
if (!elem)
|
|
||||||
elem = doc;
|
|
||||||
if (isarray(expression))
|
|
||||||
expression = util.makeXPath(expression);
|
|
||||||
|
|
||||||
let result = doc.evaluate(expression, elem,
|
|
||||||
function lookupNamespaceURI(prefix) {
|
|
||||||
return {
|
|
||||||
xul: XUL.uri,
|
|
||||||
xhtml: XHTML.uri,
|
|
||||||
xhtml2: "http://www.w3.org/2002/06/xhtml2",
|
|
||||||
dactyl: NS.uri
|
|
||||||
}[prefix] || null;
|
|
||||||
},
|
|
||||||
asIterator ? XPathResult.ORDERED_NODE_ITERATOR_TYPE : XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
__proto__: result,
|
|
||||||
__iterator__: asIterator
|
|
||||||
? function () { let elem; while ((elem = this.iterateNext())) yield elem; }
|
|
||||||
: function () { for (let i = 0; i < this.snapshotLength; i++) yield this.snapshotItem(i); }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The identity function.
|
* The identity function.
|
||||||
*
|
*
|
||||||
@@ -508,6 +355,20 @@ const Util = Module("util", {
|
|||||||
bottom: Math.min(r1.bottom, r2.bottom)
|
bottom: Math.min(r1.bottom, r2.bottom)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an XPath union expression constructed from the specified node
|
||||||
|
* tests. An expression is built with node tests for both the null and
|
||||||
|
* XHTML namespaces. See {@link Buffer#evaluateXPath}.
|
||||||
|
*
|
||||||
|
* @param nodes {Array(string)}
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
makeXPath: function makeXPath(nodes) {
|
||||||
|
return util.Array(nodes).map(util.debrace).flatten()
|
||||||
|
.map(function (node) [node, "xhtml:" + node]).flatten()
|
||||||
|
.map(function (node) "//" + node).join(" | ");
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the array that results from applying <b>func</b> to each
|
* Returns the array that results from applying <b>func</b> to each
|
||||||
* property of <b>obj</b>.
|
* property of <b>obj</b>.
|
||||||
@@ -524,21 +385,16 @@ const Util = Module("util", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Math utility methods.
|
* Memoize the lookup of a property in an object.
|
||||||
* @singleton
|
|
||||||
*/
|
|
||||||
Math: {
|
|
||||||
/**
|
|
||||||
* Returns the specified <b>value</b> constrained to the range <b>min</b> -
|
|
||||||
* <b>max</b>.
|
|
||||||
*
|
*
|
||||||
* @param {number} value The value to constrain.
|
* @param {object} obj The object to alter.
|
||||||
* @param {number} min The minimum constraint.
|
* @param {string} key The name of the property to memoize.
|
||||||
* @param {number} max The maximum constraint.
|
* @param {function} getter A function of zero to two arguments which
|
||||||
* @returns {number}
|
* will return the property's value. <b>obj</b> is
|
||||||
|
* passed as the first argument, <b>key</b> as the
|
||||||
|
* second.
|
||||||
*/
|
*/
|
||||||
constrain: function constrain(value, min, max) Math.min(Math.max(min, value), max)
|
memoize: memoize,
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a URI string into a URI object.
|
* Converts a URI string into a URI object.
|
||||||
@@ -578,7 +434,7 @@ const Util = Module("util", {
|
|||||||
[XHTML, 'html'],
|
[XHTML, 'html'],
|
||||||
[XUL, 'xul']
|
[XUL, 'xul']
|
||||||
]);
|
]);
|
||||||
if (object instanceof Element) {
|
if (object instanceof Ci.nsIDOMElement) {
|
||||||
let elem = object;
|
let elem = object;
|
||||||
if (elem.nodeType == elem.TEXT_NODE)
|
if (elem.nodeType == elem.TEXT_NODE)
|
||||||
return elem.data;
|
return elem.data;
|
||||||
@@ -616,10 +472,12 @@ const Util = Module("util", {
|
|||||||
let keys = [];
|
let keys = [];
|
||||||
try { // window.content often does not want to be queried with "var i in object"
|
try { // window.content often does not want to be queried with "var i in object"
|
||||||
let hasValue = !("__iterator__" in object);
|
let hasValue = !("__iterator__" in object);
|
||||||
|
/*
|
||||||
if (modules.isPrototypeOf(object)) {
|
if (modules.isPrototypeOf(object)) {
|
||||||
object = Iterator(object);
|
object = Iterator(object);
|
||||||
hasValue = false;
|
hasValue = false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
for (let i in object) {
|
for (let i in object) {
|
||||||
let value = <![CDATA[<no value>]]>;
|
let value = <![CDATA[<no value>]]>;
|
||||||
try {
|
try {
|
||||||
@@ -627,7 +485,7 @@ const Util = Module("util", {
|
|||||||
}
|
}
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
if (!hasValue) {
|
if (!hasValue) {
|
||||||
if (i instanceof Array && i.length == 2)
|
if (isarray(i) && i.length == 2)
|
||||||
[i, value] = i;
|
[i, value] = i;
|
||||||
else
|
else
|
||||||
var noVal = true;
|
var noVal = true;
|
||||||
@@ -689,7 +547,7 @@ const Util = Module("util", {
|
|||||||
let endTime = Date.now() + time;
|
let endTime = Date.now() + time;
|
||||||
while (start < end) {
|
while (start < end) {
|
||||||
if (Date.now() > endTime) {
|
if (Date.now() > endTime) {
|
||||||
dactyl.threadYield(true, true);
|
util.threadYield(true, true);
|
||||||
endTime = Date.now() + time;
|
endTime = Date.now() + time;
|
||||||
}
|
}
|
||||||
yield start++;
|
yield start++;
|
||||||
@@ -746,6 +604,58 @@ const Util = Module("util", {
|
|||||||
elem.scrollIntoView();
|
elem.scrollIntoView();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
sleep: function (delay) {
|
||||||
|
let mainThread = services.get("threadManager").mainThread;
|
||||||
|
|
||||||
|
let end = Date.now() + delay;
|
||||||
|
while (Date.now() < end)
|
||||||
|
mainThread.processNextEvent(true);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split a string on literal occurrences of a marker.
|
||||||
|
*
|
||||||
|
* Specifically this ignores occurrences preceded by a backslash, or
|
||||||
|
* contained within 'single' or "double" quotes.
|
||||||
|
*
|
||||||
|
* It assumes backslash escaping on strings, and will thus not count quotes
|
||||||
|
* that are preceded by a backslash or within other quotes as starting or
|
||||||
|
* ending quoted sections of the string.
|
||||||
|
*
|
||||||
|
* @param {string} str
|
||||||
|
* @param {RegExp} marker
|
||||||
|
*/
|
||||||
|
splitLiteral: function splitLiteral(str, marker) {
|
||||||
|
let results = [];
|
||||||
|
let resep = RegExp(/^(([^\\'"]|\\.|'([^\\']|\\.)*'|"([^\\"]|\\.)*")*?)/.source + marker.source);
|
||||||
|
let cont = true;
|
||||||
|
|
||||||
|
while (cont) {
|
||||||
|
cont = false;
|
||||||
|
str = str.replace(resep, function (match, before) {
|
||||||
|
results.push(before);
|
||||||
|
cont = true;
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
results.push(str);
|
||||||
|
return results;
|
||||||
|
},
|
||||||
|
|
||||||
|
threadYield: function (flush, interruptable) {
|
||||||
|
let mainThread = services.get("threadManager").mainThread;
|
||||||
|
/* FIXME */
|
||||||
|
util.interrupted = false;
|
||||||
|
do {
|
||||||
|
mainThread.processNextEvent(!flush);
|
||||||
|
if (util.interrupted)
|
||||||
|
throw new Error("Interrupted");
|
||||||
|
}
|
||||||
|
while (flush === true && mainThread.hasPendingEvents());
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an E4X XML literal to a DOM node.
|
* Converts an E4X XML literal to a DOM node.
|
||||||
*
|
*
|
||||||
@@ -780,133 +690,26 @@ const Util = Module("util", {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
// TODO: Why don't we just push all util.BuiltinType up into modules? --djk
|
Array: array
|
||||||
/**
|
|
||||||
* Array utility methods.
|
|
||||||
*/
|
|
||||||
Array: Class("Array", Array, {
|
|
||||||
init: function (ary) {
|
|
||||||
return {
|
|
||||||
__proto__: ary,
|
|
||||||
__iterator__: function () this.iteritems(),
|
|
||||||
__noSuchMethod__: function (meth, args) {
|
|
||||||
var res = util.Array[meth].apply(null, [this.__proto__].concat(args));
|
|
||||||
|
|
||||||
if (util.Array.isinstance(res))
|
|
||||||
return util.Array(res);
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
toString: function () this.__proto__.toString(),
|
|
||||||
concat: function () this.__proto__.concat.apply(this.__proto__, arguments),
|
|
||||||
map: function () this.__noSuchMethod__("map", Array.slice(arguments))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
isinstance: function isinstance(obj) {
|
|
||||||
return Object.prototype.toString.call(obj) == "[object Array]";
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts an array to an object. As in lisp, an assoc is an
|
|
||||||
* array of key-value pairs, which maps directly to an object,
|
|
||||||
* as such:
|
|
||||||
* [["a", "b"], ["c", "d"]] -> { a: "b", c: "d" }
|
|
||||||
*
|
|
||||||
* @param {Array[]} assoc
|
|
||||||
* @... {string} 0 - Key
|
|
||||||
* @... 1 - Value
|
|
||||||
*/
|
|
||||||
toObject: function toObject(assoc) {
|
|
||||||
let obj = {};
|
|
||||||
assoc.forEach(function ([k, v]) { obj[k] = v; });
|
|
||||||
return obj;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compacts an array, removing all elements that are null or undefined:
|
|
||||||
* ["foo", null, "bar", undefined] -> ["foo", "bar"]
|
|
||||||
*
|
|
||||||
* @param {Array} ary
|
|
||||||
* @returns {Array}
|
|
||||||
*/
|
|
||||||
compact: function compact(ary) ary.filter(function (item) item != null),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flattens an array, such that all elements of the array are
|
|
||||||
* joined into a single array:
|
|
||||||
* [["foo", ["bar"]], ["baz"], "quux"] -> ["foo", ["bar"], "baz", "quux"]
|
|
||||||
*
|
|
||||||
* @param {Array} ary
|
|
||||||
* @returns {Array}
|
|
||||||
*/
|
|
||||||
flatten: function flatten(ary) ary.length ? Array.concat.apply([], ary) : [],
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an Iterator for an array's values.
|
|
||||||
*
|
|
||||||
* @param {Array} ary
|
|
||||||
* @returns {Iterator(Object)}
|
|
||||||
*/
|
|
||||||
itervalues: function itervalues(ary) {
|
|
||||||
let length = ary.length;
|
|
||||||
for (let i = 0; i < length; i++)
|
|
||||||
yield ary[i];
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an Iterator for an array's indices and values.
|
|
||||||
*
|
|
||||||
* @param {Array} ary
|
|
||||||
* @returns {Iterator([{number}, {Object}])}
|
|
||||||
*/
|
|
||||||
iteritems: function iteritems(ary) {
|
|
||||||
let length = ary.length;
|
|
||||||
for (let i = 0; i < length; i++)
|
|
||||||
yield [i, ary[i]];
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filters out all duplicates from an array. If
|
|
||||||
* <b>unsorted</b> is false, the array is sorted before
|
|
||||||
* duplicates are removed.
|
|
||||||
*
|
|
||||||
* @param {Array} ary
|
|
||||||
* @param {boolean} unsorted
|
|
||||||
* @returns {Array}
|
|
||||||
*/
|
|
||||||
uniq: function uniq(ary, unsorted) {
|
|
||||||
let ret = [];
|
|
||||||
if (unsorted) {
|
|
||||||
for (let [, item] in Iterator(ary))
|
|
||||||
if (ret.indexOf(item) == -1)
|
|
||||||
ret.push(item);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (let [, item] in Iterator(ary.sort())) {
|
|
||||||
if (item != last || !ret.length)
|
|
||||||
ret.push(item);
|
|
||||||
var last = item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Zips the contents of two arrays. The resulting array is twice the
|
|
||||||
* length of ary1, with any shortcomings of ary2 replaced with null
|
|
||||||
* strings.
|
|
||||||
*
|
|
||||||
* @param {Array} ary1
|
|
||||||
* @param {Array} ary2
|
|
||||||
* @returns {Array}
|
|
||||||
*/
|
|
||||||
zip: function zip(ary1, ary2) {
|
|
||||||
let res = []
|
|
||||||
for(let [i, item] in Iterator(ary1))
|
|
||||||
res.push(item, i in ary2 ? ary2[i] : "");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Math utility methods.
|
||||||
|
* @singleton
|
||||||
|
*/
|
||||||
|
var Math = {
|
||||||
|
__proto__: window.Math,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the specified <b>value</b> constrained to the range <b>min</b> -
|
||||||
|
* <b>max</b>.
|
||||||
|
*
|
||||||
|
* @param {number} value The value to constrain.
|
||||||
|
* @param {number} min The minimum constraint.
|
||||||
|
* @param {number} max The maximum constraint.
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
constrain: function constrain(value, min, max) Math.min(Math.max(min, value), max)
|
||||||
|
};
|
||||||
|
|
||||||
// vim: set fdm=marker sw=4 ts=4 et:
|
// vim: set fdm=marker sw=4 ts=4 et:
|
||||||
|
|||||||
Reference in New Issue
Block a user