@@ -192,23 +205,13 @@ const Template = Module("template", {
return str;
},
- commandOutput: function generic(command, xml) {
- return <>:{command}
{xml}>;
- },
-
- genericTable: function genericTable(items, format) {
- completion.listCompleter(function (context) {
- context.filterFunc = null;
- if (format)
- context.format = format;
- context.completions = items;
- });
- },
+ icon: function (item, text) <>
+
{item.icon ?
: <>>}{text}
+ >,
jumps: function jumps(index, elems) {
//
- return this.commandOutput(
-
+ return
| jump | title | URI |
@@ -221,14 +224,13 @@ const Template = Module("template", {
{val.URI.spec} |
)
}
-
);
+
;
//
},
options: function options(title, opts) {
//
- return this.commandOutput(
-
+ return
| --- {title} --- |
@@ -241,7 +243,7 @@ const Template = Module("template", {
)
}
-
);
+
;
//
},
@@ -269,8 +271,7 @@ const Template = Module("template", {
tabular: function tabular(headings, style, iter) {
// TODO: This might be mind-bogglingly slow. We'll see.
//
- return this.commandOutput(
-
+ return
{
this.map(headings, function (h)
@@ -286,14 +287,13 @@ const Template = Module("template", {
}
)
}
-
);
+
;
//
},
usage: function usage(iter) {
//
- return this.commandOutput(
-
+ return
{
this.map(iter, function (item)
@@ -301,9 +301,11 @@ const Template = Module("template", {
| {item.description} |
)
}
-
);
+
;
//
}
});
-// vim: set fdm=marker sw=4 ts=4 et:
+endmodule();
+
+// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
diff --git a/common/content/util.js b/common/modules/util.jsm
similarity index 83%
rename from common/content/util.js
rename to common/modules/util.jsm
index a0ae92c7..5d854b44 100644
--- a/common/content/util.js
+++ b/common/modules/util.jsm
@@ -6,25 +6,71 @@
// given in the LICENSE.txt file included with this file.
"use strict";
-/** @scope modules */
+Components.utils.import("resource://dactyl/base.jsm");
+defmodule("util", this, {
+ exports: ["Math", "NS", "Util", "XHTML", "XUL", "util"],
+ require: ["services"],
+ use: ["template"]
+});
const XHTML = Namespace("html", "http://www.w3.org/1999/xhtml");
const XUL = Namespace("xul", "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
const NS = Namespace("dactyl", "http://vimperator.org/namespaces/liberator");
default xml namespace = XHTML;
-const Util = Module("util", {
+const Util = Module("Util", {
init: function () {
this.Array = array;
},
get activeWindow() services.get("windowWatcher").activeWindow,
+ dactyl: {
+ __noSuchMethod__: function (meth, args) {
+ let win = util.activeWindow;
+ if(win && win.dactyl)
+ return win.dactyl[meth].apply(win.dactyl, args);
+ return null;
+ }
+ },
+
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
+ if (services.get("threadManager").isMainThread)
callback.call(self);
+ else
+ mainThread.dispatch(Runnable(self, callback), mainThread.DISPATCH_NORMAL);
+ },
+
+ /**
+ * 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.
+ */
+ callInThread: function (thread, func) {
+ thread = thread || services.get("threadManager").newThread(0);
+ thread.dispatch(Runnable(null, func, Array.slice(arguments, 2)), thread.DISPATCH_SYNC);
},
/**
@@ -88,7 +134,7 @@ const Util = Module("util", {
clipboardHelper.copyString(str);
if (verbose)
- dactyl.echo("Yanked " + str, commandline.FORCE_SINGLELINE);
+ util.dactyl.echomsg("Yanked " + str);
},
/**
@@ -112,7 +158,10 @@ const Util = Module("util", {
* @param {string} pattern The pattern to deglob.
* @returns [string] The resulting strings.
*/
- debrace: function deglobBrace(pattern) {
+ debrace: function debrace(pattern) {
+ if (pattern.indexOf("{") == -1)
+ return [pattern];
+
function split(pattern, re, fn, dequote) {
let end = 0, match, res = [];
while (match = re.exec(pattern)) {
@@ -132,7 +181,7 @@ const Util = Module("util", {
}, "{}");
function rec(acc) {
if (acc.length == patterns.length)
- res.push(util.Array.zip(substrings, acc).join(""));
+ res.push(array(substrings).zip(acc).flatten().join(""));
else
for (let [, pattern] in Iterator(patterns[acc.length]))
rec(acc.concat(pattern));
@@ -203,7 +252,7 @@ const Util = Module("util", {
*/
evaluateXPath: function (expression, doc, elem, asIterator) {
if (!doc)
- doc = content.document;
+ doc = util.activeWindow.content.document;
if (!elem)
elem = doc;
if (isarray(expression))
@@ -246,20 +295,6 @@ const Util = Module("util", {
return dest;
},
- /**
- * Returns the selection controller for the given window.
- *
- * @param {Window} window
- * @returns {nsISelectionController}
- */
- selectionController: function (win)
- win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell)
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsISelectionDisplay)
- .QueryInterface(Ci.nsISelectionController),
-
/**
* Converts
bytes to a pretty printed data size string.
*
@@ -326,7 +361,7 @@ const Util = Module("util", {
return xmlhttp;
}
catch (e) {
- dactyl.log("Error opening " + String.quote(url) + ": " + e, 1);
+ util.dactyl.log("Error opening " + String.quote(url) + ": " + e, 1);
return null;
}
},
@@ -396,6 +431,8 @@ const Util = Module("util", {
*/
memoize: memoize,
+ newThread: function () services.get("threadManager").newThread(0),
+
/**
* Converts a URI string into a URI object.
*
@@ -471,13 +508,11 @@ const Util = Module("util", {
let keys = [];
try { // window.content often does not want to be queried with "var i in object"
- let hasValue = !("__iterator__" in object);
- /*
- if (modules.isPrototypeOf(object)) {
+ let hasValue = !("__iterator__" in object || isinstance(object, ["Generator", "Iterator"]));
+ if (object.dactyl && object.modules && object.modules.modules == object.modules) {
object = Iterator(object);
hasValue = false;
}
- */
for (let i in object) {
let value = ]]>;
try {
@@ -604,6 +639,28 @@ const Util = Module("util", {
elem.scrollIntoView();
},
+ /**
+ * Returns the selection controller for the given window.
+ *
+ * @param {Window} window
+ * @returns {nsISelectionController}
+ */
+ selectionController: function (win)
+ win.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsISelectionDisplay)
+ .QueryInterface(Ci.nsISelectionController),
+
+ /**
+ * Suspend execution for at least 'delay' milliseconds. Functions by
+ * yielding execution to the next item in the main event queue, and
+ * so may lead to unexpected call graphs, and long delays if another
+ * handler yields execution while waiting.
+ *
+ * @param {number} delay The time period for which to sleep in milliseconds.
+ */
sleep: function (delay) {
let mainThread = services.get("threadManager").mainThread;
@@ -613,6 +670,44 @@ const Util = Module("util", {
return true;
},
+ highlightFilter: function highlightFilter(str, filter, highlight) {
+ return this.highlightSubstrings(str, (function () {
+ if (filter.length == 0)
+ return;
+ let lcstr = String.toLowerCase(str);
+ let lcfilter = filter.toLowerCase();
+ let start = 0;
+ while ((start = lcstr.indexOf(lcfilter, start)) > -1) {
+ yield [start, filter.length];
+ start += filter.length;
+ }
+ })(), highlight || template.filter);
+ },
+
+ /**
+ * Behaves like String.split, except that when 'limit' is reached,
+ * the trailing element contains the entire trailing portion of the
+ * string.
+ *
+ * util.split("a, b, c, d, e", /, /, 3) -> ["a", "b", "c, d, e"]
+ * @param {string} str The string to split.
+ * @param {RegExp|string} re The regular expression on which to split the string.
+ * @param {number} limit The maximum number of elements to return.
+ * @returns {[string]}
+ */
+ split: function (str, re, limit) {
+ if (!re.global)
+ re = RegExp(re.source || re, "g");
+ let match, start = 0, res = [];
+ while ((match = re.exec(str)) && --limit && match[0].length) {
+ res.push(str.substring(start, match.index));
+ start = match.index + match[0].length;
+ }
+ if (limit)
+ res.push(str.substring(start));
+ return res;
+ },
+
/**
* Split a string on literal occurrences of a marker.
*
@@ -670,7 +765,7 @@ const Util = Module("util", {
if (node.length() != 1) {
let domnode = doc.createDocumentFragment();
for each (let child in node)
- domnode.appendChild(arguments.callee(child, doc, nodes));
+ domnode.appendChild(xmlToDom(child, doc, nodes));
return domnode;
}
switch (node.nodeKind()) {
@@ -681,7 +776,7 @@ const Util = Module("util", {
for each (let attr in node.@*)
domnode.setAttributeNS(attr.name() == "highlight" ? NS.uri : attr.namespace(), attr.name(), String(attr));
for each (let child in node.*)
- domnode.appendChild(arguments.callee(child, doc, nodes));
+ domnode.appendChild(xmlToDom(child, doc, nodes));
if (nodes && node.@key)
nodes[node.@key] = domnode;
return domnode;
@@ -697,8 +792,9 @@ const Util = Module("util", {
* Math utility methods.
* @singleton
*/
+const GlobalMath = Math;
var Math = {
- __proto__: window.Math,
+ __proto__: GlobalMath,
/**
* Returns the specified
value constrained to the range
min -
@@ -712,4 +808,8 @@ var Math = {
constrain: function constrain(value, min, max) Math.min(Math.max(min, value), max)
};
-// vim: set fdm=marker sw=4 ts=4 et:
+// catch(e){dump(e.fileName+":"+e.lineNumber+": "+e+"\n");}
+
+endmodule();
+
+// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
diff --git a/pentadactyl/Makefile b/pentadactyl/Makefile
index 81f4685f..71d2f47f 100644
--- a/pentadactyl/Makefile
+++ b/pentadactyl/Makefile
@@ -1,6 +1,6 @@
#### configuration
-VERSION = 2.3a1pre
+VERSION = 1.0pre
NAME = pentadactyl
include ../common/Makefile
diff --git a/pentadactyl/TODO b/pentadactyl/TODO
index a609c847..433cab04 100644
--- a/pentadactyl/TODO
+++ b/pentadactyl/TODO
@@ -41,11 +41,10 @@ BUGS:
- The MOW shouldn't close when executing hints and ;F isn't working.
FEATURES:
+9 Support multiple bookmarks, -keyword, -tags in :delbmarks
8 Document Textarea, Caret and Visual modes.
8 Replace config.name tests in dactyl with more specific feature
tests or overridable APIs where at all feasible.
-8 change the extension ID to pentadactyl@vimperator.org rather than
- pentadactyl@mozdev.org
8 finish :help TODOs
8 fix local options
8 adaptive timeout for auto-completions, :set completions can be updated more often than
diff --git a/pentadactyl/chrome.manifest b/pentadactyl/chrome.manifest
index 153d6654..63e863c7 100644
--- a/pentadactyl/chrome.manifest
+++ b/pentadactyl/chrome.manifest
@@ -9,7 +9,7 @@ resource dactyl ../common/modules/
skin dactyl classic/1.0 ../common/skin/
override chrome://dactyl/content/dactyl.dtd chrome://pentadactyl/content/dactyl.dtd
-override chrome://dactyl/content/config.js chrome://pentadactyl/content/config.js
+override chrome://dactyl/content/config.js chrome://pentadactyl/content/config.js
overlay chrome://browser/content/browser.xul chrome://dactyl/content/dactyl.xul
overlay chrome://browser/content/browser.xul chrome://pentadactyl/content/pentadactyl.xul
diff --git a/pentadactyl/content/about.html b/pentadactyl/content/about.html
index 820879b0..50b333c3 100644
--- a/pentadactyl/content/about.html
+++ b/pentadactyl/content/about.html
@@ -16,11 +16,9 @@

version ###VERSION###
-by Martin Stubenschrott et al.
+by Kris Maglione et al.
Pentadactyl is open source and freely distributable
-Sponsor Pentadactyl development!
type :help sponsor<Enter> for information
-
type :q<Enter> to exit
type :help<Enter> or <F1> for on-line help
type :help version-2.1<Enter> for version info
diff --git a/pentadactyl/content/config.js b/pentadactyl/content/config.js
index 64bebd44..b727bbf3 100644
--- a/pentadactyl/content/config.js
+++ b/pentadactyl/content/config.js
@@ -6,10 +6,6 @@
// given in the LICENSE.txt file included with this file.
const Config = Module("config", ConfigBase, {
- init: function () {
- },
-
- /*** required options, no checks done if they really exist, so be careful ***/
name: "Pentadactyl",
hostApplication: "Firefox",
@@ -122,12 +118,13 @@ const Config = Module("config", ConfigBase, {
},
scripts: [
- "browser.js",
- "bookmarks.js",
- "history.js",
- "quickmarks.js",
- "sanitizer.js",
- "tabs.js"
+ "browser",
+ "bookmarkcache",
+ "bookmarks",
+ "history",
+ "quickmarks",
+ "sanitizer",
+ "tabs"
],
get tempFile() {
@@ -299,6 +296,7 @@ const Config = Module("config", ConfigBase, {
"": modes.NORMAL | modes.INSERT,
"": modes.NORMAL | modes.INSERT
};
+ config.modes.forEach(function (mode) { modes.addMode.apply(this, mode); });
},
options: function () {
options.add(["online"],
diff --git a/pentadactyl/install.rdf b/pentadactyl/install.rdf
index e8523b45..e5c747c5 100644
--- a/pentadactyl/install.rdf
+++ b/pentadactyl/install.rdf
@@ -1,13 +1,13 @@
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
pentadactyl@dactyl.googlecode.com
Pentadactyl
@VERSION@
Make Firefox behave like Vim
Kris Maglione
- http://pentadactyl.sf.net/
+ http://dactyl.sf.net/
chrome://pentadactyl/skin/icon.png
chrome://dactyl/content/preferences.xul
@@ -19,7 +19,7 @@
{ec8030f7-c20a-464f-9b0e-13a3a9e97384}
3.5
- 4.0
+ 4.0b5pre