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

Minorish changes.

This commit is contained in:
Kris Maglione
2011-09-03 09:12:13 -04:00
parent 532f2a10ab
commit 91cbb9dacb
14 changed files with 273 additions and 216 deletions

48
common/bootstrap.js vendored
View File

@@ -9,10 +9,7 @@
const NAME = "bootstrap";
const global = this;
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
function module(uri) {
let obj = {};
@@ -29,8 +26,8 @@ const resourceProto = Services.io.getProtocolHandler("resource")
const categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
const manager = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
const BOOTSTRAP_JSM = "resource://dactyl/bootstrap.jsm";
const DISABLE_ACR = "resource://dactyl-content/disable-acr.jsm";
const BOOTSTRAP_JSM = "resource://dactyl/bootstrap.jsm";
const BOOTSTRAP_CONTRACT = "@dactyl.googlecode.com/base/bootstrap";
var JSMLoader = BOOTSTRAP_CONTRACT in Cc && Cc[BOOTSTRAP_CONTRACT].getService().wrappedJSObject.loader;
@@ -206,7 +203,7 @@ function init() {
}
try {
module("resource://dactyl-content/disable-acr.jsm").init(addon.id);
module(DISABLE_ACR).init(addon.id);
}
catch (e) {
reportError(e);
@@ -240,20 +237,21 @@ function init() {
JSMLoader.init(suffix);
JSMLoader.load("base.jsm", global);
if (!(BOOTSTRAP_CONTRACT in Cc))
manager.registerFactory(Components.ID("{f541c8b0-fe26-4621-a30b-e77d21721fb5}"),
"{f541c8b0-fe26-4621-a30b-e77d21721fb5}",
BOOTSTRAP_CONTRACT, {
if (!(BOOTSTRAP_CONTRACT in Cc)) {
let factory = {
classID: Components.ID("{f541c8b0-fe26-4621-a30b-e77d21721fb5}"),
contractID: BOOTSTRAP_CONTRACT,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
instance: {
QueryInterface: XPCOMUtils.generateQI([]),
contractID: BOOTSTRAP_CONTRACT,
wrappedJSObject: {}
},
// Use Sandbox to prevent closure over this scope
createInstance: Cu.evalInSandbox("(function () this.instance)",
// Use Sandbox to prevent closures over this scope
createInstance: Cu.evalInSandbox("(function () this)",
Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].getService()))
});
};
factory.wrappedJSObject = factory;
manager.registerFactory(factory.classID, String(factory.classID),
BOOTSTRAP_CONTRACT, factory);
}
Cc[BOOTSTRAP_CONTRACT].getService().wrappedJSObject.loader = !Cu.unload && JSMLoader;
@@ -271,7 +269,9 @@ function shutdown(data, reason) {
debug("bootstrap: shutdown " + reasonToString(reason));
if (reason != APP_SHUTDOWN) {
try {
module("resource://dactyl-content/disable-acr.jsm").cleanup();
module(DISABLE_ACR).cleanup();
if (Cu.unload)
Cu.unload(DISABLE_ACR);
}
catch (e) {
reportError(e);
@@ -293,8 +293,14 @@ function shutdown(data, reason) {
function uninstall(data, reason) {
debug("bootstrap: uninstall " + reasonToString(reason));
if (reason == ADDON_UNINSTALL)
if (reason == ADDON_UNINSTALL) {
Services.prefs.deleteBranch("extensions.dactyl.");
if (BOOTSTRAP_CONTRACT in Cc) {
let service = Cc[BOOTSTRAP_CONTRACT].getService().wrappedJSObject;
manager.unregisterFactory(service.classID, service);
}
}
}
function reasonToString(reason) {

View File

@@ -1351,7 +1351,7 @@ var CommandLine = Module("commandline", {
if (isObject(arg))
arg = util.objectToString(arg, useColor);
else if (callable(arg))
arg = String(arg);
arg = String.replace(arg, "/* use strict */ \n", "/* use strict */ ");
else if (!isString(arg) && useColor)
arg = template.highlight(arg);
return arg;

View File

@@ -737,120 +737,6 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
return UTF8(xml.toXMLString());
},
exportHelp: JavaScript.setCompleter(function (path) {
const FILE = io.File(path);
const PATH = FILE.leafName.replace(/\..*/, "") + "/";
const TIME = Date.now();
if (!FILE.exists() && (/\/$/.test(path) && !/\./.test(FILE.leafName)))
FILE.create(FILE.DIRECTORY_TYPE, octal(755));
dactyl.initHelp();
if (FILE.isDirectory()) {
var addDataEntry = function addDataEntry(file, data) FILE.child(file).write(data);
var addURIEntry = function addURIEntry(file, uri) addDataEntry(file, util.httpGet(uri).responseText);
}
else {
var zip = services.ZipWriter();
zip.open(FILE, File.MODE_CREATE | File.MODE_WRONLY | File.MODE_TRUNCATE);
addURIEntry = function addURIEntry(file, uri)
zip.addEntryChannel(PATH + file, TIME, 9,
services.io.newChannel(uri, null, null), false);
addDataEntry = function addDataEntry(file, data) // Unideal to an extreme.
addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data));
}
let empty = Set("area base basefont br col frame hr img input isindex link meta param"
.split(" "));
function fix(node) {
switch(node.nodeType) {
case Node.ELEMENT_NODE:
if (isinstance(node, [HTMLBaseElement]))
return;
data.push("<"); data.push(node.localName);
if (node instanceof HTMLHtmlElement)
data.push(" xmlns=" + XHTML.uri.quote(),
" xmlns:dactyl=" + NS.uri.quote());
for (let { name, value } in array.iterValues(node.attributes)) {
if (name == "dactyl:highlight") {
Set.add(styles, value);
name = "class";
value = "hl-" + value;
}
if (name == "href") {
value = node.href || value;
if (value.indexOf("dactyl://help-tag/") == 0) {
let uri = services.io.newChannel(value, null, null).originalURI;
value = uri.spec == value ? "javascript:;" : uri.path.substr(1);
}
if (!/^#|[\/](#|$)|^[a-z]+:/.test(value))
value = value.replace(/(#|$)/, ".xhtml$1");
}
if (name == "src" && value.indexOf(":") > 0) {
chromeFiles[value] = value.replace(/.*\//, "");
value = value.replace(/.*\//, "");
}
data.push(" ", name, '="',
<>{value}</>.toXMLString().replace(/"/g, "&quot;"),
'"');
}
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, fix);
data.push("</", node.localName, ">");
}
break;
case Node.TEXT_NODE:
data.push(<>{node.textContent}</>.toXMLString());
}
}
let chromeFiles = {};
let styles = {};
for (let [file, ] in Iterator(help.files)) {
let url = "dactyl://help/" + file;
dactyl.open(url);
util.waitFor(function () content.location.href == url && buffer.loaded
&& content.document.documentElement instanceof HTMLHtmlElement,
15000);
events.waitForPageLoad();
var 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'
];
fix(content.document.documentElement);
addDataEntry(file + ".xhtml", data.join(""));
}
let data = [h for (h in highlight) if (Set.has(styles, h.class) || /^Help/.test(h.class))]
.map(function (h) h.selector
.replace(/^\[.*?=(.*?)\]/, ".hl-$1")
.replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}")
.join("\n");
addDataEntry("help.css", data.replace(/chrome:[^ ")]+\//g, ""));
addDataEntry("tag-map.json", JSON.stringify(help.tags));
let m, re = /(chrome:[^ ");]+\/)([^ ");]+)/g;
while ((m = re.exec(data)))
chromeFiles[m[0]] = m[2];
for (let [uri, leaf] in Iterator(chromeFiles))
addURIEntry(leaf, uri);
if (zip)
zip.close();
}, [function (context, args) completion.file(context)]),
/**
* Generates a help entry and returns it as a string.
*

View File

@@ -381,7 +381,7 @@ var EventHive = Class("EventHive", Contexts.Hive, {
*/
unlisten: function (target, event, callback, capture) {
this.sessionListeners = this.sessionListeners.filter(function (args) {
if (target == null || args[0].get() == target && args[1] == event && args[2] == callback && args[3] == capture) {
if (target == null || args[0].get() == target && args[1] == event && args[2].wrapped == callback && args[3] == capture) {
args[0].get().removeEventListener.apply(args[0].get(), args.slice(1));
return false;
}
@@ -1161,7 +1161,7 @@ var Events = Module("events", {
let win = (elem.ownerDocument || elem).defaultView || elem;
if (!(services.focus.getLastFocusMethod(win) & 0x7000)
if (!(services.focus.getLastFocusMethod(win) & 0x3000)
&& events.isContentNode(elem)
&& !buffer.focusAllowed(elem)
&& isinstance(elem, [HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement, Window])) {

View File

@@ -110,6 +110,7 @@ var actions = {
description: "Reload an extension",
action: function (addon) {
util.assert(config.haveGecko("2b"), _("command.notUseful", config.host));
util.flushCache();
util.timeout(function () {
addon.userDisabled = true;
addon.userDisabled = false;

View File

@@ -216,9 +216,9 @@ function require(obj, name, from, targetName) {
}
defineModule("base", {
// sed -n 's/^(const|function) ([a-zA-Z0-9_]+).*/ "\2",/p' base.jsm | sort | fmt
// sed -n 's/^(const|var|function) ([a-zA-Z0-9_]+).*/ "\2",/p' base.jsm | sort | fmt
exports: [
"ErrorBase", "Cc", "Ci", "Class", "Cr", "Cu", "Module", "JSMLoader", "Object", "Runnable",
"ErrorBase", "Cc", "Ci", "Class", "Cr", "Cu", "Module", "JSMLoader", "Object",
"Set", "Struct", "StructBase", "Timer", "UTF8", "XPCOM", "XPCOMShim", "XPCOMUtils",
"XPCSafeJSObjectWrapper", "array", "bind", "call", "callable", "ctypes", "curry",
"debuggerProperties", "defineModule", "deprecated", "endModule", "forEach", "isArray",
@@ -228,14 +228,6 @@ defineModule("base", {
]
}, this);
function Runnable(self, func, args) {
return {
__proto__: Runnable.prototype,
run: function () { func.apply(self, args || []); }
};
}
Runnable.prototype.QueryInterface = XPCOMUtils.generateQI([Ci.nsIRunnable]);
/**
* Returns a list of all of the top-level properties of an object, by
* way of the debugger.
@@ -845,7 +837,7 @@ Class.extend = function extend(subclass, superclass, overrides) {
* property's value.
* @returns {Class.Property}
*/
Class.Memoize = Class.Memoize = function Memoize(getter, wait)
Class.Memoize = function Memoize(getter, wait)
Class.Property({
configurable: true,
enumerable: true,
@@ -887,6 +879,8 @@ Class.Memoize = Class.Memoize = function Memoize(getter, wait)
}
});
Class.memoize = deprecated("Class.Memoize", function memoize() Class.Memoize.apply(this, arguments));
/**
* Updates the given object with the object in the target class's
* prototype.
@@ -1184,7 +1178,7 @@ function Struct() {
});
return Struct;
}
let StructBase = Class("StructBase", Array, {
var StructBase = Class("StructBase", Array, {
init: function struct_init() {
for (let i = 0; i < arguments.length; i++)
if (arguments[i] != undefined)

View File

@@ -275,9 +275,9 @@ var ConfigBase = Class("ConfigBase", {
/** @property {boolean} True if the OS is Mac OS X. */
get isMacOSX() this._arch == "Darwin",
/** @property {boolean} True if the OS is some other *nix variant. */
get isUnix() !this.isWindows && !this.isMacOSX,
get isUnix() !this.isWindows,
/** @property {RegExp} A RegExp which matches illegal characters in path components. */
get illegalCharacters() this.isWindows ? /[<>:"/\\|?*\x00-\x1f]/g : /\//g,
get illegalCharacters() this.isWindows ? /[<>:"/\\|?*\x00-\x1f]/g : /[\/\x00]/g,
get pathListSep() this.isWindows ? ";" : ":"
}),

View File

@@ -669,7 +669,7 @@ var DOM = Class("DOM", {
val: function val(txt) {
return this.getSet(arguments,
function (elem) elem.value,
function (elem, val) { elem.value = val });
function (elem, val) { elem.value = val == null ? "" : val });
},
listen: function listen(event, listener, capture) {
@@ -1094,3 +1094,6 @@ var $ = DOM;
endModule();
// catch(e){ if (!e.stack) e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
// vim: set sw=4 ts=4 et ft=javascript:

View File

@@ -7,7 +7,7 @@
Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("help", {
exports: ["help"],
require: ["dom", "protocol", "services", "util"]
require: ["dom", "javascript", "protocol", "services", "util"]
}, this);
var Help = Module("Help", {
@@ -95,7 +95,120 @@ var Help = Module("Help", {
dactyl.assert(page != null, _("help.noTopic", topic));
dactyl.open("dactyl://help/" + page, { from: "help" });
}
},
exportHelp: JavaScript.setCompleter(function (path) {
const FILE = io.File(path);
const PATH = FILE.leafName.replace(/\..*/, "") + "/";
const TIME = Date.now();
if (!FILE.exists() && (/\/$/.test(path) && !/\./.test(FILE.leafName)))
FILE.create(FILE.DIRECTORY_TYPE, octal(755));
dactyl.initHelp();
if (FILE.isDirectory()) {
var addDataEntry = function addDataEntry(file, data) FILE.child(file).write(data);
var addURIEntry = function addURIEntry(file, uri) addDataEntry(file, util.httpGet(uri).responseText);
}
else {
var zip = services.ZipWriter(FILE, File.MODE_CREATE | File.MODE_WRONLY | File.MODE_TRUNCATE);
addURIEntry = function addURIEntry(file, uri)
zip.addEntryChannel(PATH + file, TIME, 9,
services.io.newChannel(uri, null, null), false);
addDataEntry = function addDataEntry(file, data) // Unideal to an extreme.
addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data));
}
let empty = Set("area base basefont br col frame hr img input isindex link meta param"
.split(" "));
function fix(node) {
switch(node.nodeType) {
case Node.ELEMENT_NODE:
if (isinstance(node, [HTMLBaseElement]))
return;
data.push("<"); data.push(node.localName);
if (node instanceof HTMLHtmlElement)
data.push(" xmlns=" + XHTML.uri.quote(),
" xmlns:dactyl=" + NS.uri.quote());
for (let { name, value } in array.iterValues(node.attributes)) {
if (name == "dactyl:highlight") {
Set.add(styles, value);
name = "class";
value = "hl-" + value;
}
if (name == "href") {
value = node.href || value;
if (value.indexOf("dactyl://help-tag/") == 0) {
let uri = services.io.newChannel(value, null, null).originalURI;
value = uri.spec == value ? "javascript:;" : uri.path.substr(1);
}
if (!/^#|[\/](#|$)|^[a-z]+:/.test(value))
value = value.replace(/(#|$)/, ".xhtml$1");
}
if (name == "src" && value.indexOf(":") > 0) {
chromeFiles[value] = value.replace(/.*\//, "");
value = value.replace(/.*\//, "");
}
data.push(" ", name, '="',
<>{value}</>.toXMLString().replace(/"/g, "&quot;"),
'"');
}
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, fix);
data.push("</", node.localName, ">");
}
break;
case Node.TEXT_NODE:
data.push(<>{node.textContent}</>.toXMLString());
}
}
let chromeFiles = {};
let styles = {};
for (let [file, ] in Iterator(help.files)) {
let url = "dactyl://help/" + file;
dactyl.open(url);
util.waitFor(function () content.location.href == url && buffer.loaded
&& content.document.documentElement instanceof HTMLHtmlElement,
15000);
events.waitForPageLoad();
var 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'
];
fix(content.document.documentElement);
addDataEntry(file + ".xhtml", data.join(""));
}
let data = [h for (h in highlight) if (Set.has(styles, h.class) || /^Help/.test(h.class))]
.map(function (h) h.selector
.replace(/^\[.*?=(.*?)\]/, ".hl-$1")
.replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}")
.join("\n");
addDataEntry("help.css", data.replace(/chrome:[^ ")]+\//g, ""));
addDataEntry("tag-map.json", JSON.stringify(help.tags));
let m, re = /(chrome:[^ ");]+\/)([^ ");]+)/g;
while ((m = re.exec(data)))
chromeFiles[m[0]] = m[2];
for (let [uri, leaf] in Iterator(chromeFiles))
addURIEntry(leaf, uri);
if (zip)
zip.close();
}, [function (context, args) completion.file(context)]),
}),

View File

@@ -37,6 +37,10 @@ var Messages = Module("messages", {
});
},
cleanup: function cleanup() {
services.stringBundle.flushBundles();
},
bundles: Class.Memoize(function ()
array.uniq([JSMLoader.getTarget("dactyl://locale/" + this.name + ".properties"),
JSMLoader.getTarget("dactyl://locale-local/" + this.name + ".properties"),
@@ -53,10 +57,6 @@ var Messages = Module("messages", {
yield [key, value];
},
cleanup: function cleanup() {
services.stringBundle.flushBundles();
},
get: function get(value, default_) {
for (let bundle in values(this.bundles))
try {
@@ -136,10 +136,7 @@ var Messages = Module("messages", {
}, {
javascript: function initJavascript(dactyl, modules, window) {
modules.JavaScript.setCompleter([this._, this.get, this.format], [
function (context) {
context.keys = { text: "key", description: "value" };
return messages.iterate();
}
function (context) messages.iterate()
]);
}
});

View File

@@ -189,7 +189,7 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
var { modules, Module } = window.dactyl.modules;
delete window.dactyl;
const start = Date.now();
this.startTime = Date.now();
const deferredInit = { load: {} };
const seen = Set();
const loaded = Set();
@@ -268,6 +268,8 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
});
function frob(name) { values(deferredInit[name] || {}).forEach(call); }
this.frob = frob;
this.modules = modules;
frobModules();
frob("init");
@@ -289,21 +291,6 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
});
});
function finish() {
// Module.list.forEach(load);
frob("load");
modules.times = update({}, defineModule.times);
defineModule.loadLog.push("Loaded in " + (Date.now() - start) + "ms");
overlay.windows = array.uniq(overlay.windows.concat(window), true);
}
if (overlay.onWindowVisible)
overlay.onWindowVisible.push(finish);
else
finish();
modules.events.listen(window, "unload", function onUnload() {
window.removeEventListener("unload", onUnload.wrapped, false);
@@ -316,12 +303,21 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
util.trapErrors("destroy", mod);
}
}, false);
},
visible: function visible(window) {
// Module.list.forEach(load);
this.frob("load");
this.modules.times = update({}, defineModule.times);
defineModule.loadLog.push("Loaded in " + (Date.now() - this.startTime) + "ms");
overlay.windows = array.uniq(overlay.windows.concat(window), true);
}
}));
},
cleanup: function cleanup() {
for (let { document: doc } in iter(services.windowMediator.getEnumerator(null))) {
for (let doc in util.iterDocuments()) {
for (let elem in values(doc.dactylOverlayElements || []))
if (elem.parentNode)
elem.parentNode.removeChild(elem);
@@ -348,10 +344,9 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
"chrome-document-global-created": function (window, uri) { this.observe(window, "toplevel-window-ready", null); },
"content-document-global-created": function (window, uri) { this.observe(window, "toplevel-window-ready", null); },
"xul-window-visible": function () {
if (this.onWindowVisible) {
if (this.onWindowVisible)
this.onWindowVisible.forEach(function (f) f.call(this), this);
this.onWindowVisible = null;
}
this.onWindowVisible = null;
}
},
@@ -367,11 +362,14 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
for (let doc in util.iterDocuments())
if (~["interactive", "complete"].indexOf(doc.readyState)) {
this.onWindowVisible = null;
this.observe(doc.defaultView, "xul-window-visible");
this._loadOverlays(doc.defaultView);
}
else
else {
if (!this.onWindowVisible)
this.onWindowVisible = [];
this.observe(doc.defaultView, "toplevel-window-ready");
}
}
},
@@ -394,7 +392,7 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
doc.dactylOverlayAttributes = [];
}
function overlay(key, fn) {
function insert(key, fn) {
if (obj[key]) {
let iterator = Iterator(obj[key]);
if (!isObject(obj[key]))
@@ -423,21 +421,30 @@ var Overlay = Module("Overlay", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReferen
}
}
overlay("before", function (elem, dom) elem.parentNode.insertBefore(dom, elem));
overlay("after", function (elem, dom) elem.parentNode.insertBefore(dom, elem.nextSibling));
overlay("append", function (elem, dom) elem.appendChild(dom));
overlay("prepend", function (elem, dom) elem.insertBefore(dom, elem.firstChild));
insert("before", function (elem, dom) elem.parentNode.insertBefore(dom, elem));
insert("after", function (elem, dom) elem.parentNode.insertBefore(dom, elem.nextSibling));
insert("append", function (elem, dom) elem.appendChild(dom));
insert("prepend", function (elem, dom) elem.insertBefore(dom, elem.firstChild));
if (obj.init)
obj.init(window);
function load(event) {
obj.load(window, event);
if (obj.visible)
if (!event || !overlay.onWindowVisible || window != util.topWindow(window))
obj.visible(window);
else
overlay.onWindowVisible.push(function () { obj.visible(window) });
}
if (obj.load)
if (doc.readyState === "complete")
obj.load(window);
load();
else
doc.addEventListener("load", util.wrapCallback(function load(event) {
doc.addEventListener("load", util.wrapCallback(function onLoad(event) {
if (event.originalTarget === event.target) {
doc.removeEventListener("load", load.wrapper, true);
obj.load(window, event);
doc.removeEventListener("load", onLoad.wrapper, true);
load(event);
}
}), true);
},

View File

@@ -70,7 +70,10 @@ var Services = Module("Services", {
this.add("zipReader", "@mozilla.org/libjar/zip-reader-cache;1", "nsIZipReaderCache");
this.addClass("CharsetConv", "@mozilla.org/intl/scriptableunicodeconverter", "nsIScriptableUnicodeConverter", "charset");
this.addClass("CharsetStream","@mozilla.org/intl/converter-input-stream;1", ["nsIConverterInputStream",
"nsIUnicharLineInputStream"], "init");
this.addClass("File", "@mozilla.org/file/local;1", "nsILocalFile");
this.addClass("FileInStream", "@mozilla.org/network/file-input-stream;1", "nsIFileInputStream", "init", false);
this.addClass("Find", "@mozilla.org/embedcomp/rangefind;1", "nsIFind");
this.addClass("HtmlConverter","@mozilla.org/widget/htmlformatconverter;1", "nsIFormatConverter");
this.addClass("HtmlEncoder", "@mozilla.org/layout/htmlCopyEncoder;1", "nsIDocumentEncoder");
@@ -79,6 +82,7 @@ var Services = Module("Services", {
this.addClass("Persist", "@mozilla.org/embedding/browser/nsWebBrowserPersist;1", "nsIWebBrowserPersist");
this.addClass("Pipe", "@mozilla.org/pipe;1", "nsIPipe", "init");
this.addClass("Process", "@mozilla.org/process/util;1", "nsIProcess", "init");
this.addClass("Pump", "@mozilla.org/network/input-stream-pump;1", "nsIInputStreamPump", "init")
this.addClass("StreamChannel","@mozilla.org/network/input-stream-channel;1",
["nsIInputStreamChannel", "nsIChannel"], "setURI");
this.addClass("StreamCopier", "@mozilla.org/network/async-stream-copier;1","nsIAsyncStreamCopier", "init");
@@ -91,7 +95,7 @@ var Services = Module("Services", {
this.addClass("XPathEvaluator", "@mozilla.org/dom/xpath-evaluator;1", "nsIDOMXPathEvaluator");
this.addClass("XMLDocument", "@mozilla.org/xml/xml-document;1", ["nsIDOMXMLDocument", "nsIDOMNodeSelector"]);
this.addClass("ZipReader", "@mozilla.org/libjar/zip-reader;1", "nsIZipReader", "open");
this.addClass("ZipWriter", "@mozilla.org/zipwriter;1", "nsIZipWriter");
this.addClass("ZipWriter", "@mozilla.org/zipwriter;1", "nsIZipWriter", "open");
},
reinit: function () {},
@@ -112,7 +116,7 @@ var Services = Module("Services", {
}
return res;
}
catch (e) {
catch (e if service.quiet !== false) {
if (typeof util !== "undefined")
util.reportError(e);
else
@@ -149,9 +153,9 @@ var Services = Module("Services", {
* @param {string} init Name of a property or method used to initialize the
* class.
*/
addClass: function (name, class_, ifaces, init) {
addClass: function (name, class_, ifaces, init, quiet) {
const self = this;
this.services[name] = { class: class_, interfaces: Array.concat(ifaces || []), method: "createInstance", init: init };
this.services[name] = { class: class_, interfaces: Array.concat(ifaces || []), method: "createInstance", init: init, quiet: quiet };
if (init)
memoize(this.services[name], "callable",
function () callable(XPCOMShim(this.interfaces)[this.init]));

View File

@@ -292,11 +292,18 @@ var Storage = Module("Storage", {
* @param {nsIFile|string} path Expanded according to {@link IO#expandPath}
* @param {boolean} checkPWD Whether to allow expansion relative to the
* current directory. @default true
* @param {string} charset The charset of the file. @default File.defaultEncoding
*/
this.File = Class("File", {
init: function (path, checkPWD) {
init: function (path, checkPWD, charset) {
let file = services.File();
if (charset)
this.charset = charset;
if (path instanceof Ci.nsIFileURL)
path = path.file;
if (path instanceof Ci.nsIFile)
file = path.clone();
else if (/file:\/\//.test(path))
@@ -320,10 +327,12 @@ this.File = Class("File", {
return self;
},
charset: Class.Memoize(function () File.defaultEncoding),
/**
* @property {nsIFileURL} Returns the nsIFileURL object for this file.
*/
get URI() services.io.newFileURI(this),
get URI() services.io.newFileURI(this).QueryInterface(Ci.nsIFileURL),
/**
* Iterates over the objects in this directory.
@@ -347,19 +356,24 @@ this.File = Class("File", {
return f;
},
/**
* Returns an iterator for all lines in a file.
*/
get lines() File.readLines(services.FileInStream(this, -1, 0, 0),
this.charset),
/**
* Reads this file's entire contents in "text" mode and returns the
* content as a string.
*
* @param {string} encoding The encoding from which to decode the file.
* @default options["fileencoding"]
* @default #charset
* @returns {string}
*/
read: function (encoding) {
let ifstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
ifstream.init(this, -1, 0, 0);
let ifstream = services.FileInStream(this, -1, 0, 0);
return File.readStream(ifstream, encoding);
return File.readStream(ifstream, encoding || this.charset);
},
/**
@@ -408,7 +422,7 @@ this.File = Class("File", {
* permissions if the file exists.
* @default 0644
* @param {string} encoding The encoding to used to write the file.
* @default options["fileencoding"]
* @default #charset
*/
write: function (buf, mode, perms, encoding) {
let ofstream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
@@ -421,7 +435,7 @@ this.File = Class("File", {
buf = buf.read();
if (!encoding)
encoding = File.defaultEncoding;
encoding = this.charset;
if (mode == ">>")
mode = File.MODE_WRONLY | File.MODE_CREATE | File.MODE_APPEND;
@@ -579,9 +593,10 @@ this.File = Class("File", {
readStream: function (ifstream, encoding) {
try {
var icstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
icstream.init(ifstream, encoding || File.defaultEncoding, 4096, // 4096 bytes buffering
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
var icstream = services.CharsetStream(
ifstream, encoding || File.defaultEncoding, 4096, // buffer size
services.CharsetStream.DEFAULT_REPLACEMENT_CHARACTER);
let buffer = [];
let str = {};
while (icstream.readString(4096, str) != 0)
@@ -594,6 +609,23 @@ this.File = Class("File", {
}
},
readLines: function (ifstream, encoding) {
try {
var icstream = services.CharsetStream(
ifstream, encoding || File.defaultEncoding, 4096, // buffer size
services.CharsetStream.DEFAULT_REPLACEMENT_CHARACTER);
var value = {};
while (icstream.readLine(value))
yield value.value;
}
finally {
icstream.close();
ifstream.close();
}
},
isAbsolutePath: function (path) {
try {
services.File().initWithPath(path);

View File

@@ -8,7 +8,6 @@
try {
let global=this;
Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("util", {
exports: ["DOM", "$", "FailedAssertion", "Math", "NS", "Point", "Util", "XBL", "XHTML", "XUL", "util"],
@@ -399,7 +398,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
*/
createURI: function createURI(str) {
try {
return services.urifixup.createFixupURI(str, services.urifixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP);
let uri = services.urifixup.createFixupURI(str, services.urifixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP);
uri instanceof Ci.nsIURL;
return uri;
}
catch (e) {
return null;
@@ -673,6 +674,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
if (params.mimeType)
xmlhttp.overrideMimeType(params.mimeType);
if (params.responseType)
xmlhttp.responseType = params.responseType;
xmlhttp.open(params.method || "GET", url, async,
params.user, params.pass);
@@ -748,11 +752,14 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* Iterates over all currently open documents, including all
* top-level window and sub-frames thereof.
*/
iterDocuments: function iterDocuments() {
iterDocuments: function iterDocuments(types) {
types = types ? types.map(function (s) "type" + util.capitalize(s))
: ["typeChrome", "typeContent"];
let windows = services.windowMediator.getXULWindowEnumerator(null);
while (windows.hasMoreElements()) {
let window = windows.getNext().QueryInterface(Ci.nsIXULWindow);
for each (let type in ["typeChrome", "typeContent"]) {
for each (let type in types) {
let docShells = window.docShell.getDocShellEnumerator(Ci.nsIDocShellTreeItem[type],
Ci.nsIDocShell.ENUMERATE_FORWARDS);
while (docShells.hasMoreElements())
@@ -820,7 +827,11 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
* @param {string} uri
* @returns {nsIURI}
*/
newURI: function newURI(uri, charset, base) this.withProperErrors("newURI", services.io, uri, charset, base),
newURI: function newURI(uri, charset, base) {
let res = this.withProperErrors("newURI", services.io, uri, charset, base);
res instanceof Ci.nsIURL;
return res;
},
/**
* Removes leading garbage prepended to URIs by the subscript
@@ -1133,8 +1144,11 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
if (isString(error))
error = Error(error);
if (Cu.reportError)
Cu.reportError(error);
Cu.reportError(error);
try {
services.console.logStringMessage(error.stack || Error().stack);
}
catch (e) {}
try {
this.errorCount++;