Update: I was reminded that using visibility: collapse for menu items leaves them in the key navigation. Instead, you should use
In my previous post, I showed how to setup a basic extension in Firefox. Having this extension will allow us to do some Firefox customization. Before I get into this post, though, I wanted to clarify one thing. I had you put your XUL overlay in the root directory and point your content directory to ./. I did that to make things simpler but in practice you'll want to separate your files. The structure most commonly used is a chrome directory with a content subdirectory underneath. In that case, the directory in the chrome manifest would be chrome/content/.
With that out of the way, let's customize Firefox. We're going to prevent a user from accessing private browsing. We need a disclaimer here, though. We are not removing private browsing, we are just removing access. So if the user has an add-on that invokes private browsing, or if they have access to about:config, they can still turn on private browsing. For any of these customizations, there's an expectation that the right things have been done to prevent the user from accessing functionality via other means.
The first step to removing functionality from the browser is to understand the different ways a user can access that function. For private browsing, there are three entry points, the Start Private Browsing menu item on the Firefox button, the Start Private Browsing menu item under the Tools menu and the keystroke Ctrl+Shift+P (command+shift+P on Mac). We'll need to handle each of these cases and prevent the user from accessing them.
In my previous post, I said that we needed the ID of an item in order to customize it. There are two ways to find the ID. One is to use the DOM Inspector and the other is to search through the Mozilla source code. I prefer to search through the Mozilla source code because it usually gives me a lot more information. Here's how I locate what I need.
The Mozilla source code is hosted in a tool called MXR and can be easily searched. The first thing you want to search on is the text of the menuitem you're trying to remove. So we'll search on Start Private Browsing. What we're looking for usually is a DTD file that has the same text as the menu item. This will help us find the actual menu item. In this case, that file is browser.dtd:
<!ENTITY privateBrowsingCmd.start.label "Start Private Browsing">
The information we actually need is the label on the left. By using that as a search term, we can find the menus that have this as their text. So we search for privateBrowsingCmd.start.label. This looks a lot more promising. We see references to browser-appmenu.inc and browser-menubar.inc. These files contain the menu items we're looking for. So let's look at one of those menuitems:
<menuitem id="appmenu_privateBrowsing" class="menuitem-iconic menuitem-iconic-tooltip" label="&privateBrowsingCmd.start.label;" startlabel="&privateBrowsingCmd.start.label;" stoplabel="&privateBrowsingCmd.stop.label;" command="Tools:PrivateBrowsing" key="key_privatebrowsing"/>
There is one of the IDs we need - appmenu_privateBrowsing.
So if we add this to our XUL overlay:
<menuitem id="appmenu_privateBrowsing" hidden="true"/>
It will hide the menu item on the Firefox button.
If we look further at this menu item, though, it will give some more interesting information. In particular it tells us that when this menu item is invoked, it calls a command - Tools:PrivateBrowsing. What if instead of hiding each menuitem, we could simply disable that command? It just so happens that you can do exactly that.
Commands are XUL elements for invoking operations from multiple sources. Because command is a XUL element, we can override it just like any other element. So let's find this element by searching the source code. In browser-sets.inc, we find this:
<command id="Tools:PrivateBrowsing" oncommand="gPrivateBrowsingUI.toggleMode();"/>
So we can prevent access to private browsing by simply overriding the oncommand:
<command id="Tools:PrivateBrowsing" oncommand=""/>
or we can even display a message when private browsing is invoked:
<command id="Tools:PrivateBrowsing" oncommand="alert('Private browsing has been disabled by your administrator.')"/>
By changing the command, we can prevent the various menuitems and keystrokes from invoking private browsing at all. This keeps us from having to worry about disabling the keystroke. If you do run into a case where disabling the command is not enough, search for the key value in the file browser-sets.inc. Usually it's just a matter of setting the command on the keystroke to nothing:
<key id="key_privatebrowsing" command=""/>
Occasionally keys use oncommand, so you'll need to set that to nothing instead.
There's still one more menu item, though, so let's go back to our first search and take a look at browser-menubar.inc.
<menuitem id="privateBrowsingItem" label="&privateBrowsingCmd.start.label;" accesskey="&privateBrowsingCmd.start.accesskey;" startlabel="&privateBrowsingCmd.start.label;" startaccesskey="&privateBrowsingCmd.start.accesskey;" stoplabel="&privateBrowsingCmd.stop.label;" stopaccesskey="&privateBrowsingCmd.stop.accesskey;" key="key_privatebrowsing" command="Tools:PrivateBrowsing"/>
All we need from here is the id. So let's add that to our XUL overlay:
<menuitem id="privateBrowsingItem" hidden="true"/>
And there you have it. You've disabled access to private browsing.
Using this process, you can find and customize or disable just about any menuitem in Firefox.