Opening links from menus, the right way

Here’s what I currently do to open a link from a menu, respecting what the user actually wants to happen and without repeating code.

<!-- ... -->
<menuitem oncommand="myExtension.foo(event)" onclick="checkForMiddleClick(this, event)"/>
<!-- ... -->
/* ... */
foo: function(event) {
  myExtension.openURL(event, "theKey");
},
openURL: function(event, key) {
  openUILinkIn(myExtension.urlStrings.getString(key), whereToOpenLink(event));
},
/* ... */

What to take note of:

  • openUILinkIn, whereToOpenLink, and checkForMiddleClick are part of Firefox’s utilityOverlay.js. This file is included in browser.xul so its functions are available to browser overlays.
  • oncommand handles regular clicks, but isn’t fired for middle-clicks. We make use of Firefox’s checkForMiddleClick, which will call our oncommand function for middle clicks and do nothing otherwise.
  • whereToOpenLink figures out the appropriate place to open of the new link (current tab, new tab, new window, etc.) based on the mouse button and/or keys pressed and/or user preferences. We pass it as openUILinkIn’s second parameter.
  • The functions are in a wrapper.
  • The function foo only needs to know the key of the URL property. This reduces repetition if you have do create bar, baz, etc.
  • The URL is stored in a properties file (urlStrings is a reference to a stringbundle). This properties file should be stored under content, not locale, as it doesn’t change for different languages.

Any additional suggestions?

Updates

  • Feb 8, 2007: I forgot about middle clicks!
  • Feb 17, 2007: Changed to use Firefox’s checkForMiddleClick function, thanks LouCypher!
  • May 22, 2007: Now available at developer.mozilla.org.

7 Responses to “Opening links from menus, the right way”

  1. Tucana Says:

    Very good explanation… thanks a lot! :)

    I only think that for a complex menu is more practice to insert urls directly in the menuitems in the xul file as a parameter for the function, for example:

    and then modify a little the openURL function.
    What do you think about?

  2. Tucana Says:

    The code is not showed, was:

  3. Tucana Says:

    Last retry…

    menuitem oncommand=”myExtension.openURL(event, ‘url’)” onclick=”myExtension.openURL(event, ‘url’)”

  4. LouCypher Says:

    I usually use oncommand="openUILink(url, event, false, true)" and onclick="checkForMiddleClick" on menuitems for browser overlay.

  5. LouCypher Says:

    Oops… it’s onclick="checkForMiddleClick(this, event)"

    … on menuitems for browser overlay.

    Also on toolbarbuttons.

  6. jason Says:

    Tucana, storing the URLs separately makes it easier to make changes, for example if your server changes or you’re rebranding your extension. If you’re only doing this for one URL, I don’t see anything wrong with including it directly in the XUL.

  7. jason Says:

    LouCypher, that function looks like it going through the same process as I am (doing the command on middle click and making sure to close the menu). I’ll try it out and if it works, I’ll update the code I posted to use it instead to reduce repetition. Thanks!

Leave a Reply

Adventures in development - Web standards and Firefox extensions