问题
With Firefox 17.0.1 I am using an add-on called KeyConfig 20110522 to set some new hot keys and also set the acceltext
of menuitems
for my new keys as well as for add-ons that do not bother to do so.
I want the acceltext
of the menuitems
to be set when Firefox starts, but currently I am just using a hot key to execute the following code against the UI via KeyConfig:
document.getElementById("tabmix-menu")
.setAttribute("acceltext","Alt+Ctrl+Shift+T");
// more of the same...
I need a couple of beginners tips:
How can I execute arbitrary code against the UI in the same way as I execute against an HTML page via the console?
Is there a sneaky way to get a clump of code to execute on browser start-up without delving into XUL development?
Is there a way to trace commands executed against the UI so I can get at command calls instead of using triggers when I set my hot keys like so:
document.getElementById("tabmix-menu").click();
Any other tips on this type of low-level hacking would also be welcome.
回答1:
You can execute arbitrary code against the Firefox UI from an addon, but as you say, doing all the XUL related stuff is a bit boring :-)
Enter "Bootstrapped" extensions!
Part 1:
A "Bootstrapped" (or re-startless) extension needs only an install.rdf file to identify the addon, and a bootstrap.js file to implement the bootstrap interface.
Bootstrapped Extension: https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions
Good example: http://blog.fpmurphy.com/2011/02/firefox-4-restartless-add-ons.html
The bootstrap interface can be implemented very simply:
function install() {}
function uninstall() {}
function shutdown(data, reason) {}
function startup(data, reason) { /* YOUR ARBITRARY CODE HERE! */ }
You compile the extension by putting install.rdf
and bootstrap.js
into the top-level of a new zip file, and rename the zip file extension to .xpi.
Part 2:
Your code is privileged and can use any of the Mozilla platform APIs. There is however an issue of timing. The moment-in-time at which the "startup" function is executed is one at which no Chrome window objects exist yet!
If it's important for your code that you have a Chrome Window, we need to wait for it to appear:
// useful services.
Cu.import("resource://gre/modules/Services.jsm");
var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
var wmSvc = Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
var logSvc = Cc["@mozilla.org/consoleservice;1"]
.getService(Ci.nsIConsoleService);
// get the first gBrowser
var done_startup = 0;
var windowListener;
function do_startup(win) {
if (done_startup) return;
done_startup = 1;
wmSvc.removeListener(windowListener);
var browserEnum = wmSvc.getEnumerator("navigator:browser");
var browserWin = browserEnum.getNext();
var tabbrowser = browserWin.gBrowser;
/* your code goes here! */
}
// window listener implementation
windowListener = {
onWindowTitleChange: function(aWindow, aTitle) {},
onCloseWindow: function(aWindow) {},
onOpenWindow: function(aWindow) {
var win = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
win.addEventListener("load", function(aEvent) {
win.removeEventListener("load", arguments.callee, false);
if (aEvent.originalTarget.nodeName != "#document") return;
do_startup();
}
};
// CODE ENTRY POINT (put this in bootstrap "startup" function)
wmSvc.addListener(windowListener);
来源:https://stackoverflow.com/questions/13941960/get-firefox-to-run-xul-type-script-on-startup