Tag: firefox

Blog entries related to Mozilla Firefox

Show right-click menus on form elements

Ever since bug 404536 has landed, a number of users have been angry.  What that bug did was removing the context menu for HTML form elements.  This change annoyed mainly two classes of users: those who were accustomed to those context menus, and those who used extensions which add menu items to the context menus for form elements (along with other elements, possibly), most notably, Firebug.

Exactly one year later, I am releasing the Form Control Context Menu extension, with the sole purpose of reverting back to the old behavior of showing the context menus for HTML form elements.  So, if you’ve been affected by this in the past, jump up and install this extension.  It can be installed on anything from Firefox 3.0 Beta 4 to the latest trunk builds.

Remember that the extension is currently in sandbox, so you need to log in before installing it.  Make sure to leave your comments if you find the extension useful, because moving it out of the sandbox needs your comment love. 

If you are an extension developer, and your extension adds something to those context menus, and is hence affected by that fix, you can either ask your users to install the Form Control Context Menu extension, or use the below code inside your own extension.  This code needs to run exactly once for each browser window, so you can add it to the load event handler of the XUL window.

let setTargetOriginal = nsContextMenu.prototype.setTarget;
nsContextMenu.prototype.setTarget = function(aNode, aRangeParent, aRangeOffset) {
  setTargetOriginal.apply(this, arguments);
  if (this.isTargetAFormControl(aNode))
    this.shouldDisplay = true;
};

For the curious, this is exactly the same code used inside the extension.  You can browse the extension’s source code on AMO, but there’s nothing too interesting there.

Tagged with: , ,

Unicode installer and updater available soon

Until now, localization projects which did not have a Windows code-page assigned to them were out of luck for localizing the installer and updater user interfaces for all Mozilla-based applications.  We all know that code-pages are evil; here are the main problems encountered with code-page based localization of these two applications:

  • Locales which did not have a code-page available could not localize the installer and updater files.
  • The installer and updater applications made for locales which did have a code-page available only worked if Windows was configured to use exactly that code-page, otherwise the users would see garbage text (see for example this screenshot which was taken from the Russian installer on an English version of Windows XP).

These two reasons had caused many locales not localizing the updater and installer applications.  And because the installer at least is the first part of the application a user needs to interact with, this was a big problem.

I found out about this when trying to find out why my Persian translations for the Firefox installer cause the build process to break.  Soon I found out that there are two bugs filed for Unicode support in the installer and the updater, so I stepped up and worked on them.  We are switching to Unicode NSIS, which is a heroic project of Jim Park, to teach Unicode to the NSIS Installer.  Thanks to the wonderful help from Robert Strong, we are nearly ready to land the Unicode support for the installer (Unicode support for the updater has landed recently).

I’ve tried to summarize what this means for localizers:

  • This will affect Firefox trunk (3.2) and 3.1, Thunderbird 3.0, SeaMonkey 2.0 as well as Sunbird 1.0.
  • If you have already translated the installer and updater strings for your locale, there is nothing special for you to do here – you can relax and enjoy the results (which would be that the installer and updater will magically show up correct on all Windows configurations)!
  • If you have not yet translated the installer and updater so far, this means that you can get started right now!  But please don’t land your translations until bug 305039 lands, otherwise your locale builds will fail until then.

Last but not least, here are some screenshots from the Persian translation of Firefox installer for your viewing pleasure.

Persian Firefox Unicode Installer

Persian Firefox Unicode Installer

Persian Firefox Unicode Installer

Happy localizing!

Tagged with: , , , , ,

First Persian Firefox builds available

The first Persian Firefox builds (built by Tinderbox) are available!  These builds, according to Persian Mozilla Dashboard are 86% percent complete.  Nearly all parts of the browser are translated.  The remaining things to translate include a number of security error messages and UI strings, and the installer (which is in fact translated, I’m just working on bug 305039 to make the installer Unicode, so that we can have a useful Persian installer).  These will hopefully be finished soon as well.

Your feedback is very much appreciated.  If you are a Persian speaking user, please download these builds and provide feedback here.  You can get the builds from these locations:

By the way, as you note, the version of these builds is 3.2a1pre, which means they are preliminary versions of what will eventually be Firefox 3.2 Alpha 1.  Firefox 3.1 builds will be available as well as soon as bug 467573 is fixed.

Tagged with: , , , ,

HTTP Accept-Ranges support improved

I thought I’d blog about this, hoping some web developers may find it useful.

Previously, Mozilla’s HTTP protocol implementation did not check the presence of the Accept-Ranges response header.  The job of this header is to tell the client whether it can perform HTTP range requests, and if so, in what units should it express its range requests.  Practically, the only unit used by web servers is bytes, so this header’s job in the real world is to tell the server whether it can perform range requests at all.

The main purpose of performing range requests is either supporting download resume (where you close the connection, and next time you request the resource, you specify the remaining range of the file in your HTTP request) or downloading files in smaller chunks simultaneously like download manager applications do (where they perform several range requests side by side in order to start downloading on multiple channels instead of a single channel).

Bad news was that the Accept-Ranges header was not checked in Mozilla at all.  So, if a server would send the Accept-Ranges: none response header, in order to tell the client that the download is not resumable, Mozilla was not aware of this fact, and would show the download as resumable to the user.  And this is bad, because for example a user might have such a download in progress, and when closing Firefox, it wouldn’t prompt the user about the in-progress download, because it would blindly think that it’s actually resumable, so it would pause the download hoping to resume it next time Firefox starts, but that of course didn’t work.

In an IRC discussion with biesi, we noted the bug, so I filed and fixed bug 462707, which will appear in Firefox 3.1 and later versions.  This makes Mozilla a little bit more conformant to the HTTP specification. 

Tagged with: , ,

Testing in Mozilla talk

I gave a talk on Mozilla Software testing approach as part of my Software Testing course.  You can find the slides (built using S5) here.  I introduced a number of tools that we use for automated and manual testing, and also gave an overview on parts of the process employed to use the tests in real life.

You can grab the slides.  I hope that they’ll be useful to you.

Update: I made a mistake when writing this post, which caused the links not work.  I’ve fixed that, so now you can really see the slides. 

Update 2: I uploaded the presentation to the Mozilla Library, which is a collection of Mozilla-related presentations.  Thanks to Clint for pointing this out!

Tagged with: , ,

Persian Firefox: Sneak Peak

Look what we’re building!

Persian Firefox (فایرفاکس فارسی)

Tagged with: , , , ,

First Private Browsing extension

I did expect the community to get interested in extending the Private Browsing mode by developing extensions, but I didn’t expect it to happen this soon!  I’m happy to announce that the first Private Browsing extension has been developed by the community member Kurt Schultz! This extension adds a toolbar and a status bar button to Firefox for quick access to the Private Browsing feature, and lets you toggle a few of the underlying preferences as a bonus!  Grab it while it’s hot from AMO!

Here’s a screenshot provided by Kurt:

Toggle Private Browsing extension in action

Thanks for the great work, Kurt!

Tagged with: , , ,

Prepare your add-on for Private Browsing

Private Browsing is one of the new features of Firefox which extension developers should start to handle in their extensions.  The API for this new mode is quite straightforward, and easy to use.  In addition, theme developers may want to style Firefox differently inside the Private Browsing mode.  That is also insanely easy to do.  In this article, I’m going to give you an overview of how the API works, plus with some sample code.  Note that what I’m explaining here is based the latest features landed on Mozilla trunk, and I don’t expect any of them to break before the final release of Firefox 3.1, but we may land extra API support if add-on developers demand it, so make sure to leave your comments.

Notice: This post is targeted at Mozilla extension developers and theme designers.  See my previous post for a general overview of the Private Browsing mode.

Private Browsing mode for extension developers

First, a bit of background is in order.  Many extensions may store data which can be used to reveal the places that the user has visited.  Examples include a download manager/helper extension, an extension which manipulates Places information, an extension which stores or otherwise manipulates cookies, etc.  You may be wondering what it takes to ensure that your extension respects the user’s choice about the private mode.  The most important thing to note here is that the Private Browsing mode does not magically handle what your extension does in saving browsing history data; that is the job of each extension.

At the heart of our Private Browsing implementation lies the Private Browsing service.  This service, which can be accessed using the contract ID @mozilla.org/privatebrowsing;1, implements the nsIPrivateBrowsingService interface.  Here is the definition of this interface:

[scriptable, uuid(49d6f133-80c0-48c7-876d-0b70bbfd0289)]
interface nsIPrivateBrowsingService : nsISupports
{
    // When read, determines whether the private browsing mode is currently
    // active.  Setting to true enters the private browsing mode, and setting
    // to false leaves the private browsing mode.
    // Setting this value while handling one of the notifications generated
    // by the private browsing service throws NS_ERROR_FAILURE.
    attribute boolean privateBrowsingEnabled;

    // Determine whether the private browsing mode has been started
    // automatically at application startup.
    // This value will never be true if privateBrowsingEnabled is false.
    readonly attribute boolean autoStarted;
};

The privateBrowsingEnabled attribute is the most important one.  To get the current status of the Private Browsing service, it’s enough to get the value of this attribute.  To switch to the Private Browsing mode, this attribute should be set to true, and to exit this mode, it should be set to false.  The autoStarted attribute can be queried to determine whether the browser.privatebrowsing.autostart preference has triggered the private mode automatically at startup.

There are a number of notifications which the Private Browsing service sends out in order to notify extensions about the Private Browsing related events that happen at runtime.  When the Private Browsing mode is about to initiate, the service sends out the private-browsing-cancel-vote notification in order to ask all the observers if they are all OK with entering the private browsing mode.  The data parameter if this notification will be set to enter.  The subject parameter of this notification will be set to a nsISupportsPRBool object.  Extensions are supposed to set this object to true if they wish to prevent the browser from entering the Private Browsing mode (for example, if the extension is downloading a file which can’t be interrupted).  If none of the observers vote to cancel the mode transition, the Private Browsing mode will be activated.  This sends a private-browsing notification with the data parameter set to enter.

The reverse case happens when the Private Browsing service is requested to leave the private mode.  First, a private-browsing-cancel-vote notification is sent to check if all modules can handle the private mode switch.  The data parameter will be set to exit this time.  If no extension sets the subject parameter to true, then the private mode will be turned off, and a private-browsing notification will be sent with the data parameter set to exit.  One extra point to mention here is that the subject parameter of the private-browsing notification will be a nsISupportsPRBool which determines whether the mode is being terminated normally, or because of an application shutdown (true standing for the case of an application shutdown).

A few code samples will be useful here, to demonstrate the API.

Sample 1: check the status of the Private Browsing mode

This sample shows the most basic usage of the Private Browsing service: querying the current status of Private Browsing.

var pbs = Components.classes["@mozilla.org/privatebrowsing;1"]
                    .getService(Components.interfaces.nsIPrivateBrowsingService);

// are we currently in the Private Browsing mode?
var inPrivateBrowsingMode = pbs.privateBrowsingEnabled;

Sample 2: listen for Private Browsing notifications

This sample first defines a helper object to make the process of listening for Private Browsing mode changes easier, and then shows a small sample of how this can be used.

// Helper object to register listeners for Private Browsing mode changes
function PrivateBrowsingListener() {
  this.init();
}
PrivateBrowsingListener.prototype = {
  _os: null,
  _inPrivateBrowsing: false, // whether we are in private browsing mode
  _watcher: null, // the watcher object

  init : function () {
    this._inited = true;
    this._os = Components.classes["@mozilla.org/observer-service;1"]
                         .getService(Components.interfaces.nsIObserverService);
    this._os.addObserver(this, "private-browsing", false);
    this._os.addObserver(this, "quit-application", false);
    try {
      var pbs = Components.classes["@mozilla.org/privatebrowsing;1"]
                          .getService(Components.interfaces.nsIPrivateBrowsingService);
      this._inPrivateBrowsing = pbs.privateBrowsingEnabled;
    } catch(ex) {
      // ignore exceptions in older versions of Firefox
    }
  },

  observe : function (aSubject, aTopic, aData) {
    if (aTopic == "private-browsing") {
      if (aData == "enter") {
        this._inPrivateBrowsing = true;
        if (this.watcher &&
            "onEnterPrivateBrowsing" in this._watcher) {
          this.watcher.onEnterPrivateBrowsing();
        }
      } else if (aData == "exit") {
        this._inPrivateBrowsing = false;
        if (this.watcher &&
            "onExitPrivateBrowsing" in this._watcher) {
          this.watcher.onExitPrivateBrowsing();
        }
      }
    } else if (aTopic == "quit-application") {
      this._os.removeObserver(this, "quit-application");
      this._os.removeObserver(this, "private-browsing");
    }
  },

  get inPrivateBrowsing() {
    return this._inPrivateBrowsing;
  },

  get watcher() {
    return this._watcher;
  },

  set watcher(val) {
    this._watcher = val;
  }
};

// Here's how to use this helper

var listener = new PrivateBrowsingListener();

if (listener.inPrivateBrowsing) {
  // we are in the private mode!
} else {
  // we are not in the private mode!
}

listener.watcher = {
  onEnterPrivateBrowsing : function() {
    // we have just entered the private browsing mode!
  },

  onExitPrivateBrowsing : function() {
    // we have just left the private browsing mode!
  }
};

Please note that the onEnterPrivateBrowsing and onExitPrivateBrowsing functions are optional, and you can avoid declaring one if you don’t need it.  Also, note that the PrivateBrowsingListener object is safe to use in previous version of Firefox which did not have the Private Browsing service available.

Sample 3: turn Private Browsing on or off

This sample shows how extensions can switch to and from the Private Browsing mode.

var pbs = Components.classes["@mozilla.org/browser/privatebrowsing;1"]
                    .getService(Components.interfaces.nsIPrivateBrowsingService);

// enter the Private Browsing mode
pbs.privateBrowsingEnabled = true;

// now, whatever we do remains private!

// exit the Private Browsing mode
pbs.privateBrowsingEnabled = false;

Sample 4: prevent leaving the Private Browsing mode

This sample shows how an extension can prevent the browser from turning the Private Browsing mode off.

var os = Components.classes["@mozilla.org/observer-service;1"]
                   .getService(Components.interfaces.nsIObserverService);
os.addObserver(function (aSubject, aTopic, aData) {
    aSubject.QueryInterface(Components.interfaces.nsISupportsPRBool);
    // if another extension has not already canceled entering the private mode
    if (!aSubject.data) {
      if (aData == "exit") { // if we are leaving the private mode
        aSubject.data = true; // cancel the operation
      }
    }
  }, "private-browsing-cancel-vote", false);

Private Browsing mode for theme designers

Our goal here was to enable a CSS-only mechanism to allow theme designers to style the browser both outside and inside of the Private Browsing mode.  I simply added the browsingmode attribute to the window element in browser.xul.  The value of this attribute is normal when the user is outside the Private Browsing mode, and it’s switched to private when the user turns the Private Browsing mode on.  This allows having CSS rules to select any element inside the browser’s window inside the private browsing mode specifically, and styling them to your heart’s content.  For example, suppose that you would like the location bar to appear with a gray background while we’re inside the Private Browsing mode.  This can simply be done like below:

[browsingmode=private] #urlbar {
  background: #eee;
}

We have tried to keep everything as simple as we could, so if you feel there’s something which can be improved in the API, or need to ask a question, please do not hesitate to leave a comment here.  You’re feedback is appreciated.  Yes, really!

Update:  Modified Sample 2 to work in previous versions of Firefox.

Tagged with: , , ,

Don’t leave a trace: Private Browsing in Firefox

Today, a major feature was added to the pre-release versions of Firefox 3.1, called Private Browsing.  I’ve been working for quite some time on this, so I thought it may be a good time to write about what this feature is and how to use it.

As you may know, while you browse the web, your browser usually records a lot of data which will later be used to improve your browsing experience.  For example, it records a history of all the web pages you have visited, so that later if you need help remembering a site you visited a while back, it can assist you in finding that site.  Now, that is great, but there is a downside: those data can be used to trace your online activities.  For example, if your coworker sits at your computer, she can view all of your browsing history, which may not be what you want.

Suppose you’re doing something online, and you don’t want your coworkers know about it.  An example scenario would be looking for a new employer while at work!  One option would be to do your work, and then clear the data that Firefox has stored for you, such as history, cookies, cache, ….  But the problem is that this action will also remove the parts of your online activities data which you don’t want to hide, so the history that Firefox records can no longer be used to find a web site you had visited a month before.  Private Browsing will help you here.

Private Browsing aims to help you make sure that your web browsing activities don’t leave any trace on your own computer.  It is very important to note that Private Browsing is not a tool to keep you anonymous from websites or your ISP, or for example protect you from all kinds of spyware applications which use sophisticated techniques to intercept your online traffic.  Private Browsing is only about making sure that Firefox doesn’t store any data which can be used to trace your online activities, no more, no less.

So how does one actually use this feature?  It couldn’t be simpler!  To start, just select Private Browsing from the Tools menu.

To start, just select Private Browsing from the Tools menu.

You will see a dialog box which asks you whether you want to save and close all of your current windows and tabs, and start the Private Browsing mode.  Click Start Private Browsing to start your private session.

Click Start Private Browsing to start your private session.

After you do this, your non-private browsing session is closed and a new private session is opened, showing you the screen below.  (Before you mention, the ugly icon you see there is something I created as a placeholder!  This icon will be replaced in the final release of Firefox 3.1.)

Start of the Private Browsing mode

As you see, not much is different in the Firefox window inside the Private Browsing mode, except for the (Private Browsing) text added to the title bar at the top of the window.  That is intentional: after all, if you’re doing something online that you don’t want your coworkers to know about, you don’t want to raise their attention with a big sign saying PRIVATE as they pass by and glance over your shoulder. 

At this stage, you can start browsing web sites, without ever having to worry that Firefox might store something on your computer which can be used to tell which pages you have visited.  Once you’re done, just uncheck the same menu item in the Tools menu to close your private session.

Once you're done, just uncheck the same menu item in the Tools menu to close your private session.

 This action discards all of the data from your private session, and will restore your non-private browsing session, just like it was before entering the Private Browsing mode.

This action will restore your non-private browsing session, just like it was before entering the Private Browsing mode.

Now, as I mentioned at the top of this post, this feature is available in pre-release versions of Firefox 3.1 (what we geeks call nightly builds).  This feature will be included in Firefox 3.1 Beta 2 which will be released soon, so if you want to try it, you can give it a shot then.  And of course, it will appear in the final release of Firefox 3.1, so if you’re not the type who test beta software, you can wait until Firefox 3.1 is released.

Update:  As many people seem interested in knowing this, there is a way to make Firefox always start in Private Browsing mode.  Go to the about:config page, click I’ll be careful, I promise, type browser.privatebrowsing.autostart in the Filter text box, double click the entry to make its value true.  After doing this, the next time you start Firefox, it will start in private browsing mode automatically.  To turn this off, use the same steps to change the value of this preference to false.  There is a plan to provide an easier method to set this option in the final release of Firefox 3.1.

Tagged with: , , ,

First bits of the Private Browsing patch landed

I’m pleased to announce that the first pieces of the Private Browsing feature have just landed on Firefox trunk!  This might not be something to get too excited about, since all of the landed code remains disabled for now, but it’s a big breakthrough for me, considering the fact that I’ve been playing with this code since January!  Some of you may even remember that this feature was cut off Firefox 3 because of the fact that it was too big to take at that stage of Firefox 3 development, it will be included in the final release of Firefox 3.1.

Based on my latest chat with Marcia on IRC, the current plan is to finish the work on the code for private browsing, and land all of the remaining pieces by the end of October 26.  After that, during the week of October 27, we are going to have a test week for the community to start testing the Private Browsing mode to make sure that it will be rock solid in the final release.  Of couse, every piece of this patch has automated unit tests (on which Aaron has been helping me) to make sure that the feature at least works according to the functional specification, but a feature of this size still needs lots of human testing as well.  Stay tuned for more updates on the schedule.

A little bit more of technical details follows.  The pieces landed at this stage include the nsIPrivateBrowsingService, and the private browsing implementation and unit tests for the Places, Cookies, Content Preferences, and Form History modules.  These include all of the code necessary to implement Private Browsing handling in those modules, but because the implementation has been designed to ignore the absence of the Private Browsing service if it’s not available (like the case of these pieces of shared code using in other applications than Firefox), nothing will change in the functionality of these modules.  Those who want to test the Private Browsing mode should still run try server builds that I post to the Private Browsing bug.

For the details of what was checked in, check out the links below (pun intended):

Tagged with: , , ,
Top