Customizing Firefox - Advanced Autoconfig Files

We're almost done with autoconfig files. My previous posts covered what an autoconfig file is and how to create one. Now we're going to discover how truly powerful the autoconfig feature is.

I've been saying this over and over, but it's worth repeating:

Autoconfig files are Javascript files that have full access to all components of Firefox.

This means we can use autoconfig files to change just about anything the browser that doesn't involve the user interface (and there are even ways to change that).

So how do we access the various components? The best way to use those components is via a helper Javascript module called Services.jsm. Services.jsm provides shortcuts to access frequently used components within Firefox. So for instance, if you wanted to display an alert to a user from inside your autoconfig file, you could use:

Components.utils.import("resource://gre/modules/Services.jsm");
Services.prompt.alert(null, "Title", "Message");

nsIPromptService shows all the functions you can use to prompt a user, including confirmations as well as data input

Or what if you wanted to add a bookmark? Unfortunately, the bookmarks services isn't in Services.jsm, but it's easy to get:

//
Components.utils.import("resource://gre/modules/Services.jsm");
var uri = Services.io.newURI("http://mike.kaply.com", null, null);
var navBookmarksService = Components.classes["@mozilla.org/browser/nav-bookmarks-service;1"]
                          .getService(Components.interfaces.nsINavBookmarksService);
navBookmarksService.insertBookmark(navBookmarksService.toolbarFolder, uri, -1, "Mike's Blog");

As you can see, you can pretty much do anything from an autoconfig file. I couldn't even begin to scratch the surface. The best place to start looking is MDN (or just ask in the comments).

Before we finish up, I want to give one other code snippet that might be useful for folks. In a couple posts, we'll be covering userChrome.css and userContent.css Putting these files in a user's profile directory is a common way to do simple customization of the browser. Unfortunately that usually requires setting up a default profile (which is another thing we'll be talking about in a few posts). By using an autoconfig file to write out these files, we avoid having to manually place them in each user's profile:

//
const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/Services.jsm");
var profileDir = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
profileDir.append("chrome");
if( !profileDir.exists() || !profileDir.isDirectory() ) {
  profileDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
}
profileDir.append("userChrome.css");
var fos = 
Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
fos.init(profileDir, -1, -1, false);
var css = "#context-setDesktopBackground { display: none;}";
fos.write(css, css.length);
fos.close();

This example removes the menuitem that changes the desktop background.

Autoconfig files are VERY powerful, even more powerful then even I realized. In combination with userContent.css and userChrome.css, you can do a lot.

So when do you choose to use autoconfig files? The best thing about autoconfig files is how easy they are to get into Firefox. No need for an add-on or anything like that. You just drop in two files and you're done. You can also put the configuration file on a server which makes things even easier. So you should choose autoconfig files when the changes you are making to Firefox don't involve major changes to the user interface. You should also choose autoconfig files if you need to lock preferences (although you can lock preferences with the CCK - we'll talk about that later).

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 *

33 thoughts on “Customizing Firefox - Advanced Autoconfig Files

  1. I'm trying to add popup and cookie exceptions to my autoconfig file but I can't get it to work. Here's what I've tried:

    Components.utils.import("resource://gre/modules/Services.jsm");
    var uri = Services.io.newURI("http://utexas.edu", null, null);
    Services.perms.add(uri, "popup", 1);
    Services.perms.add(uri, "cookie", 1);

    It generates no errors (that I'm aware of) but neither does it add the exceptions. Everything else in the autoconfig file is getting applied (numerous lockPref() and pref() calls earlier in the file) and I can even get an alert to appear after importing the Services module so I guess that I'm either building the URI or adding the exception incorrectly (or both).

    • I just cut and pasted your exact code and put it into an autoconfig file and it worked for me. Did you try it by itself in an autoconfig file? (If you do decide to cut and paste to retest, don't forget to fix the double quotes that wordpress messes with)

      • Indeed it does... I tracked it down to one pref in the autoconfig file:
        pref("privacy.clearOnShutdown.siteSettings", true);

        "Why yes, of course!" Firefox is launched (for the first time), the autoconfig settings get applied, Firefox relaunches itself and deletes the popup and cookie exceptions as instructed.

        I guess that's what I get for being overly paranoid about browsing privacy. :)

        Thanks for the response.

  2. OK, I've got a question for you. I'm trying to set the cache directory to point to a location outside the user home directory. Using the autoconfig file, I set browser.cache.disk.parent_directory to the directory I want: inside Firefox's about:config page I can see that setting, italicized. However, the cache stays right where it is.

    If I set it manually in the prefs.js file, the next time Firefox starts the cache goes to the preferred location. However, upon quitting Firefox writes out the preferences and removes that pref.

    Any ideas?

  3. Hi,

    First, many thanks for your "musings" that have been highly time-saving for me.

    Is there a way to get a reference to the browser object from the autoconfig file in order to add tab-related event handlers ?

    Regards.

    • The autoconfig is processed very early, so anything browser related wouldn't be setup yet.

      Something like that would be best handled via an add-on.

  4. Referring to your post: "This means we can use autoconfig files to change just about anything the browser that doesn't involve the user interface (and
    there are even ways to change that). "
    Since long, I have been trying to disable buttons in Tools -> Options and also disable the whole tab like "Advanced" tab. Can I achieve this using auto config files.
    Your suggestions in this regards will be really helpful.

    • When it comes to user interface, most of the time it's easier to just write an extension to do it.

      Some preference options can be disabled via preferences (if you lock the preferences, it disables the item).

      Another option is to write out the file userChrome.css to disable things. That can be done via autoconfig.

  5. any chance you have something to change to a new profile?
    for example I want to run firefox esr and firefox nightly with two different profiles. and it would be great if one could automate this.

    • You can bring up the profile manager by typing:

      firefox -profile-manager

      Uncheck the box that says "Don't ask at startup".

      Then create a new profile for your Nightly.

      When you start Firefox, you can start it with "firefox -p "Profile name" -no-remote and then you can start the second Firefox the same way.

      • I was thinking of distributin the two firefox versions to other users than me. so idealy the profile would just be default in firefox esr and in nightly a new profile created and used automaticly. so without the user doing anything ;)

        • Ah.

          The only way I know to do that would be to have the shortcuts for the two Firefox versions point to different directories for their profiles.

          If you start Firefox with -profile "PATH" you can specify where the profile is initially created.

          So you could have icons for the different firefoxes like:

          firefox -profile "C:\Users\foo\ESR"

          and

          firefox -profile "C:\Users\foo\Nightly"

          That's the only thing that I can think of...

          • not a bad idea. I will test that out.
            I also posted an argument change in mozilla suggestion box about a autocreat profile.

            many thanks ;)

          • works great!
            C:\Programfiler\Nightly\firefox.exe -profile "%appdata%\Mozilla\Firefox\Profiles\thor" -no-remote

            not sure if -no-remote is necessary

            many thanks ;)

  6. I am trying to hide Sync,Security,Privacy and advanced tab.
    Firefox version is 19.0
    I think this can be achieved via creating userchrome.css file and saving it under chrome folder. However, i am not sure how to write codes in this file. Also, there is no chrome folder in the location where the executable of firefox exists.
    Please help me.

      • Thanks for the response. I checked the link but there is no mention that i can hide the Security or Privacy tab under Firefox options. Please advise if this is possible using .css file. If yes, please help me with an example code which can hide any of these option so that i can use it to hide other options as per the requirement.
        Thanks in advance :)

        • You'll need to do some research to find the answers you're looking for. You'll need to find the IDs of the elements you want to hide. From http://mike.kaply.com/2012/03/30/customizing-firefox-default-profiles/

          There are so many things you can do with this file, I couldn't even begin to describe them here. You can hide menuitems, change parts of the UI, etc. If you choose to hide something, it's better to use visibility: collapse than display: none. Messing with display can cause very strange results in Firefox. If you're interested in figuring out the IDs of the various elements of the UI, check out the DOM Inspector. You can also just browser through the source code. browser-menubar.inc and browser-context.inc are particularly useful.

  7. What I want is the ability to set three pages to open each in a separate tab and set the focus to a particular tab.

    I just made the following up (stuff in caps) for lack of any examples

    user_pref(browser.startup.tab.TABNAME.TAB1.link", "www.microsoft.com");
    user_pref(browser.startup.tab.TABNAME.TAB2.link", "www.google.ca");
    user_pref(browser.startup.tab.TABNAME.TAB3.link", "www.outlook.com");
    user_pref(browser.startup.tab.SETFOCUS.TAB2

    obviously the tab gets it's name from the url so you wouldn't use that but is there a way that you can think of to get the desired effect

    Logically speaking... Create an index of three and set focus to the desired tab index.

    • There's no way to set the default tab (I believe it is always the last one), but you can set multiple homepages like this:

      pref("browser.startup.homepage", "http://www.yahoo.com|http://www.google.com|http://www.digg.com");

  8. profileDir.append did not do exactly what it said.
    it does not append. it overwrite the file.

    how can i append only few lines into the file?

    tnx.
    dny

    • profileDir.append appends a file name to a profileDir.

      What exactly are you trying to do? What file are you trying to append to?

  9. I am not a coder. I have a question about the alert sound in firefox.

    I am a lead of a helpdesk team. We provide chat support using a web ticketing tool which has limitations.

    Our team members hear a very faint "pop" sound when there is a chat window from a user. But this is too faint.
    I would want to know the source file of sound in Firefox. So that I could change the sound's source file to a louder alert sound.

    Any ideas?

    • Why not just raise the volume on the computer ?
      Unless you want a different sound.
      Also, if you are using Microsoft windows, you can set different sounds for different events, with provided or custom files.
      If you use chatzilla (with seamonkey or separately), you can configure it to beep or play whatever sound file you like, for various events.

  10. Mike,

    In my case the user's profile has already been created so leveraging the autoconfig to set the userChrome.css is perfect! Your example worked flawlessly in my environment, however I need to write 4 different settings to the userChrome.css. I need a little assistance figuring this out as I kept getting all 4 lines on just a single line in the userChrome.css file.

    Thanks!

    -Steve