mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2026-03-11 08:25:47 +01:00
Allow loading plugins globally.
This commit is contained in:
@@ -128,6 +128,8 @@ let jsmodules = {
|
|||||||
memoize(target || this, name, function (name) require(module)[name]);
|
memoize(target || this, name, function (name) require(module)[name]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
jsmodules.jsmodules = jsmodules;
|
||||||
|
|
||||||
let use = {};
|
let use = {};
|
||||||
let loaded = {};
|
let loaded = {};
|
||||||
let currentModule;
|
let currentModule;
|
||||||
|
|||||||
@@ -8,9 +8,12 @@ try {
|
|||||||
|
|
||||||
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
||||||
defineModule("contexts", {
|
defineModule("contexts", {
|
||||||
exports: ["Contexts", "Group", "contexts"]
|
exports: ["Contexts", "Group", "contexts"],
|
||||||
|
require: ["services", "util"]
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this.lazyRequire("overlay", ["overlay"]);
|
||||||
|
|
||||||
var Const = function Const(val) Class.Property({ enumerable: true, value: val });
|
var Const = function Const(val) Class.Property({ enumerable: true, value: val });
|
||||||
|
|
||||||
var Group = Class("Group", {
|
var Group = Class("Group", {
|
||||||
@@ -85,6 +88,17 @@ var Group = Class("Group", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var Contexts = Module("contexts", {
|
var Contexts = Module("contexts", {
|
||||||
|
init: function () {
|
||||||
|
this.pluginModules = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
cleanup: function () {
|
||||||
|
for each (let module in this.pluginModules)
|
||||||
|
util.trapErrors("cleanup", module);
|
||||||
|
|
||||||
|
this.pluginModules = {};
|
||||||
|
},
|
||||||
|
|
||||||
Local: function Local(dactyl, modules, window) ({
|
Local: function Local(dactyl, modules, window) ({
|
||||||
init: function () {
|
init: function () {
|
||||||
const contexts = this;
|
const contexts = this;
|
||||||
@@ -195,7 +209,7 @@ var Contexts = Module("contexts", {
|
|||||||
|
|
||||||
let name = isPlugin ? file.getRelativeDescriptor(isPlugin).replace(File.PATH_SEP, "-")
|
let name = isPlugin ? file.getRelativeDescriptor(isPlugin).replace(File.PATH_SEP, "-")
|
||||||
: file.leafName;
|
: file.leafName;
|
||||||
let id = name.replace(/\.[^.]*$/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase());
|
let id = util.camelCase(name.replace(/\.[^.]*$/, ""));
|
||||||
|
|
||||||
let contextPath = file.path;
|
let contextPath = file.path;
|
||||||
let self = Set.has(plugins, contextPath) && plugins.contexts[contextPath];
|
let self = Set.has(plugins, contextPath) && plugins.contexts[contextPath];
|
||||||
@@ -205,7 +219,7 @@ var Contexts = Module("contexts", {
|
|||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
if (Set.has(self, "onUnload"))
|
if (Set.has(self, "onUnload"))
|
||||||
self.onUnload();
|
util.trapErrors("onUnload", self);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self = args && !isArray(args) ? args : newContext.apply(null, args || [userContext]);
|
self = args && !isArray(args) ? args : newContext.apply(null, args || [userContext]);
|
||||||
@@ -216,10 +230,16 @@ var Contexts = Module("contexts", {
|
|||||||
|
|
||||||
CONTEXT: Const(self),
|
CONTEXT: Const(self),
|
||||||
|
|
||||||
|
set isGlobalModule(val) {
|
||||||
|
// Hack.
|
||||||
|
if (val)
|
||||||
|
throw Contexts;
|
||||||
|
},
|
||||||
|
|
||||||
unload: Const(function unload() {
|
unload: Const(function unload() {
|
||||||
if (plugins[this.NAME] === this || plugins[this.PATH] === this)
|
if (plugins[this.NAME] === this || plugins[this.PATH] === this)
|
||||||
if (this.onUnload)
|
if (this.onUnload)
|
||||||
this.onUnload();
|
util.trapErrors("onUnload", this);
|
||||||
|
|
||||||
if (plugins[this.NAME] === this)
|
if (plugins[this.NAME] === this)
|
||||||
delete plugins[this.NAME];
|
delete plugins[this.NAME];
|
||||||
@@ -270,6 +290,74 @@ var Contexts = Module("contexts", {
|
|||||||
return this.Context(file, group, [this.modules.userContext, true]);
|
return this.Context(file, group, [this.modules.userContext, true]);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Module: function Module(uri, isPlugin) {
|
||||||
|
const { io, plugins } = this.modules;
|
||||||
|
|
||||||
|
let canonical = uri.spec;
|
||||||
|
if (uri.scheme == "resource")
|
||||||
|
canonical = services["resource:"].resolveURI(uri);
|
||||||
|
|
||||||
|
if (uri instanceof Ci.nsIFileURL)
|
||||||
|
var file = File(uri.file);
|
||||||
|
|
||||||
|
let isPlugin = array.nth(io.getRuntimeDirectories("plugins"),
|
||||||
|
function (dir) dir.contains(file, true),
|
||||||
|
0);
|
||||||
|
|
||||||
|
let name = isPlugin && file && file.getRelativeDescriptor(isPlugin)
|
||||||
|
.replace(File.PATH_SEP, "-");
|
||||||
|
let id = util.camelCase(name.replace(/\.[^.]*$/, ""));
|
||||||
|
|
||||||
|
let self = Set.has(this.pluginModules, canonical) && this.pluginModules[canonical];
|
||||||
|
|
||||||
|
if (!self) {
|
||||||
|
self = Object.create(jsmodules);
|
||||||
|
|
||||||
|
update(self, {
|
||||||
|
NAME: Const(id),
|
||||||
|
|
||||||
|
PATH: Const(file && file.path),
|
||||||
|
|
||||||
|
CONTEXT: Const(self),
|
||||||
|
|
||||||
|
get isGlobalModule() true,
|
||||||
|
set isGlobalModule(val) {
|
||||||
|
util.assert(val, "Loading non-global module as global",
|
||||||
|
false);
|
||||||
|
},
|
||||||
|
|
||||||
|
unload: Const(function unload() {
|
||||||
|
if (contexts.pluginModules[canonical] == this) {
|
||||||
|
if (this.onUnload)
|
||||||
|
util.trapErrors("onUnload", this);
|
||||||
|
|
||||||
|
delete contexts.pluginModules[canonical];
|
||||||
|
}
|
||||||
|
|
||||||
|
for each (let { plugins } in overlay.modules)
|
||||||
|
if (plugins[this.NAME] == this)
|
||||||
|
delete plugins[this.name];
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
JSMLoader.loadSubScript(uri.spec, self, File.defaultEncoding);
|
||||||
|
this.pluginModules[canonical] = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This belongs elsewhere
|
||||||
|
if (isPlugin)
|
||||||
|
Object.defineProperty(plugins, self.NAME, {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
get: function () self,
|
||||||
|
set: function (val) {
|
||||||
|
util.dactyl(val).reportError(FailedAssertion(_("plugin.notReplacingContext", self.NAME), 3, false), true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return self;
|
||||||
|
},
|
||||||
|
|
||||||
context: null,
|
context: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ defineModule("io", {
|
|||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
this.lazyRequire("config", ["config"]);
|
this.lazyRequire("config", ["config"]);
|
||||||
|
this.lazyRequire("contexts", ["Contexts", "contexts"]);
|
||||||
|
|
||||||
// TODO: why are we passing around strings rather than file objects?
|
// TODO: why are we passing around strings rather than file objects?
|
||||||
/**
|
/**
|
||||||
@@ -167,8 +168,14 @@ var IO = Module("io", {
|
|||||||
|
|
||||||
let uri = services.io.newFileURI(file);
|
let uri = services.io.newFileURI(file);
|
||||||
|
|
||||||
// handle pure JavaScript files specially
|
let sourceJSM = function sourceJSM() {
|
||||||
if (/\.js$/.test(filename)) {
|
context = contexts.Module(uri);
|
||||||
|
dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/\.js,$/.test(filename))
|
||||||
|
sourceJSM();
|
||||||
|
else if (/\.js$/.test(filename)) {
|
||||||
try {
|
try {
|
||||||
var context = contexts.Script(file, params.group);
|
var context = contexts.Script(file, params.group);
|
||||||
if (Set.has(this._scriptNames, file.path))
|
if (Set.has(this._scriptNames, file.path))
|
||||||
@@ -178,15 +185,21 @@ var IO = Module("io", {
|
|||||||
dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime);
|
dactyl.triggerObserver("io.source", context, file, file.lastModifiedTime);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
if (e.fileName && !(e instanceof FailedAssertion))
|
if (e == Contexts) { // Hack;
|
||||||
try {
|
context.unload();
|
||||||
e.fileName = util.fixURI(e.fileName);
|
sourceJSM();
|
||||||
if (e.fileName == uri.spec)
|
}
|
||||||
e.fileName = filename;
|
else {
|
||||||
e.echoerr = <>{e.fileName}:{e.lineNumber}: {e}</>;
|
if (e.fileName && !(e instanceof FailedAssertion))
|
||||||
}
|
try {
|
||||||
catch (e) {}
|
e.fileName = util.fixURI(e.fileName);
|
||||||
throw e;
|
if (e.fileName == uri.spec)
|
||||||
|
e.fileName = filename;
|
||||||
|
e.echoerr = <>{e.fileName}:{e.lineNumber}: {e}</>;
|
||||||
|
}
|
||||||
|
catch (e) {}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (/\.css$/.test(filename))
|
else if (/\.css$/.test(filename))
|
||||||
|
|||||||
Reference in New Issue
Block a user