mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2026-02-06 11:25:46 +01:00
Move some event-based code into observers in the modules it affects.
This commit is contained in:
@@ -26,9 +26,7 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase),
|
||||
observers: {
|
||||
"chrome-document-global-created": function (win, uri) { this.observe(win, "content-document-global-created", uri); },
|
||||
"content-document-global-created": function (win, uri) {
|
||||
let top = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
|
||||
let top = util.topWindow(win);
|
||||
|
||||
if (top == window)
|
||||
this._triggerLoadAutocmd("PageLoadPre", win.document, win.location.href != "null" ? window.location.href : uri);
|
||||
@@ -101,10 +99,10 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase),
|
||||
// STATE_IS_DOCUMENT | STATE_IS_WINDOW is important, because we also
|
||||
// receive statechange events for loading images and other parts of the web page
|
||||
if (flags & (Ci.nsIWebProgressListener.STATE_IS_DOCUMENT | Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
|
||||
dactyl.applyTriggerObserver("browser.stateChange", arguments);
|
||||
// This fires when the load event is initiated
|
||||
// only thrown for the current tab, not when another tab changes
|
||||
if (flags & Ci.nsIWebProgressListener.STATE_START) {
|
||||
statusline.progress = 0;
|
||||
while (document.commandDispatcher.focusedWindow == webProgress.DOMWindow
|
||||
&& modes.have(modes.INPUT))
|
||||
modes.pop();
|
||||
@@ -115,48 +113,29 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase),
|
||||
config.browser.mCurrentBrowser.collapsed = false;
|
||||
if (!dactyl.focusedElement || dactyl.focusedElement === document.documentElement)
|
||||
dactyl.focusContent();
|
||||
statusline.updateUrl();
|
||||
}
|
||||
}
|
||||
}),
|
||||
// for notifying the user about secure web pages
|
||||
onSecurityChange: util.wrapCallback(function onSecurityChange(webProgress, request, state) {
|
||||
onSecurityChange.superapply(this, arguments);
|
||||
if (state & Ci.nsIWebProgressListener.STATE_IS_BROKEN)
|
||||
statusline.security = "broken";
|
||||
else if (state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL)
|
||||
statusline.security = "extended";
|
||||
else if (state & Ci.nsIWebProgressListener.STATE_SECURE_HIGH)
|
||||
statusline.security = "secure";
|
||||
else // if (state & Ci.nsIWebProgressListener.STATE_IS_INSECURE)
|
||||
statusline.security = "insecure";
|
||||
if (webProgress && webProgress.DOMWindow)
|
||||
webProgress.DOMWindow.document.dactylSecurity = statusline.security;
|
||||
dactyl.applyTriggerObserver("browser.securityChange", arguments);
|
||||
}),
|
||||
onStatusChange: util.wrapCallback(function onStatusChange(webProgress, request, status, message) {
|
||||
onStatusChange.superapply(this, arguments);
|
||||
statusline.updateUrl(message);
|
||||
dactyl.applyTriggerObserver("browser.statusChange", arguments);
|
||||
}),
|
||||
onProgressChange: util.wrapCallback(function onProgressChange(webProgress, request, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress) {
|
||||
onProgressChange.superapply(this, arguments);
|
||||
if (webProgress && webProgress.DOMWindow)
|
||||
webProgress.DOMWindow.dactylProgress = curTotalProgress / maxTotalProgress;
|
||||
statusline.progress = curTotalProgress / maxTotalProgress;
|
||||
dactyl.applyTriggerObserver("browser.progressChange", arguments);
|
||||
}),
|
||||
// happens when the users switches tabs
|
||||
onLocationChange: util.wrapCallback(function onLocationChange(webProgress, request, uri) {
|
||||
onLocationChange.superapply(this, arguments);
|
||||
|
||||
contexts.flush();
|
||||
options.get("passkeys").flush();
|
||||
|
||||
statusline.updateUrl();
|
||||
statusline.progress = "";
|
||||
dactyl.applyTriggerObserver("browser.locationChange", arguments);
|
||||
|
||||
let win = webProgress.DOMWindow;
|
||||
if (win && uri) {
|
||||
statusline.progress = win.dactylProgress;
|
||||
|
||||
let oldURI = win.document.dactylURI;
|
||||
if (win.document.dactylLoadIdx === webProgress.loadedTransIndex
|
||||
|| !oldURI || uri.spec.replace(/#.*/, "") !== oldURI.replace(/#.*/, ""))
|
||||
@@ -177,14 +156,6 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase),
|
||||
(win || content).document,
|
||||
uri);
|
||||
});
|
||||
|
||||
// if this is not delayed we get the position of the old buffer
|
||||
util.timeout(function () {
|
||||
statusline.updateBufferPosition();
|
||||
statusline.updateZoomLevel();
|
||||
if (loaded.commandline)
|
||||
commandline.clear();
|
||||
}, 500);
|
||||
}),
|
||||
// called at the very end of a page load
|
||||
asyncUpdateUI: util.wrapCallback(function asyncUpdateUI() {
|
||||
@@ -193,26 +164,37 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase),
|
||||
}),
|
||||
setOverLink: util.wrapCallback(function setOverLink(link, b) {
|
||||
setOverLink.superapply(this, arguments);
|
||||
switch (options["showstatuslinks"]) {
|
||||
case "status":
|
||||
statusline.updateUrl(link ? _("status.link", link) : null);
|
||||
break;
|
||||
case "command":
|
||||
if (link)
|
||||
dactyl.echo(_("status.link", link),
|
||||
commandline.DISALLOW_MULTILINE);
|
||||
else
|
||||
commandline.clear();
|
||||
break;
|
||||
}
|
||||
dactyl.triggerObserver("browser.overLink", link);
|
||||
}),
|
||||
}
|
||||
}, {
|
||||
}, {
|
||||
events: function () {
|
||||
events: function initEvents(dactyl, modules, window) {
|
||||
events.listen(config.browser, browser, "events", true);
|
||||
},
|
||||
mappings: function () {
|
||||
commands: function initCommands(dactyl, modules, window) {
|
||||
commands.add(["o[pen]"],
|
||||
"Open one or more URLs in the current tab",
|
||||
function (args) { dactyl.open(args[0] || "about:blank"); },
|
||||
{
|
||||
completer: function (context) completion.url(context),
|
||||
domains: function (args) array.compact(dactyl.parseURLs(args[0] || "").map(
|
||||
function (url) util.getHost(url))),
|
||||
literal: 0,
|
||||
privateData: true
|
||||
});
|
||||
|
||||
commands.add(["redr[aw]"],
|
||||
"Redraw the screen",
|
||||
function () {
|
||||
window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils)
|
||||
.redraw();
|
||||
statusline.updateUrl();
|
||||
commandline.clear();
|
||||
},
|
||||
{ argCount: "0" });
|
||||
},
|
||||
mappings: function initMappings(dactyl, modules, window) {
|
||||
// opening websites
|
||||
mappings.add([modes.NORMAL],
|
||||
["o"], "Open one or more URLs",
|
||||
@@ -256,29 +238,6 @@ var Browser = Module("browser", XPCOM(Ci.nsISupportsWeakReference, ModuleBase),
|
||||
mappings.add([modes.MAIN], ["<C-l>"],
|
||||
"Redraw the screen",
|
||||
function () { ex.redraw(); });
|
||||
},
|
||||
|
||||
commands: function () {
|
||||
commands.add(["o[pen]"],
|
||||
"Open one or more URLs in the current tab",
|
||||
function (args) { dactyl.open(args[0] || "about:blank"); },
|
||||
{
|
||||
completer: function (context) completion.url(context),
|
||||
domains: function (args) array.compact(dactyl.parseURLs(args[0] || "").map(
|
||||
function (url) util.getHost(url))),
|
||||
literal: 0,
|
||||
privateData: true
|
||||
});
|
||||
|
||||
commands.add(["redr[aw]"],
|
||||
"Redraw the screen",
|
||||
function () {
|
||||
window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils)
|
||||
.redraw();
|
||||
statusline.updateUrl();
|
||||
commandline.clear();
|
||||
},
|
||||
{ argCount: "0" });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -515,6 +515,12 @@ var CommandLine = Module("commandline", {
|
||||
}; //}}}
|
||||
},
|
||||
|
||||
signals: {
|
||||
"browser.locationChange": function (webProgress, request, uri) {
|
||||
this.clear();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines whether the command line should be visible.
|
||||
*
|
||||
|
||||
@@ -61,19 +61,15 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
|
||||
"dactyl-cleanup": function dactyl_cleanup() {
|
||||
let modules = dactyl.modules;
|
||||
|
||||
let mods = Object.getOwnPropertyNames(modules).reverse()
|
||||
.map(function (name) Object.getOwnPropertyDescriptor(modules, name).value);
|
||||
for (let mod in values(modules.moduleList.reverse())) {
|
||||
mod.stale = true;
|
||||
if ("cleanup" in mod)
|
||||
this.trapErrors("cleanup", mod);
|
||||
if ("destroy" in mod)
|
||||
this.trapErrors("destroy", mod);
|
||||
}
|
||||
|
||||
for (let mod in values(mods))
|
||||
if (mod instanceof ModuleBase || mod && mod.isLocalModule) {
|
||||
mod.stale = true;
|
||||
if ("cleanup" in mod)
|
||||
this.trapErrors("cleanup", mod);
|
||||
if ("destroy" in mod)
|
||||
this.trapErrors("destroy", mod);
|
||||
}
|
||||
|
||||
for (let mod in values(mods))
|
||||
for (let mod in values(modules.ownPropertyValues.reverse()))
|
||||
if (mod instanceof Class && "INIT" in mod && "cleanup" in mod.INIT)
|
||||
this.trapErrors(mod.cleanup, mod, dactyl, modules, window);
|
||||
|
||||
@@ -145,20 +141,24 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
|
||||
postCommands: null
|
||||
},
|
||||
|
||||
registerObserver: function (type, callback, weak) {
|
||||
registerObserver: function registerObserver(type, callback, weak) {
|
||||
if (!(type in this._observers))
|
||||
this._observers[type] = [];
|
||||
this._observers[type].push(weak ? Cu.getWeakReference(callback) : { get: function () callback });
|
||||
},
|
||||
|
||||
unregisterObserver: function (type, callback) {
|
||||
registerObservers: function registerObservers(obj, prop) {
|
||||
for (let [signal, func] in Iterator(obj[prop || "signals"]))
|
||||
this.registerObserver(signal, obj.closure(func), false);
|
||||
},
|
||||
|
||||
unregisterObserver: function unregisterObserver(type, callback) {
|
||||
if (type in this._observers)
|
||||
this._observers[type] = this._observers[type].filter(function (c) c.get() != callback);
|
||||
},
|
||||
|
||||
// TODO: "zoom": if the zoom value of the current buffer changed
|
||||
triggerObserver: function (type) {
|
||||
let args = Array.slice(arguments, 1);
|
||||
applyTriggerObserver: function triggerObserver(type, args) {
|
||||
if (type in this._observers)
|
||||
this._observers[type] = this._observers[type].filter(function (callback) {
|
||||
if (callback.get()) {
|
||||
@@ -179,6 +179,10 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
|
||||
});
|
||||
},
|
||||
|
||||
triggerObserver: function triggerObserver(type) {
|
||||
return this.applyTriggerObserver(type, Array.slice(arguments, 1));
|
||||
},
|
||||
|
||||
addUsageCommand: function (params) {
|
||||
let name = commands.add(params.name, params.description,
|
||||
function (args) {
|
||||
|
||||
@@ -447,6 +447,12 @@ var Events = Module("events", {
|
||||
});
|
||||
},
|
||||
|
||||
signals: {
|
||||
"browser.locationChange": function (webProgress, request, uri) {
|
||||
options.get("passkeys").flush();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an event listener for this session and removes it on
|
||||
* dactyl shutdown.
|
||||
|
||||
@@ -273,7 +273,7 @@ var Modes = Module("modes", {
|
||||
let msg = null;
|
||||
if (options.get("showmode").getKey(this.main.name, true))
|
||||
msg = this._getModeMessage();
|
||||
if (loaded.commandline)
|
||||
if (msg || loaded.commandline)
|
||||
commandline.widgets.mode = msg || null;
|
||||
},
|
||||
|
||||
|
||||
@@ -92,6 +92,63 @@ var StatusLine = Module("statusline", {
|
||||
|
||||
get visible() !this.statusBar.collapsed && !this.statusBar.hidden,
|
||||
|
||||
signals: {
|
||||
"browser.locationChange": function (webProgress, request, uri) {
|
||||
let win = webProgress.DOMWindow;
|
||||
this.updateUrl();
|
||||
this.progress = uri && win && win.dactylProgress || "";
|
||||
|
||||
// if this is not delayed we get the position of the old buffer
|
||||
this.timeout(function () {
|
||||
this.updateBufferPosition();
|
||||
this.updateZoomLevel();
|
||||
}, 500);
|
||||
},
|
||||
"browser.overLink": function (link) {
|
||||
switch (options["showstatuslinks"]) {
|
||||
case "status":
|
||||
this.updateUrl(link ? _("status.link", link) : null);
|
||||
break;
|
||||
case "command":
|
||||
if (link)
|
||||
dactyl.echo(_("status.link", link), commandline.DISALLOW_MULTILINE);
|
||||
else
|
||||
commandline.clear();
|
||||
break;
|
||||
}
|
||||
},
|
||||
"browser.progressChange": function onProgressChange(webProgress, request, curSelfProgress, maxSelfProgress, curTotalProgress, maxTotalProgress) {
|
||||
if (webProgress && webProgress.DOMWindow)
|
||||
webProgress.DOMWindow.dactylProgress = curTotalProgress / maxTotalProgress;
|
||||
this.progress = curTotalProgress / maxTotalProgress;
|
||||
},
|
||||
"browser.securityChange": function onSecurityChange(webProgress, request, state) {
|
||||
|
||||
if (state & Ci.nsIWebProgressListener.STATE_IS_BROKEN)
|
||||
this.security = "broken";
|
||||
else if (state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL)
|
||||
this.security = "extended";
|
||||
else if (state & Ci.nsIWebProgressListener.STATE_SECURE_HIGH)
|
||||
this.security = "secure";
|
||||
else // if (state & Ci.nsIWebProgressListener.STATE_IS_INSECURE)
|
||||
this.security = "insecure";
|
||||
|
||||
if (webProgress && webProgress.DOMWindow)
|
||||
webProgress.DOMWindow.document.dactylSecurity = this.security;
|
||||
},
|
||||
"browser.stateChange": function onStateChange(webProgress, request, flags, status) {
|
||||
if (flags & Ci.nsIWebProgressListener.STATE_START)
|
||||
this.progress = 0;
|
||||
if (flags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||
this.progress = "";
|
||||
this.updateUrl();
|
||||
}
|
||||
},
|
||||
"browser.statusChange": function onStatusChange(webProgress, request, status, message) {
|
||||
this.updateUrl(message);
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the status bar to indicate how secure the website is:
|
||||
* extended - Secure connection with Extended Validation(EV) certificate.
|
||||
|
||||
@@ -983,6 +983,9 @@ Module.INIT = {
|
||||
locals.reverse().forEach(function (fn, i) update(objs[i], fn.apply(module, args)))
|
||||
module.instance = module;
|
||||
module.init();
|
||||
|
||||
if (module.signals)
|
||||
modules.dactyl.registerObservers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,12 @@ var Contexts = Module("contexts", {
|
||||
util.trapErrors("onUnload", plugin);
|
||||
},
|
||||
|
||||
signals: {
|
||||
"browser.locationChange": function (webProgress, request, uri) {
|
||||
this.flush();
|
||||
}
|
||||
},
|
||||
|
||||
Group: Class("Group", Group, { modules: modules, get hiveMap() modules.contexts.hives }),
|
||||
|
||||
Hives: Class("Hives", Class.Property, {
|
||||
|
||||
@@ -79,6 +79,7 @@ var Overlay = Module("Overlay", {
|
||||
const module = Class(name, base, prototype, classProperties);
|
||||
|
||||
module.INIT = moduleInit || {};
|
||||
module.modules = modules;
|
||||
module.prototype.INIT = module.INIT;
|
||||
module.requires = prototype.requires || [];
|
||||
Module.list.push(module);
|
||||
@@ -143,7 +144,13 @@ var Overlay = Module("Overlay", {
|
||||
sandbox.Math = jsmodules.Math;
|
||||
sandbox.__proto__ = proto || modules;
|
||||
return sandbox;
|
||||
}
|
||||
},
|
||||
|
||||
get ownPropertyValues() array.compact(
|
||||
Object.getOwnPropertyNames(this)
|
||||
.map(function (name) Object.getOwnPropertyDescriptor(this, name).value, this)),
|
||||
|
||||
get moduleList() this.ownPropertyValues.filter(function (mod) mod instanceof this.ModuleBase || mod.isLocalModule, this)
|
||||
});
|
||||
modules.plugins = create(modules);
|
||||
modules.modules = modules;
|
||||
@@ -228,6 +235,9 @@ var Overlay = Module("Overlay", {
|
||||
Class.replaceProperty(modules, module.className, obj);
|
||||
loaded[module.className] = true;
|
||||
|
||||
if (loaded.dactyl && obj.signals)
|
||||
modules.dactyl.registerObservers(obj);
|
||||
|
||||
frob(module.className);
|
||||
}
|
||||
catch (e) {
|
||||
@@ -258,7 +268,8 @@ var Overlay = Module("Overlay", {
|
||||
delete modules[mod.className];
|
||||
return load(mod.className, null, Components.stack.caller);
|
||||
});
|
||||
Object.keys(mod.prototype.INIT).forEach(function (name) { deferInit(name, mod.prototype.INIT, mod); });
|
||||
Object.keys(mod.prototype.INIT)
|
||||
.forEach(function (name) { deferInit(name, mod.prototype.INIT, mod); });
|
||||
}
|
||||
mod.frobbed = true;
|
||||
});
|
||||
@@ -300,15 +311,12 @@ var Overlay = Module("Overlay", {
|
||||
modules.events.listen(window, "unload", function onUnload() {
|
||||
window.removeEventListener("unload", onUnload.wrapped, false);
|
||||
|
||||
for (let prop in properties(modules)) {
|
||||
let mod = Object.getOwnPropertyDescriptor(modules, prop).value;
|
||||
util.dump("unload", modules.moduleList);
|
||||
for each (let mod in modules.moduleList.reverse()) {
|
||||
mod.stale = true;
|
||||
|
||||
if (mod instanceof ModuleBase || mod && mod.isLocalModule) {
|
||||
mod.stale = true;
|
||||
|
||||
if ("destroy" in mod)
|
||||
util.trapErrors("destroy", mod);
|
||||
}
|
||||
if ("destroy" in mod)
|
||||
util.trapErrors("destroy", mod);
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
@@ -1645,6 +1645,17 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
||||
|
||||
wrapCallback: wrapCallback,
|
||||
|
||||
/**
|
||||
* Returns the top-level chrome window for the given window.
|
||||
*
|
||||
* @param {Window} win The child window.
|
||||
* @returns {Window} The top-level parent window.
|
||||
*/
|
||||
topWindow: function topWindow(win)
|
||||
win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow),
|
||||
|
||||
/**
|
||||
* Traps errors in the called function, possibly reporting them.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user