1
0
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:
Kris Maglione
2011-02-27 16:58:21 -05:00
parent 191ece33e0
commit 74fbc5833f
10 changed files with 159 additions and 99 deletions

View File

@@ -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" });
}
});

View File

@@ -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.
*

View File

@@ -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) {

View File

@@ -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.

View File

@@ -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;
},

View File

@@ -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.

View File

@@ -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
}
}
}

View File

@@ -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, {

View File

@@ -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);
}

View File

@@ -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.
*