Customizing Firefox – Hiding Private Browsing

Update: I was reminded that using visibility: collapse for menu items leaves them in the key navigation. Instead, you should use hidden=”true” or in places that doesn’t work (context menus) display: none.

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.

Please note: I reserve the right to delete comments that are offensive or off-topic.

Leave a Reply

Your email address will not be published. Required fields are marked *

13 thoughts on “Customizing Firefox – Hiding Private Browsing

  1. Please hide menuitems (hidden=”true” or use display: none; in CSS) rather than collapsing them. Arrow key navigation relies on menuitems being hidden rather then collapsed.

    • I knew there was a reason to use hidden, I couldn’t remember. The problem with using hidden is in context menus where hidden will be overridden by Firefox. Is there something that will work for both?

    • I tried using this tutorial to hide the “Set Up Sync…” menu item, and found the ids “sync-setup-appmenu” and “sync-syncnow-appmenu”, and added them to a working browseroverlay.xul (I know it works because it contains your commands for hiding Private Browsing and it does that correctly). So these are inserted below the private browsing ids:

      and they do not appear to have any affect on the browser. Any ideas?

      Thanks,
      Josh

      • So those two menuitems are hidden and shown by Firefox, so it will override your choices.

        Try using style=”display: none” instead of hidden=”true”

        • Thank you for the help Mike.

          I used [menuitem id=”sync-setup-appmenu” style=”display:none”] and [menuitem id=”sync-syncnow-appmenu” style=”display:none”] (with proper tags instead of brackets of course) and this had no effect either.

    • Ah the famous WMWOOD…

      Your icognito gone is blocked by firefox when downloading it! I assume this is where you got your code for it from?

  2. hey i tried to manage the whole “tutorial” but iám not sure how the pathname ist correct.

    You did say the that we have to change the structure of our directories to “chrome/content”. My Extension should be called “FirefoxAnpassungen”. Is my following path directory in my chrome.manifest ok?

    content FirefoxAnpassungen ./
    overlay chrome://chrome/content/FirefoxAnpassungen/browser.xul
    chrome://FirefoxAnpassungen/content/browseroverlay.xul

    I´am totally new to this so please be gentle with my inexperience 🙂
    thanks a lot!

    • The first part of the overlay statement stays the same. So it would be:

      overlay chrome://browser/content/browser.xul chrome://FirefoxAnpassungen/content/browseroverlay.xul

    • I had to figure this out too. So if you have your files organized this way: [Firefox directory]\distribution\bundles\FirefoxAnpassungen\chrome\content\browseroverlay.xul, then you want your chrome.manifest two directories up inside FirefoxAnpassungen, and the first line of your chrome.manifest should be “content FirefoxAnpassungen chrome/content/”

      In my testing, the trailing slash was required for FF v17 but had to be left off for previous versions of FF to find the browseroverlay.xul properly, so I guess the standard is still in flux. Very frustrating from a deployment perspective.

  3. Well looks like I can’t do tags, should’ve expected that. My tags looks just like your menuitem=”appmenu_privateBrowsing” hidden=”true” tags, but with the “sync-setup-appmenu” and “sync-syncnow-appmenu” ids.