mozilla

Revision 515237 of Add a Menu Item to Firefox

  • Revision slug: Mozilla/Add-ons/SDK/Tutorials/Add_a_Menu_Item_to_Firefox
  • Revision title: Add a Menu Item to Firefox
  • Revision id: 515237
  • Created:
  • Creator: wbamberg
  • Is current revision? No
  • Comment

Revision Content

To follow this tutorial you'll need to have installed the SDK and learned the basics of cfx.

The SDK doesn't yet provide an API to add new menu items to Firefox. But it's extensible by design, so anyone can build and publish modules for add-on developers to use. Luckily, Erik Vold has written a menuitems module that enables us to add menu items.

This tutorial does double-duty. It describes the general method for using an external, third-party module in your add-on, and it describes how to add a menu item using the menuitems module in particular.

First, create a new add-on. Make a directory called "clickme" wherever you like, navigate to it and run cfx init.

mkdir clickme
cd clickme
cfx init

The usual directory structure will be created:

  • clickme
    • data
    • docs
      • main.md
    • lib
      • main.js
    • package.json
    • README.md
    • tests
      • test-main.js
 

Installing menuitems

Create a directory under "clickme" called "packages". Then download the menuitems package from https://github.com/mykmelez/menuitems-jplib and extract it into the "packages" directory you just created:

mkdir packages
cd packages
tar -xf ../erikvold-menuitems-jplib-d80630c.zip

Module Dependencies

If third-party modules only depend on SDK modules, you can use them right away, but if they depend on other third-party modules, you'll have to install those dependencies as well.

In the package's main directory you'll find a file called "package.json". Open it up and look for an entry named "dependencies". The entry for the menuitems package is:

"dependencies": ["vold-utils"]

This tells us that we need to install the vold-utils package, which we can do by downloading it from https://github.com/mykmelez/vold-utils-jplib and adding it under the packages directory alongside menuitems.

Using menuitems

The documentation for the menuitems module tells us to create a menu item using MenuItem(). Of the options accepted by MenuItem(), we'll use this minimal set:

  • id: identifier for this menu item
  • label: text the item displays
  • command: function called when the user selects the item
  • menuid: identifier for the item's parent element
  • insertbefore: identifier for the item before which we want our item to appear
var menuitem = require("menuitems").Menuitem({
  id: "clickme",
  menuid: "menu_ToolsPopup",
  label: "Click Me!",
  onCommand: function() {
    console.log("clicked");
  },
  insertbefore: "menu_pageInfo"
});
 

Next, we have to declare our dependency on the menuitems package. In your add-on's package.json add the line:

"dependencies": "menuitems"

Note that due to bug 663480, if you add a dependencies line to package.json, and you use any modules from the SDK, then you must also declare your dependency on that built-in package, like this:

"dependencies": ["menuitems", "addon-sdk"]

Now we're done. Run the add-on and you'll see the new item appear in the Tools menu: select it and you'll see info: clicked appear in the console.

Caveats

Third-party modules are a great way to use features not directly supported by the SDK, but because third party modules typically use low-level APIs, they may be broken by new releases of Firefox.

 

Revision Source

<div class="note">
 <p>To follow this tutorial you'll need to have <a href="/en-US/Add-ons/SDK/Installation">installed the SDK</a> and learned the <a href="/en-US/Add-ons/SDK/Getting_Started_With_cfx">basics of <code>cfx</code></a>.</p>
</div>
<p>The SDK doesn't yet provide an API to add new menu items to Firefox. But it's extensible by design, so anyone can build and publish modules for add-on developers to use. Luckily, Erik Vold has written a <a href="https://github.com/mykmelez/menuitems-jplib"><code>menuitems</code></a> module that enables us to add menu items.</p>
<p>This tutorial does double-duty. It describes the general method for using an external, third-party module in your add-on, and it describes how to add a menu item using the <code>menuitems</code> module in particular.</p>
<p>First, create a new add-on. Make a directory called "clickme" wherever you like, navigate to it and run <code>cfx init</code>.</p>
<pre>
mkdir clickme
cd clickme
cfx init
</pre>
<p>The usual directory structure will be created:</p>
<ul>
 <li>clickme
  <ul>
   <li>data</li>
   <li>docs
    <ul>
     <li>main.md</li>
    </ul>
   </li>
   <li>lib
    <ul>
     <li>main.js</li>
    </ul>
   </li>
   <li>package.json</li>
   <li>README.md</li>
   <li>tests
    <ul>
     <li>test-main.js</li>
    </ul>
   </li>
  </ul>
 </li>
</ul>
<div>
 &nbsp;</div>
<h2 id="Installing_menuitems">Installing <code>menuitems</code></h2>
<p>Create a directory under "clickme" called "packages". Then download the <code>menuitems</code> package from <a href="https://github.com/mykmelez/menuitems-jplib/zipball/4d6ae5b410d79cc16c9c76920fbaa8a367e44ca7">https://github.com/mykmelez/menuitems-jplib</a> and extract it into the "packages" directory you just created:</p>
<pre>
mkdir packages
cd packages
tar -xf ../erikvold-menuitems-jplib-d80630c.zip
</pre>
<h2 id="Module_Dependencies">Module Dependencies</h2>
<p>If third-party modules only depend on SDK modules, you can use them right away, but if they depend on other third-party modules, you'll have to install those dependencies as well.</p>
<p>In the package's main directory you'll find a file called "package.json". Open it up and look for an entry named "dependencies". The entry for the <code>menuitems</code> package is:</p>
<pre>
"dependencies": ["vold-utils"]
</pre>
<p>This tells us that we need to install the <code>vold-utils</code> package, which we can do by downloading it from <a href="https://github.com/mykmelez/vold-utils-jplib/zipball/a321447dc5d613df33023165854957c181dc3174">https://github.com/mykmelez/vold-utils-jplib</a> and adding it under the <code>packages</code> directory alongside <code>menuitems</code>.</p>
<h2 id="Using_menuitems">Using <code>menuitems</code></h2>
<p>The <a href="https://github.com/mykmelez/menuitems-jplib/blob/master/docs/menuitems.md">documentation for the <code>menuitems</code> module</a> tells us to create a menu item using <code>MenuItem()</code>. Of the options accepted by <code>MenuItem()</code>, we'll use this minimal set:</p>
<ul>
 <li><code>id</code>: identifier for this menu item</li>
 <li><code>label</code>: text the item displays</li>
 <li><code>command</code>: function called when the user selects the item</li>
 <li><code>menuid</code>: identifier for the item's parent element</li>
 <li><code>insertbefore</code>: identifier for the item before which we want our item to appear</li>
</ul>
<div>
 <div>
  <pre class="brush: js">
var menuitem = require("menuitems").Menuitem({
  id: "clickme",
  menuid: "menu_ToolsPopup",
  label: "Click Me!",
  onCommand: function() {
    console.log("clicked");
  },
  insertbefore: "menu_pageInfo"
});</pre>
  <div>
   &nbsp;</div>
 </div>
</div>
<p>Next, we have to declare our dependency on the <code>menuitems</code> package. In your add-on's <code>package.json</code> add the line:</p>
<pre>
"dependencies": "menuitems"
</pre>
<p>Note that due to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=663480">bug 663480</a>, if you add a <code>dependencies</code> line to <code>package.json</code>, and you use any modules from the SDK, then you must also declare your dependency on that built-in package, like this:</p>
<pre>
"dependencies": ["menuitems", "addon-sdk"]
</pre>
<p>Now we're done. Run the add-on and you'll see the new item appear in the <code>Tools</code> menu: select it and you'll see <code>info: clicked</code> appear in the console.</p>
<h2 id="Caveats">Caveats</h2>
<p>Third-party modules are a great way to use features not directly supported by the SDK, but because third party modules typically use low-level APIs, they may be broken by new releases of Firefox.</p>
<p>&nbsp;</p>
Revert to this revision