Customizing WebRunner Behavior
I would like to share a technique that I am using to customize WebRunner's behavior without directly changing the source code. In my AppRunner extension I have created an overlay for webrunner.xul and within the overlay I include my custom apprunner.js script. Today I decided that I want to modify the behavior of a function in the core WebRunner application object.
In webrunner.js there is a global WebRunner object which is defined like this:
var WebRunner = {
_profile : null,
_ios : null,
// webrunner functions omitted...
}
In my apprunner.js file I have my own global AppRunner namespace object, defined similarly to the WebRunner object above. I will try to let the code speak for it's self with a short explanation afterward:
window.addEventListener("load", function() { apprunner.startup(); }, false);
window.addEventListener("unload", function() { apprunner.shutdown(); }, false);
var apprunner = {
startup: function() {
self = this;
var browserContext = document.getElementById("popup_main");
browserContext.addEventListener("popupshowing", self._popupShowing, false);
//replace the webrunner _isLinkExternal function with a modified version:
WebRunner._isLinkExternal = this._isLinkExternal;
},
shutdown: function() {
self = this;
window.removeEventListener("popupshowing",self._popupShowing, false);
},
_popupShowing: function(aEvent) {
var isAnchor = (document.popupNode instanceof HTMLAnchorElement);
document.getElementById("menuitem_copylink").setAttribute("hidden",!isAnchor);
document.getElementById("link_popup_separator").setAttribute("hidden",!isAnchor);
},
_isLinkExternal : function(aLink) {
if (aLink instanceof HTMLAnchorElement) {
if (aLink.target == "_self" || aLink.target == "_top")
return false;
var currentURL = this._ios.newURI(aLink.href, null, null).QueryInterface(Ci.nsIURL);
var commonBase = currentURL.getCommonBaseSpec(this._getBrowser().currentURI);
//alert(commonBase + ":" + aLink.href + ":" + this._getBrowser().currentURI.href);
return (commonBase.length == 0);
}
return true;
},
copylink: function(event) {
var gClipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].
getService(Components.interfaces.nsIClipboardHelper);
gClipboardHelper.copyString(document.popupNode.href);
},
doCommand : function(aCmd) {
switch (aCmd) {
case "cmd_aboutconfig":
window.open("chrome://global/content/config.xul", "About:Config", "chrome,extrachrome,dependent,menubar,resizable,scrollbars,status,toolbar");
break;
}
}
}
The code above is mostly for other functionality that I have added in my webrunner extension, however, the startup function shows the technique which I wanted to highlight. Notice the bold face code which replaces a function in WebRunner with my own version of the same function. This doesn't have much effect right now because I have not rewritten the function to my liking, however, my changes to that function will override WebRunner's version of the same function, all without touching webrunner.js or webrunner.xul.
This is the beauty of Mozilla's platform for extensibility and the flexibility of JavaScript makes it even more powerful. This is incredible extensibility due to the simple and intelligent design of the Mozilla platform in general and WebRunner in particular.
