Customising browser UI

First of all, I’m well aware that Mozilla SDK extensions are going to be abandoned soon.
That being said, in the name of scientific endeavour I’d like to write an addon-sdk extension to customise parts of the browser UI. Specifically, the lower, locked section of the hamburger menu (the area which houses the “Quit” and “Help” buttons), the about:preferences page and about:addons.

Are there any APIs for it?

My own research only led me to XUL overlay addons (which, AFAIK, are unusable from JPM) and one bootstrapped addon called “Slipperymonkey” that promises adding a new list item to about:addons but doesn’t seem to work anymore.

Hey @Happy-Ferret! :slight_smile:

I also needed to do this for my addon Profilist - https://addons.mozilla.org/en-US/firefox/addon/profilist/

However it’s not possible and it’s too early for UI customization questions. Android-native (JNI.jsm) support is in the same boat. No one has an answer to this question yet.

In my future proof version I have moved my GUI to a tab, as an HTML thing. Beta testers absolutely hate it. But there’s nothing we can do right now. Predicting what they’ll do and acting preemptively is a waste of time and effort, for example native.js and what it actually ended up as.

Disclaimer: This is just based on what I have heard/seen. I might be wrong.

I see.
Is there a way to use jpm for XUL overlay extension packing and testing, at least?

As I was saying before. Future proofing is really not one of my issues.

With jpm you can get the XUL window. For instance this gets the most recent window:

const { getMostRecentWindow } = require(“sdk/window/utils”);

let win = getMostRecentWindow(‘navigator:browser’);

Then you can access the panel GUI of that window. However the panelui loads lazily. So it wont all be there until you open the menu once.

After that you can access all the goods at win.PanelUI. You want to be looking at the footer section. I get that below at PUIf

This is an example of how to deal with it:

var getPUIMembers = function(aDOMWindow) {
	// returns null if DNE or the object
	var PUI = aDOMWindow.PanelUI;
	if (!PUI) {
		return {
			PUI: null,
			PUIp: null,
			PUIf: null
		}
	}
	
	var PUIp;
	if (!PUI._initialized) {
		PUIp = aDOMWindow.document.getElementById('PanelUI-popup'); // have to do it this way, doing PanelUI.panel does getElementById anyways so this is no pref loss
	} else {
		PUIp = PUI.panel; // PanelUI-popup
	}

	// console.log('PUI.mainView:', PUI.mainView, PUI.mainView.childNodes);
	var PUIf = PUI.mainView ? PUI.mainView.childNodes[1] : null; // PanelUI-footer // aDOMWindow.PanelUI.mainView.childNodes == NodeList [ <vbox#PanelUI-contents-scroller>, <footer#PanelUI-footer> 		]
	
	return {
		PUI: PUI,
		PUIp: PUIp,
		PUIf: PUIf
	};

};

	var {PUI, PUIp, PUIf} = getPUIMembers(aDOMWindow);
	
	if (PUIp.state == 'open' || PUIp.state == 'showing') {
		insertProfilistBox({view:aDOMWindow});
	} else {
		PUIp.addEventListener('popupshowing', insertProfilistBox, false);
	}

Thanks!

As it happens, I found an older post of yours on Stackoverflow.

http://stackoverflow.com/questions/23450137/when-add-toolbarbutton-to-footer-of-panelui-it-doesnt-get-the-anonymous-element

I modified it a bit and it turned out to work just great.

PUIf.appendChild(jsonToDOM(profilistToolbarButton, document, {}));

has to be

PUIf.appendChild(jsonToDOM(profilistToolbarButton, window.document, {}));

and

['toolbarbutton', {id:'dynamictoolbarbutton',label:'Sync Now'}];

has to be

['xul:toolbarbutton', {id:'dynamictoolbarbutton',label:'Sync Now'}];

after that I just had to define window, similarly to how you did it above.

1 Like

Oh wow! Superb! Does using that xul namespace make anonymous elements work on it?

The only thing I’ve tested so far that doesn’t work is an svg list-style-image and I have no idea why (can we have no svg icons as part of the UI?)

style: “list-style-image: url(‘chrome://addUI/content/icon.svg’);” fails whereas
style: “list-style-image: url(‘chrome://addUI/content/icon.png’);” displays the proper icon.

XUL is funky. You might have to remove the display="xul:button" per this topic - http://stackoverflow.com/a/24401363/1828637

As that’s what I had to do to get anonymous elements working. I’m not sure past this, I would have to trial and error. :frowning: