Custom about: URLs

For creating an own about: URL, you have to use the following template . You have to replace SITENAME with your chosen name for the URL. Your URL will be "about:SITENAME". Also you'll have to generate a unique UUID for your page and replace YOUR-UUID with it. CHROMEDIR is the path to the file you want to display with your about: URL.

const Cc = Components.classes;
const Ci = Components.interfaces;

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

function AboutSITENAME() { }
AboutSITENAME.prototype = {
  classDescription: "about:SITENAME",
  contractID: "@mozilla.org/network/protocol/about;1?what=SITENAME",
  classID: Components.ID("{YOUR-UUID}"),
  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
  
  getURIFlags: function(aURI) {
    return Ci.nsIAboutModule.ALLOW_SCRIPT;
  },
  
  newChannel: function(aURI) {
    let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
    let channel = ios.newChannel("chrome://CHROMEDIR",
                                 null, null);
    channel.originalURI = aURI;
    return channel;
  }
};

function NSGetModule(compMgr, fileSpec)
  XPCOMUtils.generateModule([AboutSITENAME]);

After that, you should edit the Manifest file and add:

EXTRA_PP_COMPONENTS = \
      aboutSITENAME.js \
    $(NULL)

 This makes sure that your file will be pre-processed and copied into browser/components/ .

For Firefox 4

In the extension's chrome.manifest file, write:

component CID relative/file/location/of/file.js/whereever/you/put/it
contract @mozilla.org/network/protocol/about;1?what=sitename CID

For example:

component {00000000-0000-0000-0000-000000000000} components/aboutSitename.js
contract @mozilla.org/network/protocol/about;1?what=sitename {00000000-0000-0000-0000-000000000000}

See this article for information on how to create a valid UUID; making up your own will most likely result in a "Malformed CID" error.

Then, in your JavaScript file (probably components/aboutSitename.js):

const Cc = Components.classes;
const Ci = Components.interfaces;

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

function AboutSitename() { }
AboutSitename.prototype = {
  classDescription: "about:sitename",
  contractID: "@mozilla.org/network/protocol/about;1?what=sitename",
  classID: Components.ID("{YOUR-UUID}"),
//Note: classID here should be exactly the same as CID in chrome.manifest
  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
  
  getURIFlags: function(aURI) {
    return Ci.nsIAboutModule.ALLOW_SCRIPT;
  },
  
  newChannel: function(aURI) {
    let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
    let channel = ios.newChannel("chrome://CHROMEDIR",
                                 null, null);
//Note:"chrome://CHROMEDIR" is like chrome://extension/content/aboutSitename.html Read more about chrome registration: https://developer.mozilla.org/en/Chrome_Registration
  channel.originalURI = aURI;
    return channel;
  }
};
const NSGetFactory = XPCOMUtils.generateNSGetFactory([AboutSitename]);

 

For Firefox 4 (Second Approach)

This is basically the samething as above but I just don't understand the above, and this was easy to understand. You can just copy paste it and run with it. This is copied from "about:addons-memory" addon by Nils Maier. This one does not need a manifest file like the one above. It's realy easy, copy paste and you got yourself a restartless custom about page.

A demo of this method is attached, it is called "custom about page demo.xpi". With this addon, when you type in about:demo it loads a page within the addon called index.txt.

Follow these steps:

  1. Copy and paste the code below (in scratchpad [with browser environement] or into your own addon)
  2. Replace in the copied and pasted code /*{YOUR_UUID_HERE}*/ with your UUID (if you don't have one generate one: See this article)
  3. Replace in the pasted code /*PATH_TO_PAGE*/ with a URL to the page it should redirect to
    1. If you have a page in your addon that you want to show then you have to use its path which will look something like:
      jar:file:///C:/Documents%20and%20Settings/Jeff%20Thompson/Application%20Data/Mozilla/Firefox/Profiles/ye66zx1t.default/extensions/custom-about-page-demo@jetpack.xpi!/frontend%20module/index.txt. This path will obviously differ for each user depending on many things, so you will have to dynamically figure out this url.
    2. To accomplish this you have to figure out the path, do this by create a global variable called selfPath and then set this to the addon path by putting "selfPath = aData.resourceURI.spec;" in your startup area so like for example:
      function startup(aData, aReason) {
          selfPath = aData.resourceURI.spec;
      }

      This creates a global variable called selfPath and sets it to this leading path. So now back to our code below, we would replace /*PATH_TO_PAGE*/ with selfPath + 'bootstrap.js' or selfPath + 'my%20folder/index.htm'.
    3. I have attached to this page "custom-about-page-demo.xpi" addon which demonstrates this.
  4. Replace in the pasted code /*YOUR_ABOUT_WORDS_HERE*/ with what you want the user to type in after "about:" in the URL bar
  5. Replace /*{YOUR_TEXT_DESCRIPTION_HERE}*/ with whatever you want to describe your about page with.

Note: See the commented parts in the code for example/idea how it works

var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr, manager: Cm} = Components; //can make this const if not in scratchpad
Cm.QueryInterface(Ci.nsIComponentRegistrar);
Cu.import('resource://gre/modules/Services.jsm');
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

var AboutModuleUnloaders = [];
function AboutModule() {}

AboutModule.prototype = {
	uri: Services.io.newURI('/*PATH_TO_PAGE*/', null, null), //EXAMPLE1: uri: Services.io.newURI('http://www.bing.com/', null, null), //EXAMPLE2: uri: Services.io.newURI('chrome://about-addons-memory/content/about.xhtml', null, null),
	classDescription: '/*{YOUR_TEXT_DESCRIPTION_HERE}*/',
	classID: Components.ID('/*{YOUR_UUID_HERE}*/'), //EXAMPLE: classID: Components.ID('1704E6F0-8039-11E3-9CE1-C4766188709B'),
	contractID: '@mozilla.org/network/protocol/about;1?what=/*YOUR_ABOUT_WORDS_HERE*/', //EXAMPLE: contractID: '@mozilla.org/network/protocol/about;1?what=yabba'
	QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
	newChannel: function (aURI) {
		let chan = Services.io.newChannelFromURI(this.uri);
		chan.originalURI = aURI;
		return chan;
	},
	getURIFlags: function (aURI) 0
};
function registerComponents() {
	for (let[y, cls] in Iterator([AboutModule])) {
	   Cu.reportError('y: ' + y);
	   Cu.reportError('cls: ' + cls);
		try {
			var factory = {
				_cls: cls,
				createInstance: function (outer, iid) {
					if (outer) {
						throw Cr.NS_ERROR_NO_AGGREGATION;
					}
					return new cls();
				}
			};
			Cm.registerFactory(cls.prototype.classID, cls.prototype.classDescription, cls.prototype.contractID, factory);
			AboutModuleUnloaders.push(function(){
			 Cm.unregisterFactory(factory._cls.prototype.classID, factory);
			});
		} catch (ex) {
			Cu.reportError('failed to register module: ' + cls.name + '\nexception thrown: ' + ex);
		}
	}
}

function unregisterComponents() {
	for (var i=0; i<AboutModuleUnloaders.length; i++) {
		AboutModuleUnloaders[i]();
	}
}

registerComponents(); //run this to make it work. once this is run follwoing examples above: typing "about:yabba" will take you to bings homepage
//unregisterComponents(); //do this to remove it //after running this typing about:yabba will take you to problem loading page 

Document Tags and Contributors

Tags:
Contributors to this page: Wikiwide, MichaelKohler, yarrkov, Noitidart, Sheppy
Last updated by: Noitidart,