1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-20 23:37:59 +01:00

Automagically generate DTDs. One more step towards dropping the chrome: protocol.

--HG--
rename : common/content/io.js => common/modules/io.jsm
This commit is contained in:
Kris Maglione
2011-01-03 21:11:28 -05:00
parent 30ec5fc393
commit 43458d4432
59 changed files with 553 additions and 463 deletions

View File

@@ -24,6 +24,7 @@ var global = this;
var Cc = Components.classes; var Cc = Components.classes;
var Ci = Components.interfaces; var Ci = Components.interfaces;
var Cu = Components.utils; var Cu = Components.utils;
var DNE = "chrome://dactyl/content/does/not/exist";
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
@@ -34,21 +35,23 @@ function makeChannel(url, orig) {
try { try {
if (url == null) if (url == null)
return fakeChannel(orig); return fakeChannel(orig);
if (typeof url === "function") if (typeof url === "function")
return let ([type, data] = url()) StringChannel(data, type, orig); return let ([type, data] = url()) StringChannel(data, type, orig);
let channel = ioService.newChannel(url, null, null); let uri = ioService.newURI(url, null, null);
channel.contentCharset = "UTF-8"; return (new XMLChannel(uri)).channel;
channel.owner = systemPrincipal;
channel.originalURI = orig;
return channel;
} }
catch (e) { catch (e) {
util.reportError(e); util.reportError(e);
throw e; throw e;
} }
} }
function fakeChannel(orig) makeChannel("chrome://dactyl/content/does/not/exist", orig); function fakeChannel(orig) {
let channel = ioService.newChannel(DNE, null, null);
channel.originalURI = orig;
return channel;
}
function redirect(to, orig, time) { function redirect(to, orig, time) {
let html = <html><head><meta http-equiv="Refresh" content={(time || 0) + ";" + to}/></head></html>.toXMLString(); let html = <html><head><meta http-equiv="Refresh" content={(time || 0) + ";" + to}/></head></html>.toXMLString();
return StringChannel(html, "text/html", ioService.newURI(to, null, null)); return StringChannel(html, "text/html", ioService.newURI(to, null, null));
@@ -148,13 +151,13 @@ Dactyl.prototype = {
newChannel: function newChannel(uri) { newChannel: function newChannel(uri) {
try { try {
if (uri.host != "content" && !("all" in this.FILE_MAP)) if (/^help/.test(uri.host) && !("all" in this.FILE_MAP))
return redirect(uri.spec, uri, 1); return redirect(uri.spec, uri, 1);
let path = decodeURIComponent(uri.path.replace(/^\/|#.*/g, "")); let path = decodeURIComponent(uri.path.replace(/^\/|#.*/g, ""));
switch(uri.host) { switch(uri.host) {
case "content": case "content":
return makeChannel(this.pages[path], uri); return makeChannel(this.pages[path] || "chrome://dactyl/content/" + path, uri);
case "help": case "help":
return makeChannel(this.FILE_MAP[path], uri); return makeChannel(this.FILE_MAP[path], uri);
case "help-overlay": case "help-overlay":
@@ -165,6 +168,10 @@ Dactyl.prototype = {
return redirect("dactyl://help/" + tag, uri); return redirect("dactyl://help/" + tag, uri);
if (tag in this.HELP_TAGS) if (tag in this.HELP_TAGS)
return redirect("dactyl://help/" + this.HELP_TAGS[tag] + "#" + tag, uri); return redirect("dactyl://help/" + this.HELP_TAGS[tag] + "#" + tag, uri);
case "locale":
return makeChannel("chrome://dactyl/locale/" + path, uri);
case "locale-local":
return makeChannel("chrome://" + config.name + "/locale/" + path, uri);
} }
} }
catch (e) {} catch (e) {}
@@ -188,6 +195,7 @@ Dactyl.prototype = {
function StringChannel(data, contentType, uri) { function StringChannel(data, contentType, uri) {
let channel = services.StreamChannel(uri); let channel = services.StreamChannel(uri);
channel.contentStream = services.StringStream(data); channel.contentStream = services.StringStream(data);
if (contentType)
channel.contentType = contentType; channel.contentType = contentType;
channel.contentCharset = "UTF-8"; channel.contentCharset = "UTF-8";
channel.owner = systemPrincipal; channel.owner = systemPrincipal;
@@ -197,17 +205,76 @@ function StringChannel(data, contentType, uri) {
} }
function XMLChannel(uri, contentType) { function XMLChannel(uri, contentType) {
let channel = services.io.newChannelFromURI(uri);
try {
var channelStream = channel.open();
}
catch (e) {
this.channel = fakeChannel(uri);
return;
}
this.uri = uri;
this.sourceChannel = services.io.newChannelFromURI(uri); this.sourceChannel = services.io.newChannelFromURI(uri);
this.pipe = services.Pipe(true, true, 0, 0, null); this.pipe = services.Pipe(true, true, 0, 0, null);
this.writes = [];
this.channel = services.StreamChannel(uri); this.channel = services.StreamChannel(uri);
this.channel.contentStream = this.pipe.outputStream; this.channel.contentStream = this.pipe.inputStream;
this.channel.contentType = contentType; this.channel.contentType = contentType || channel.contentType;
this.channel.contentCharset = "UTF-8"; this.channel.contentCharset = "UTF-8";
this.channel.owner = systemPrincipal; this.channel.owner = systemPrincipal;
let stream = services.InputStream(channelStream);
let [, pre, doctype, url, open, post] = util.regexp(<![CDATA[
^ ([^]*?)
(?:
(<!DOCTYPE \s+ \S+ \s+) SYSTEM \s+ "([^"]*)"
(\s+ \[)?
([^]*)
)?
$
]]>).exec(stream.read(4096));
this.writes.push(pre);
if (doctype) {
this.writes.push(doctype + "[\n");
try {
this.writes.push(services.io.newChannel(url, null, null).open())
}
catch (e) {}
if (!open)
this.writes.push("\n]");
this.writes.push(post)
}
this.writes.push(channelStream);
this.writeNext();
} }
XMLChannel.prototype = { XMLChannel.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRequestObserver]), QueryInterface: XPCOMUtils.generateQI([Ci.nsIRequestObserver]),
writeNext: function () {
try {
if (!this.writes.length)
this.pipe.outputStream.close();
else {
let stream = this.writes.shift();
if (isString(stream))
stream = services.StringStream(stream);
services.StreamCopier(stream, this.pipe.outputStream, null,
false, true, 4096, true, false)
.asyncCopy(this, null);
}
}
catch (e) {
util.reportError(e);
}
},
onStartRequest: function (request, context) {},
onStopRequest: function (request, context, statusCode) {
this.writeNext();
}
}; };
function AboutHandler() {} function AboutHandler() {}

View File

@@ -1,19 +0,0 @@
<!ENTITY % dactylBranding SYSTEM "chrome://branding/locale/brand.dtd">
%dactylBranding;
<!ENTITY dactyl.version "@VERSION@">
<!ENTITY dactyl.host "&brandShortName;">
<!ENTITY dactyl.home "http://dactyl.sourceforge.net/">
<!ENTITY dactyl.apphome "&dactyl.home;&dactyl.name;">
<!ENTITY dactyl.code "http://code.google.com/p/dactyl/">
<!ENTITY dactyl.issues "&dactyl.home;bug/&dactyl.name;">
<!ENTITY dactyl.plugins "http://dactyl.sf.net/&dactyl.name;/plugins">
<!ENTITY dactyl.list.mailto "&dactyl.name;@googlegroups.com">
<!ENTITY dactyl.list.href "http://groups.google.com/group/&dactyl.name;">
<!ENTITY dactyl.faq "&dactyl.home;&dactyl.name;/faq">
<!ENTITY xmlns.dactyl "http://vimperator.org/namespaces/liberator">
<!ENTITY xmlns.html "http://www.w3.org/1999/xhtml">
<!ENTITY xmlns.xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

View File

@@ -92,9 +92,9 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* @property {number} The current main mode. * @property {number} The current main mode.
* @see modes#mainModes * @see modes#mainModes
*/ */
mode: Class.Property({ mode: deprecated("Please use modes.main instead", {
get: deprecated("Please use modes.main instead", function mode() modes.main), get: function mode() modes.main,
set: deprecated("Please use modes.main instead", function mode(val) modes.main = val), set: function mode(val) modes.main = val
}), }),
get menuItems() Dactyl.getMenuItems(), get menuItems() Dactyl.getMenuItems(),
@@ -108,23 +108,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
forceNewTab: false, forceNewTab: false,
forceNewWindow: false, forceNewWindow: false,
/** @property {string} The Dactyl version string. */ version: deprecated("Please use config.version instead", { get: function version() config.version }),
version: Class.memoize(function () {
if (/pre$/.test(util.addon.version)) {
let uri = util.addon.getResourceURI("../.hg");
if (uri instanceof Ci.nsIFileURL &&
uri.QueryInterface(Ci.nsIFileURL).file.exists() &&
io.pathSearch("hg")) {
return io.system(["hg", "-R", uri.file.parent.path,
"log", "-r.",
"--template=hg{rev} ({date|isodate})"]);
}
}
let version = util.addon.version;
if ("@DATE" !== "@" + "DATE@")
version += " (created: @DATE@)";
return version;
}),
/** /**
* @property {Object} The map of command-line options. These are * @property {Object} The map of command-line options. These are
@@ -304,9 +288,9 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
}, },
dump: deprecated("Use util.dump instead", dump: deprecated("Use util.dump instead",
function dump() util.dump.apply(util, arguments)), { get: function dump() util.closure.dump }),
dumpStack: deprecated("Use util.dumpStack instead", dumpStack: deprecated("Use util.dumpStack instead",
function dumpStack() util.dumpStack.apply(util, arguments)), { get: function dumpStack() util.closure.dumpStack }),
/** /**
* Outputs a plain message to the command line. * Outputs a plain message to the command line.
@@ -546,14 +530,14 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* @private * @private
* Initialize the help system. * Initialize the help system.
*/ */
initHelp: function () { initHelp: function (force) {
if (!this.helpInitialized) { if (!force && !this.helpInitialized) {
if ("noscriptOverlay" in window) { if ("noscriptOverlay" in window) {
noscriptOverlay.safeAllow("chrome-data:", true, false); noscriptOverlay.safeAllow("chrome-data:", true, false);
noscriptOverlay.safeAllow("dactyl:", true, false); noscriptOverlay.safeAllow("dactyl:", true, false);
} }
let namespaces = [config.name, "dactyl"]; let namespaces = ["locale-local", "locale"];
services["dactyl:"].init({}); services["dactyl:"].init({});
let tagMap = services["dactyl:"].HELP_TAGS; let tagMap = services["dactyl:"].HELP_TAGS;
@@ -564,7 +548,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
function findHelpFile(file) { function findHelpFile(file) {
let result = []; let result = [];
for (let [, namespace] in Iterator(namespaces)) { for (let [, namespace] in Iterator(namespaces)) {
let url = ["chrome://", namespace, "/locale/", file, ".xml"].join(""); let url = ["dactyl://", namespace, "/", file, ".xml"].join("");
let res = util.httpGet(url); let res = util.httpGet(url);
if (res) { if (res) {
if (res.responseXML.documentElement.localName == "document") if (res.responseXML.documentElement.localName == "document")
@@ -894,9 +878,8 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
* These are set and accessed with the "g:" prefix. * These are set and accessed with the "g:" prefix.
*/ */
_globalVariables: {}, _globalVariables: {},
globalVariables: Class.Property({ globalVariables: deprecated("Please use the options system instead", {
get: deprecated("Please use the options system instead", get: function globalVariables() this._globalVariables
function globalVariables() this._globalVariables)
}), }),
loadPlugins: function (args) { loadPlugins: function (args) {
@@ -2051,7 +2034,7 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
dactyl.open("about:"); dactyl.open("about:");
else else
commandline.commandOutput(<> commandline.commandOutput(<>
{config.appName} {dactyl.version} running on:<br/>{navigator.userAgent} {config.appName} {config.version} running on:<br/>{navigator.userAgent}
</>); </>);
}, { }, {
argCount: "0", argCount: "0",

View File

@@ -1,6 +0,0 @@
<!ENTITY % dactylMain SYSTEM "chrome://dactyl/content/dactyl.dtd">
%dactylMain;
<!ENTITY tag.command-line '<link topic="command-line">command line</link>'>
<!ENTITY tag.status-line '<link topic="status-line">status line</link>'>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE stylesheet SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE stylesheet SYSTEM "dactyl://content/dtd">
<!-- Header {{{1 --> <!-- Header {{{1 -->
<xsl:stylesheet version="1.0" <xsl:stylesheet version="1.0"

View File

@@ -163,9 +163,9 @@ var Option = Class("Option", {
setValues: deprecated("Please use Option#set instead", "set"), setValues: deprecated("Please use Option#set instead", "set"),
joinValues: deprecated("Please use Option#stringify instead", "stringify"), joinValues: deprecated("Please use Option#stringify instead", "stringify"),
parseValues: deprecated("Please use Option#parse instead", "parse"), parseValues: deprecated("Please use Option#parse instead", "parse"),
values: Class.Property({ values: deprecated("Please use Option#value instead", {
get: deprecated("Please use Option#value instead", function values() this.value), get: function values() this.value,
set: deprecated("Please use Option#value instead", function values(val) this.value = val) set: function values(val) this.value = val
}), }),
/** /**

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="all" name="all"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="autocommands" name="autocommands"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="browsing" name="browsing"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="buffer" name="buffer"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="cmdline" name="cmdline"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd" [ <!DOCTYPE document SYSTEM "dactyl://content/dtd" [
<!ENTITY tab "&#xa0;&#xa0;&#xa0;"> <!ENTITY tab "&#xa0;&#xa0;&#xa0;">
]> ]>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="eval" name="eval"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="gui" name="gui"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="hints" name="hints"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="index" name="index"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="insert" name="insert"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="intro" name="intro"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="map" name="map"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="marks" name="marks"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="message" name="message"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd" [ <!DOCTYPE document SYSTEM "dactyl://content/dtd" [
<!ENTITY hinttags "//*[@onclick or @onmouseover or @onmousedown or <!ENTITY hinttags "//*[@onclick or @onmouseover or @onmousedown or
@onmouseup or @oncommand or @role='link'] | @onmouseup or @oncommand or @role='link'] |
//input[not(@type='hidden')] | //xhtml:input[not(@type='hidden')] | //input[not(@type='hidden')] | //xhtml:input[not(@type='hidden')] |

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="pattern" name="pattern"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="print" name="print"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="repeat" name="repeat"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="starting" name="starting"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="styling" name="styling"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="tabs" name="tabs"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="various" name="various"

View File

@@ -312,6 +312,10 @@ function properties(obj, prototypes, debugger_) {
} }
function deprecated(reason, fn) { function deprecated(reason, fn) {
if (isObject(fn))
return Class.Property(iter(fn).map(function ([k, v]) [k, callable(v) ? deprecated(reason, v) : v])
.toObject());
let name, func = callable(fn) ? fn : function () this[fn].apply(this, arguments); let name, func = callable(fn) ? fn : function () this[fn].apply(this, arguments);
function deprecatedMethod() { function deprecatedMethod() {
@@ -708,6 +712,23 @@ function Class() {
}); });
return Constructor; return Constructor;
} }
if (Cu.getGlobalForObject)
Class.objectGlobal = function (caller) {
try {
return Cu.getGlobalForObject(caller);
}
catch (e) {
return null;
}
};
else
Class.objectGlobal = function (caller) {
while (caller.__parent__)
caller = caller.__parent__;
return caller;
};
/** /**
* @class Class.Property * @class Class.Property
* A class which, when assigned to a property in a Class's prototype * A class which, when assigned to a property in a Class's prototype
@@ -870,27 +891,34 @@ function Module(name, prototype) {
const module = Class.apply(Class, Array.slice(arguments, 0, init)); const module = Class.apply(Class, Array.slice(arguments, 0, init));
let instance = module(); let instance = module();
module.className = name.toLowerCase(); module.className = name.toLowerCase();
instance.INIT = arguments[init] || {};
instance.INIT = update(Object.create(Module.INIT),
arguments[init] || {});
currentModule[module.className] = instance; currentModule[module.className] = instance;
defineModule.modules.push(instance); defineModule.modules.push(instance);
return module; return module;
} }
Module.INIT = {
init: function (dactyl, modules, window) {
let args = arguments;
if (Cu.getGlobalForObject) let locals = [];
Class.objectGlobal = function (caller) { for (let local = this.Local; local; local = local.super)
try { locals.push(local);
return Cu.getGlobalForObject(caller);
if (locals.length) {
let module = this, objs = {};
for (let i in locals)
module = objs[i] = Object.create(module);
modules[this.constructor.className] = module;
locals.reverse().forEach(function (fn, i) update(objs[i], fn.apply(module, args)))
module.instance = module;
module.init();
} }
catch (e) {
return null;
} }
}; }
else
Class.objectGlobal = function (caller) {
while (caller.__parent__)
caller = caller.__parent__;
return caller;
};
/** /**
* @class Struct * @class Struct

View File

@@ -11,7 +11,8 @@ try {
Components.utils.import("resource://dactyl/base.jsm"); Components.utils.import("resource://dactyl/base.jsm");
defineModule("config", { defineModule("config", {
exports: ["ConfigBase", "Config", "config"], exports: ["ConfigBase", "Config", "config"],
require: ["highlight", "services", "storage", "util", "template"] require: ["highlight", "services", "storage", "util", "template"],
use: ["io"]
}); });
var ConfigBase = Class("ConfigBase", { var ConfigBase = Class("ConfigBase", {
@@ -37,9 +38,77 @@ var ConfigBase = Class("ConfigBase", {
if (util.haveGecko("2b")) if (util.haveGecko("2b"))
this.features.push("Gecko2"); this.features.push("Gecko2");
this.timeout(function () {
services["dactyl:"].pages.dtd = function () [null,
iter(config.dtdExtra, (["dactyl." + s, config[s]] for each (s in config.dtdStrings)))
.map(function ([k, v]) ["<!ENTITY ", k, " '", String.replace(v, /'/g, "&apos;"), "'>"].join(""))
.join("\n")]
});
}, },
get addonID() this.name + "@dactyl.googlecode.com", get addonID() this.name + "@dactyl.googlecode.com",
addon: Class.memoize(function () {
let addon = services.fuel.storage.get("dactyl.bootstrap", {}).addon;
if (!addon)
addon = AddonManager.getAddonByID(this.addonID);
return addon;
}),
/** @property {string} The Dactyl version string. */
version: Class.memoize(function () {
if (/pre$/.test(this.addon.version)) {
let uri = this.addon.getResourceURI("../.hg");
if (uri instanceof Ci.nsIFileURL &&
uri.QueryInterface(Ci.nsIFileURL).file.exists() &&
io.pathSearch("hg")) {
return io.system(["hg", "-R", uri.file.parent.path,
"log", "-r.",
"--template=hg{rev} ({date|isodate})"]);
}
}
let version = this.addon.version;
if ("@DATE" !== "@" + "DATE@")
version += " (created: @DATE@)";
return version;
}),
// TODO: DTD properties. Cleanup.
get home() "http://dactyl.sourceforge.net/",
get apphome() this.home + this.name,
code: "http://code.google.com/p/dactyl/",
get issues() this.home + "bug/" + this.name,
get plugins() "http://dactyl.sf.net/" + this.name + "/plugins",
get faq() this.home + this.name + "/faq",
"list.mailto": Class.memoize(function () config.name + "@googlegroups.com"),
"list.href": Class.memoize(function () "http://groups.google.com/group/" + config.name),
dtdExtra: {
"xmlns.dactyl": "http://vimperator.org/namespaces/liberator",
"xmlns.html": "http://www.w3.org/1999/xhtml",
"xmlns.xul": "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"tag.command-line": '<link topic="command-line">command line</link>',
"tag.status-line": '<link topic="status-line">status line</link>',
},
dtdStrings: [
"appName",
"apphome",
"code",
"faq",
"fileExt",
"home",
"host",
"hostbin",
"idName",
"issues",
"list.href",
"list.mailto",
"name",
"plugins",
"version",
],
styleHelp: function styleHelp() { styleHelp: function styleHelp() {
if (!this.helpStyled) if (!this.helpStyled)
@@ -519,15 +588,6 @@ config.INIT = update(Object.create(config.INIT), config.INIT, {
init: function init(dactyl, modules, window) { init: function init(dactyl, modules, window) {
init.superapply(this, arguments); init.superapply(this, arguments);
// Hmm...
let config1 = Object.create(config);
let config2 = Object.create(config1);
config2.instance = config2;
update(config1, config.Local.superapply(config2, arguments));
update(config2, config.Local.apply(config2, arguments));
modules.config = config2;
modules.config.init();
let img = window.Image(); let img = window.Image();
img.src = this.logo || "chrome://" + this.name + "/content/logo.png"; img.src = this.logo || "chrome://" + this.name + "/content/logo.png";
img.onload = function () { img.onload = function () {

View File

@@ -7,31 +7,14 @@
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
"use strict"; "use strict";
/** @scope modules */ try {
plugins.contexts = {}; Components.utils.import("resource://dactyl/base.jsm");
function Script(file) { defineModule("io", {
let self = set.has(plugins, file.path) && plugins[file.path]; exports: ["IO", "io"],
if (self) { require: ["services"],
if (set.has(self, "onUnload")) use: ["config", "storage", "template", "util"]
self.onUnload(); });
}
else {
self = update({ __proto__: plugins }, {
NAME: file.leafName.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase()),
PATH: file.path,
CONTEXT: self
});
Class.replaceProperty(plugins, file.path, self);
// This belongs elsewhere
if (io.getRuntimeDirectories("plugins").some(
function (dir) dir.contains(file, false)))
Class.replaceProperty(plugins, self.NAME, self);
}
plugins.contexts[file.path] = self;
return self;
}
// TODO: why are we passing around strings rather than file objects? // TODO: why are we passing around strings rather than file objects?
/** /**
@@ -43,6 +26,14 @@ var IO = Module("io", {
this._processDir = services.directory.get("CurWorkD", Ci.nsIFile); this._processDir = services.directory.get("CurWorkD", Ci.nsIFile);
this._cwd = this._processDir.path; this._cwd = this._processDir.path;
this._oldcwd = null; this._oldcwd = null;
},
Local: function (dactyl, modules, window) let ({ Script, plugins } = modules) ({
init: function init() {
this._processDir = services.directory.get("CurWorkD", Ci.nsIFile);
this._cwd = this._processDir.path;
this._oldcwd = null;
this._lastRunCommand = ""; // updated whenever the users runs a command with :! this._lastRunCommand = ""; // updated whenever the users runs a command with :!
this._scriptNames = []; this._scriptNames = [];
@@ -56,8 +47,8 @@ var IO = Module("io", {
let size = download.size; let size = download.size;
dactyl.echomsg({ domains: [util.getHost(url)], message: "Download of " + title + " to " + file + " finished" }, dactyl.echomsg({ domains: [util.getHost(url)], message: "Download of " + title + " to " + file + " finished" },
1, commandline.ACTIVE_WINDOW); 1, modules.commandline.ACTIVE_WINDOW);
autocommands.trigger("DownloadPost", { url: url, title: title, file: file, size: size }); modules.autocommands.trigger("DownloadPost", { url: url, title: title, file: file, size: size });
} }
}, },
onStateChange: function () {}, onStateChange: function () {},
@@ -68,13 +59,136 @@ var IO = Module("io", {
services.downloadManager.addListener(this.downloadListener); services.downloadManager.addListener(this.downloadListener);
}, },
destroy: function () { destroy: function destroy() {
services.downloadManager.removeListener(this.downloadListener); services.downloadManager.removeListener(this.downloadListener);
for (let [, plugin] in Iterator(plugins.contexts)) for (let [, plugin] in Iterator(plugins.contexts))
if (plugin.onUnload) if (plugin.onUnload)
plugin.onUnload(); plugin.onUnload();
}, },
/**
* Returns all directories named *name* in 'runtimepath'.
*
* @param {string} name
* @returns {nsIFile[])
*/
getRuntimeDirectories: function getRuntimeDirectories(name) {
let dirs = modules.options["runtimepath"];
dirs = dirs.map(function (dir) File.joinPaths(dir, name, this.cwd), this)
.filter(function (dir) dir.exists() && dir.isDirectory() && dir.isReadable());
return dirs;
},
// FIXME: multiple paths?
/**
* Sources files found in 'runtimepath'. For each relative path in *paths*
* each directory in 'runtimepath' is searched and if a matching file is
* found it is sourced. Only the first file found (per specified path) is
* sourced unless *all* is specified, then all found files are sourced.
*
* @param {string[]} paths An array of relative paths to source.
* @param {boolean} all Whether all found files should be sourced.
*/
sourceFromRuntimePath: function sourceFromRuntimePath(paths, all) {
let dirs = options["runtimepath"];
let found = false;
dactyl.echomsg("Searching for " + paths.join(" ").quote() + " in " + options.get("runtimepath").stringValue, 2);
outer:
for (let [, dir] in Iterator(dirs)) {
for (let [, path] in Iterator(paths)) {
let file = File.joinPaths(dir, path, this.cwd);
dactyl.echomsg("Searching for " + file.path.quote(), 3);
if (file.exists() && file.isFile() && file.isReadable()) {
io.source(file.path, false);
found = true;
if (!all)
break outer;
}
}
}
if (!found)
dactyl.echomsg("not found in 'runtimepath': " + paths.join(" ").quote(), 1);
return found;
},
/**
* Reads Ex commands, JavaScript or CSS from *filename*.
*
* @param {string} filename The name of the file to source.
* @param {boolean} silent Whether errors should be reported.
*/
source: function source(filename, silent) {
defineModule.loadLog.push("sourcing " + filename);
let time = Date.now();
this.withSavedValues(["sourcing"], function _source() {
this.sourcing = null;
try {
var file = util.getFile(filename) || io.File(filename);
if (!file.exists() || !file.isReadable() || file.isDirectory()) {
if (!silent)
dactyl.echoerr("E484: Can't open file " + filename.quote());
return;
}
dactyl.echomsg("sourcing " + filename.quote(), 2);
let uri = services.io.newFileURI(file);
// handle pure JavaScript files specially
if (/\.js$/.test(filename)) {
try {
dactyl.loadScript(uri.spec, Script(file));
dactyl.helpInitialized = false;
}
catch (e) {
if (e.fileName)
try {
e.fileName = e.fileName.replace(/^(chrome|resource):.*? -> /, "");
if (e.fileName == uri.spec)
e.fileName = filename;
e.echoerr = <>{e.fileName}:{e.lineNumber}: {e}</>;
}
catch (e) {}
throw e;
}
}
else if (/\.css$/.test(filename))
styles.registerSheet(uri.spec, false, true);
else {
modules.commands.execute(file.read(), null, silent || "loud", null,
{ file: file.path, line: 1 });
}
if (this._scriptNames.indexOf(file.path) == -1)
this._scriptNames.push(file.path);
dactyl.echomsg("finished sourcing " + filename.quote(), 2);
dactyl.log("Sourced: " + filename, 3);
}
catch (e) {
if (!(e instanceof FailedAssertion))
dactyl.reportError(e);
let message = "Sourcing file: " + (e.echoerr || file.path + ": " + e);
if (!silent)
dactyl.echoerr(message);
}
finally {
defineModule.loadLog.push("done sourcing " + filename + ": " + (Date.now() - time) + "ms");
}
});
},
}),
// TODO: there seems to be no way, short of a new component, to change // TODO: there seems to be no way, short of a new component, to change
// the process's CWD - see https://bugzilla.mozilla.org/show_bug.cgi?id=280953 // the process's CWD - see https://bugzilla.mozilla.org/show_bug.cgi?id=280953
/** /**
@@ -123,10 +237,11 @@ var IO = Module("io", {
* @property {function} File class. * @property {function} File class.
* @final * @final
*/ */
File: Class("File", File, { File: Class.memoize(function () let (io = this)
Class("File", File, {
init: function init(path, checkCWD) init: function init(path, checkCWD)
init.supercall(this, path, (arguments.length < 2 || checkCWD) && io.cwd) init.supercall(this, path, (arguments.length < 2 || checkCWD) && io.cwd)
}), })),
/** /**
* @property {Object} The current file sourcing context. As a file is * @property {Object} The current file sourcing context. As a file is
@@ -135,36 +250,7 @@ var IO = Module("io", {
*/ */
sourcing: null, sourcing: null,
/** expandPath: deprecated("Please use File.expandPath instead", function expandPath() File.expandPath.apply(File, arguments)),
* Expands "~" and environment variables in *path*.
*
* "~" is expanded to to the value of $HOME. On Windows if this is not
* set then the following are tried in order:
* $USERPROFILE
* ${HOMDRIVE}$HOMEPATH
*
* The variable notation is $VAR (terminated by a non-word character)
* or ${VAR}. %VAR% is also supported on Windows.
*
* @param {string} path The unexpanded path string.
* @param {boolean} relative Whether the path is relative or absolute.
* @returns {string}
*/
expandPath: File.expandPath,
/**
* Returns all directories named *name* in 'runtimepath'.
*
* @param {string} name
* @returns {nsIFile[])
*/
getRuntimeDirectories: function (name) {
let dirs = options["runtimepath"];
dirs = dirs.map(function (dir) File.joinPaths(dir, name, this.cwd), this)
.filter(function (dir) dir.exists() && dir.isDirectory() && dir.isReadable());
return dirs;
},
/** /**
* Returns the first user RC file found in *dir*. * Returns the first user RC file found in *dir*.
@@ -207,7 +293,7 @@ var IO = Module("io", {
Cc["@mozilla.org/uriloader/external-helper-app-service;1"] Cc["@mozilla.org/uriloader/external-helper-app-service;1"]
.getService(Ci.nsPIExternalAppLauncher).deleteTemporaryFileOnExit(file); .getService(Ci.nsPIExternalAppLauncher).deleteTemporaryFileOnExit(file);
return io.File(file); return File(file);
}, },
isJarURL: function (url) { isJarURL: function (url) {
@@ -266,9 +352,9 @@ var IO = Module("io", {
let file; let file;
if (File.isAbsolutePath(program)) if (File.isAbsolutePath(program))
file = io.File(program, true); file = this.File(program, true);
else else
file = io.pathSearch(program); file = this.pathSearch(program);
if (!file || !file.exists()) { if (!file || !file.exists()) {
dactyl.echoerr("Command not found: " + program); dactyl.echoerr("Command not found: " + program);
@@ -283,7 +369,7 @@ var IO = Module("io", {
function () { function () {
if (!process.isRunning) { if (!process.isRunning) {
timer.cancel(); timer.cancel();
dactyl.trapErrors(blocking); util.trapErrors(blocking);
} }
}, },
100, services.Timer.TYPE_REPEATING_SLACK); 100, services.Timer.TYPE_REPEATING_SLACK);
@@ -299,114 +385,6 @@ var IO = Module("io", {
return process.exitValue; return process.exitValue;
}, },
// FIXME: multiple paths?
/**
* Sources files found in 'runtimepath'. For each relative path in *paths*
* each directory in 'runtimepath' is searched and if a matching file is
* found it is sourced. Only the first file found (per specified path) is
* sourced unless *all* is specified, then all found files are sourced.
*
* @param {string[]} paths An array of relative paths to source.
* @param {boolean} all Whether all found files should be sourced.
*/
sourceFromRuntimePath: function (paths, all) {
let dirs = options["runtimepath"];
let found = false;
dactyl.echomsg("Searching for " + paths.join(" ").quote() + " in " + options.get("runtimepath").stringValue, 2);
outer:
for (let [, dir] in Iterator(dirs)) {
for (let [, path] in Iterator(paths)) {
let file = File.joinPaths(dir, path, this.cwd);
dactyl.echomsg("Searching for " + file.path.quote(), 3);
if (file.exists() && file.isFile() && file.isReadable()) {
io.source(file.path, false);
found = true;
if (!all)
break outer;
}
}
}
if (!found)
dactyl.echomsg("not found in 'runtimepath': " + paths.join(" ").quote(), 1);
return found;
},
/**
* Reads Ex commands, JavaScript or CSS from *filename*.
*
* @param {string} filename The name of the file to source.
* @param {boolean} silent Whether errors should be reported.
*/
source: function (filename, silent) {
defineModule.loadLog.push("sourcing " + filename);
let time = Date.now();
this.withSavedValues(["sourcing"], function () {
this.sourcing = null;
try {
var file = util.getFile(filename) || io.File(filename);
if (!file.exists() || !file.isReadable() || file.isDirectory()) {
if (!silent)
dactyl.echoerr("E484: Can't open file " + filename.quote());
return;
}
dactyl.echomsg("sourcing " + filename.quote(), 2);
let uri = services.io.newFileURI(file);
// handle pure JavaScript files specially
if (/\.js$/.test(filename)) {
try {
dactyl.loadScript(uri.spec, Script(file));
dactyl.helpInitialized = false;
}
catch (e) {
if (e.fileName)
try {
e.fileName = e.fileName.replace(/^(chrome|resource):.*? -> /, "");
if (e.fileName == uri.spec)
e.fileName = filename;
e.echoerr = <>{e.fileName}:{e.lineNumber}: {e}</>;
}
catch (e) {}
throw e;
}
}
else if (/\.css$/.test(filename))
styles.registerSheet(uri.spec, false, true);
else {
commands.execute(file.read(), null, silent || "loud", null,
{ file: file.path, line: 1 });
}
if (this._scriptNames.indexOf(file.path) == -1)
this._scriptNames.push(file.path);
dactyl.echomsg("finished sourcing " + filename.quote(), 2);
dactyl.log("Sourced: " + filename, 3);
}
catch (e) {
if (!(e instanceof FailedAssertion))
dactyl.reportError(e);
let message = "Sourcing file: " + (e.echoerr || file.path + ": " + e);
if (!silent)
dactyl.echoerr(message);
}
finally {
defineModule.loadLog.push("done sourcing " + filename + ": " + (Date.now() - time) + "ms");
}
});
},
// TODO: when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is // TODO: when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is
// fixed use that instead of a tmpfile // fixed use that instead of a tmpfile
/** /**
@@ -418,7 +396,7 @@ var IO = Module("io", {
* @returns {string} * @returns {string}
*/ */
system: function (command, input) { system: function (command, input) {
dactyl.echomsg("Calling shell to execute: " + command, 4); util.dactyl.echomsg("Calling shell to execute: " + command, 4);
function escape(str) '"' + str.replace(/[\\"$]/g, "\\$&") + '"'; function escape(str) '"' + str.replace(/[\\"$]/g, "\\$&") + '"';
@@ -428,7 +406,8 @@ var IO = Module("io", {
else if (input) else if (input)
stdin.write(input); stdin.write(input);
let shell = File.expandPath(options["shell"]); let shell = File.expandPath(storage["options"].get("shell").value);
let shcf = storage["options"].get("shellcmdflag").value;
if (isArray(command)) if (isArray(command))
command = command.map(escape).join(" "); command = command.map(escape).join(" ");
@@ -436,12 +415,12 @@ var IO = Module("io", {
// TODO: implement 'shellredir' // TODO: implement 'shellredir'
if (util.OS.isWindows && !/sh/.test(options["shell"])) { if (util.OS.isWindows && !/sh/.test(options["shell"])) {
command = "cd /D " + this.cwd + " && " + command + " > " + stdout.path + " 2>&1" + " < " + stdin.path; command = "cd /D " + this.cwd + " && " + command + " > " + stdout.path + " 2>&1" + " < " + stdin.path;
var res = this.run(shell, options["shellcmdflag"].split(/\s+/).concat(command), true); var res = this.run(shell, shcf.split(/\s+/).concat(command), true);
} }
else { else {
cmd.write("cd " + escape(this.cwd) + "\n" + cmd.write("cd " + escape(this.cwd) + "\n" +
["exec", ">" + escape(stdout.path), "2>&1", "<" + escape(stdin.path), ["exec", ">" + escape(stdout.path), "2>&1", "<" + escape(stdin.path),
escape(shell), options["shellcmdflag"], escape(command)].join(" ")); escape(shell), shcf, escape(command)].join(" "));
res = this.run("/bin/sh", ["-e", cmd.path], true); res = this.run("/bin/sh", ["-e", cmd.path], true);
} }
@@ -496,9 +475,40 @@ var IO = Module("io", {
/** /**
* @property {string} The current platform's path separator. * @property {string} The current platform's path separator.
*/ */
PATH_SEP: File.PATH_SEP PATH_SEP: deprecated("Please use File.PATH_SEP", { get: function PATH_SEP() File.PATH_SEP })
}, { }, {
commands: function () { init: function init(dactyl, modules, window) {
modules.plugins.contexts = {};
modules.Script = function Script(file) {
const { io, plugins } = modules;
let self = set.has(plugins, file.path) && plugins[file.path];
if (self) {
if (set.has(self, "onUnload"))
self.onUnload();
}
else {
self = update(modules.newContext(plugins, true), {
NAME: file.leafName.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase()),
PATH: file.path,
CONTEXT: self
});
Class.replaceProperty(plugins, file.path, self);
// This belongs elsewhere
if (io.getRuntimeDirectories("plugins").some(
function (dir) dir.contains(file, false)))
Class.replaceProperty(plugins, self.NAME, self);
}
plugins.contexts[file.path] = self;
return self;
}
init.superapply(this, arguments);
},
commands: function (dactyl, modules, window) {
const { commands, completion, io } = modules;
commands.add(["cd", "chd[ir]"], commands.add(["cd", "chd[ir]"],
"Change the current directory", "Change the current directory",
function (args) { function (args) {
@@ -517,7 +527,7 @@ var IO = Module("io", {
dactyl.echomsg(io.cwd); dactyl.echomsg(io.cwd);
} }
else { else {
let dirs = options["cdpath"]; let dirs = modules.options["cdpath"];
for (let [, dir] in Iterator(dirs)) { for (let [, dir] in Iterator(dirs)) {
dir = File.joinPaths(dir, arg, io.cwd); dir = File.joinPaths(dir, arg, io.cwd);
@@ -708,9 +718,9 @@ unlet s:cpo_save
commands: wrap("syn keyword " + config.name + "Command ", commands: wrap("syn keyword " + config.name + "Command ",
array(c.specs for (c in commands)).flatten()), array(c.specs for (c in commands)).flatten()),
options: wrap("syn keyword " + config.name + "Option ", options: wrap("syn keyword " + config.name + "Option ",
array(o.names for (o in options) if (o.type != "boolean")).flatten()), array(o.names for (o in modules.options) if (o.type != "boolean")).flatten()),
toggleoptions: wrap("let s:toggleOptions = [", toggleoptions: wrap("let s:toggleOptions = [",
array(o.realNames for (o in options) if (o.type == "boolean")) array(o.realNames for (o in modules.options) if (o.type == "boolean"))
.flatten().map(String.quote), .flatten().map(String.quote),
", ") + "]" ", ") + "]"
})); }));
@@ -734,7 +744,7 @@ unlet s:cpo_save
commands.add(["scrip[tnames]"], commands.add(["scrip[tnames]"],
"List all sourced script names", "List all sourced script names",
function () { function () {
commandline.commandOutput( modules.commandline.commandOutput(
template.tabular(["<SNR>", "Filename"], ["text-align: right; padding-right: 1em;"], template.tabular(["<SNR>", "Filename"], ["text-align: right; padding-right: 1em;"],
([i + 1, file] for ([i, file] in Iterator(io._scriptNames))))); // TODO: add colon and remove column titles for pedantic Vim compatibility? ([i + 1, file] for ([i, file] in Iterator(io._scriptNames))))); // TODO: add colon and remove column titles for pedantic Vim compatibility?
}, },
@@ -768,7 +778,7 @@ unlet s:cpo_save
// This is an asinine and irritating feature when we have searchable // This is an asinine and irritating feature when we have searchable
// command-line history. --Kris // command-line history. --Kris
if (options["banghist"]) { if (modules.options["banghist"]) {
// replaceable bang and no previous command? // replaceable bang and no previous command?
dactyl.assert(!/((^|[^\\])(\\\\)*)!/.test(arg) || io._lastRunCommand, dactyl.assert(!/((^|[^\\])(\\\\)*)!/.test(arg) || io._lastRunCommand,
"E34: No previous command"); "E34: No previous command");
@@ -782,10 +792,10 @@ unlet s:cpo_save
let output = io.system(arg); let output = io.system(arg);
commandline.command = "!" + arg; modules.commandline.command = "!" + arg;
commandline.commandOutput(<span highlight="CmdOutput">{output}</span>); modules.commandline.commandOutput(<span highlight="CmdOutput">{output}</span>);
autocommands.trigger("ShellCmdPost", {}); modules.autocommands.trigger("ShellCmdPost", {});
}, { }, {
argCount: "?", // TODO: "1" - probably not worth supporting weird Vim edge cases. The dream is dead. --djk argCount: "?", // TODO: "1" - probably not worth supporting weird Vim edge cases. The dream is dead. --djk
bang: true, bang: true,
@@ -794,7 +804,9 @@ unlet s:cpo_save
literal: 0 literal: 0
}); });
}, },
completion: function () { completion: function (dactyl, modules, window) {
const { completion, io } = modules;
completion.charset = function (context) { completion.charset = function (context) {
context.anchored = false; context.anchored = false;
context.keys = { context.keys = {
@@ -840,8 +852,8 @@ unlet s:cpo_save
}; };
context.compare = function (a, b) b.isdir - a.isdir || String.localeCompare(a.text, b.text); context.compare = function (a, b) b.isdir - a.isdir || String.localeCompare(a.text, b.text);
if (options["wildignore"]) { if (modules.options["wildignore"]) {
let wig = options.get("wildignore"); let wig = modules.options.get("wildignore");
context.filters.push(function (item) item.isdir || !wig.getKey(this.name)); context.filters.push(function (item) item.isdir || !wig.getKey(this.name));
} }
@@ -881,7 +893,7 @@ unlet s:cpo_save
}; };
completion.runtime = function (context) { completion.runtime = function (context) {
for (let [, dir] in Iterator(options["runtimepath"])) for (let [, dir] in Iterator(modules.options["runtimepath"]))
context.fork(dir, 0, this, function (context) { context.fork(dir, 0, this, function (context) {
dir = dir.replace("/+$", "") + "/"; dir = dir.replace("/+$", "") + "/";
completion.file(context, true, dir + context.filter); completion.file(context, true, dir + context.filter);
@@ -938,15 +950,17 @@ unlet s:cpo_save
completion.file(context, full); completion.file(context, full);
}); });
}, },
javascript: function () { javascript: function (dactyl, modules, window) {
JavaScript.setCompleter([File, File.expandPath], modules.JavaScript.setCompleter([File, File.expandPath],
[function (context, obj, args) { [function (context, obj, args) {
context.quote[2] = ""; context.quote[2] = "";
completion.file(context, true); completion.file(context, true);
}]); }]);
}, },
options: function () { options: function (dactyl, modules, window) {
const { options } = modules;
var shell, shellcmdflag; var shell, shellcmdflag;
if (util.OS.isWindows) { if (util.OS.isWindows) {
shell = "cmd.exe"; shell = "cmd.exe";
@@ -991,6 +1005,8 @@ unlet s:cpo_save
return /sh/.test(options["shell"]) ? "-c" : "/c"; return /sh/.test(options["shell"]) ? "-c" : "/c";
} }
}); });
options["shell"]; // Make sure it's loaded into global storage.
options["shellcmdflag"];
options.add(["wildignore", "wig"], options.add(["wildignore", "wig"],
"List of file patterns to ignore when completing file names", "List of file patterns to ignore when completing file names",
@@ -998,4 +1014,8 @@ unlet s:cpo_save
} }
}); });
// vim: set fdm=marker sw=4 ts=4 et: endModule();
} catch(e){ if (isString(e)) e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
// vim: set fdm=marker sw=4 ts=4 et ft=javascript:

View File

@@ -129,7 +129,9 @@ var Overlay = Module("Overlay", {
} }
}, },
newContext: function newContext(proto) { newContext: function newContext(proto, normal) {
if (normal)
return create(proto);
let sandbox = Components.utils.Sandbox(window, { sandboxPrototype: proto || modules, wantXrays: false }); let sandbox = Components.utils.Sandbox(window, { sandboxPrototype: proto || modules, wantXrays: false });
// Hack: // Hack:
sandbox.Object = jsmodules.Object; sandbox.Object = jsmodules.Object;

View File

@@ -69,11 +69,12 @@ var Services = Module("Services", {
this.addClass("Find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind); this.addClass("Find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind);
this.addClass("HtmlConverter","@mozilla.org/widget/htmlformatconverter;1", Ci.nsIFormatConverter); this.addClass("HtmlConverter","@mozilla.org/widget/htmlformatconverter;1", Ci.nsIFormatConverter);
this.addClass("HtmlEncoder", "@mozilla.org/layout/htmlCopyEncoder;1", Ci.nsIDocumentEncoder); this.addClass("HtmlEncoder", "@mozilla.org/layout/htmlCopyEncoder;1", Ci.nsIDocumentEncoder);
this.addClass("StreamChannel","@mozilla.org/network/input-stream-channel;1", this.addClass("InputStream", "@mozilla.org/scriptableinputstream;1", Ci.nsIScriptableInputStream, "init");
[Ci.nsIChannel, Ci.nsIInputStreamChannel, Ci.nsIRequest], "setURI");
this.addClass("Persist", "@mozilla.org/embedding/browser/nsWebBrowserPersist;1", Ci.nsIWebBrowserPersist); this.addClass("Persist", "@mozilla.org/embedding/browser/nsWebBrowserPersist;1", Ci.nsIWebBrowserPersist);
this.addClass("Pipe", "@mozilla.org/pipe;1", Ci.nsIPipe, "init"); this.addClass("Pipe", "@mozilla.org/pipe;1", Ci.nsIPipe, "init");
this.addClass("Process", "@mozilla.org/process/util;1", Ci.nsIProcess, "init"); this.addClass("Process", "@mozilla.org/process/util;1", Ci.nsIProcess, "init");
this.addClass("StreamChannel","@mozilla.org/network/input-stream-channel;1",
[Ci.nsIChannel, Ci.nsIInputStreamChannel, Ci.nsIRequest], "setURI");
this.addClass("String", "@mozilla.org/supports-string;1", Ci.nsISupportsString, "data"); this.addClass("String", "@mozilla.org/supports-string;1", Ci.nsISupportsString, "data");
this.addClass("StringStream", "@mozilla.org/io/string-input-stream;1", Ci.nsIStringInputStream, "data"); this.addClass("StringStream", "@mozilla.org/io/string-input-stream;1", Ci.nsIStringInputStream, "data");
this.addClass("Timer", "@mozilla.org/timer;1", Ci.nsITimer, "initWithCallback"); this.addClass("Timer", "@mozilla.org/timer;1", Ci.nsITimer, "initWithCallback");

View File

@@ -490,6 +490,21 @@ var File = Class("File", {
defaultEncoding: "UTF-8", defaultEncoding: "UTF-8",
/**
* Expands "~" and environment variables in *path*.
*
* "~" is expanded to to the value of $HOME. On Windows if this is not
* set then the following are tried in order:
* $USERPROFILE
* ${HOMDRIVE}$HOMEPATH
*
* The variable notation is $VAR (terminated by a non-word character)
* or ${VAR}. %VAR% is also supported on Windows.
*
* @param {string} path The unexpanded path string.
* @param {boolean} relative Whether the path is relative or absolute.
* @returns {string}
*/
expandPath: function (path, relative) { expandPath: function (path, relative) {
function getenv(name) services.environment.get(name); function getenv(name) services.environment.get(name);

View File

@@ -59,13 +59,6 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
} }
}, },
addon: Class.memoize(function () {
let addon = services.fuel.storage.get("dactyl.bootstrap", {}).addon;
if (!addon)
addon = AddonManager.getAddonByID(config.addonID);
return addon;
}),
// FIXME: Only works for Pentadactyl // FIXME: Only works for Pentadactyl
get activeWindow() services.windowMediator.getMostRecentWindow("navigator:browser"), get activeWindow() services.windowMediator.getMostRecentWindow("navigator:browser"),
dactyl: update(function dactyl(obj) { dactyl: update(function dactyl(obj) {
@@ -1203,8 +1196,8 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
services.fuel.storage.set("dactyl.commandlineArgs", args); services.fuel.storage.set("dactyl.commandlineArgs", args);
this.timeout(function () { this.timeout(function () {
this.rehashing = true; this.rehashing = true;
this.addon.userDisabled = true; config.addon.userDisabled = true;
this.addon.userDisabled = false; config.addon.userDisabled = false;
}); });
}, },
@@ -1508,6 +1501,6 @@ var Math = update(Object.create(GlobalMath), {
endModule(); endModule();
} catch(e){dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack);} } catch(e){ if (isString(e)) e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
// vim: set fdm=marker sw=4 ts=4 et ft=javascript: // vim: set fdm=marker sw=4 ts=4 et ft=javascript:

View File

@@ -1,15 +0,0 @@
<!ENTITY dactyl.mainWindow "mainplayer">
<!ENTITY dactyl.commandContainer "&dactyl.mainWindow;">
<!ENTITY dactyl.statusBefore "statusbar-display">
<!ENTITY dactyl.statusAfter "">
<!ENTITY dactyl.name "melodactyl">
<!ENTITY dactyl.appName "Melodactyl">
<!ENTITY dactyl.idName "MELODACTYL">
<!ENTITY dactyl.fileExt "melo">
<!ENTITY dactyl.hostbin "songbird">
<!ENTITY % dactylBase SYSTEM "chrome://dactyl/content/base.dtd">
%dactylBase;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/help.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="player" name="player"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,15 +0,0 @@
<!ENTITY dactyl.mainWindow "main-window">
<!ENTITY dactyl.commandContainer "browser-bottombox">
<!ENTITY dactyl.statusBefore "statusbar-display">
<!ENTITY dactyl.statusAfter "">
<!ENTITY dactyl.appName "Pentadactyl">
<!ENTITY dactyl.idName "PENTADACTYL">
<!ENTITY dactyl.name "pentadactyl">
<!ENTITY dactyl.fileExt "penta">
<!ENTITY dactyl.hostbin "firefox">
<!ENTITY % dactylBase SYSTEM "chrome://dactyl/content/base.dtd">
%dactylBase;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE document SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE document SYSTEM "dactyl://content/dtd">
<document <document
name="tutorial" name="tutorial"

View File

@@ -1,9 +0,0 @@
<!ENTITY dactyl.mainWindow "msgcomposeWindow">
<!ENTITY dactyl.name "teledactyl">
<!ENTITY dactyl.statusBefore "">
<!ENTITY dactyl.statusAfter "statusText">
<!ENTITY xmlns.dactyl "http://vimperator.org/namespaces/liberator">
<!ENTITY xmlns.html "http://www.w3.org/1999/xhtml">
<!ENTITY xmlns.xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

View File

@@ -1,15 +0,0 @@
<!ENTITY dactyl.mainWindow "messengerWindow">
<!ENTITY dactyl.commandContainer "&dactyl.mainWindow;">
<!ENTITY dactyl.statusBefore "">
<!ENTITY dactyl.statusAfter "statusTextBox">
<!ENTITY dactyl.name "teledactyl">
<!ENTITY dactyl.idName "TELEDACTYL">
<!ENTITY dactyl.appName "Teledactyl">
<!ENTITY dactyl.hostbin "thunderbird">
<!ENTITY dactyl.fileExt "tele">
<!ENTITY % dactylBase SYSTEM "chrome://dactyl/content/base.dtd">
%dactylBase;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="chrome://dactyl/content/help.xsl"?> <?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>
<!DOCTYPE overlay SYSTEM "chrome://dactyl/content/dactyl.dtd"> <!DOCTYPE overlay SYSTEM "dactyl://content/dtd">
<overlay <overlay
xmlns="&xmlns.dactyl;" xmlns="&xmlns.dactyl;"