O'Reilly

David Walsh Blog Firefox Toolbar

By on  

Update: The toolbar will now attempt to install when you click the link. .htaccess FTW!

I spent a few hours on Saturday doing something I've always wanted to learn how to do -- create a Mozilla Firefox extension ("addon"/plugin). I wanted to start with something fairly simple but useful so I created a David Walsh Blog toolbar. My toolbar provides quick links to different areas of my site as well as links to MooTools resources and recommended websites.

David Walsh Toolbar

While I'd love to do one article on how I created the plugin, I think it would end up being either 200 pages long or short without necessary details. Expect a few articles with regard to making Firefox extensions. You may also access all of this project's files on GitHub. Here's a quick summary of the code files.

The CSS

#davidwalshtoolbar-search-toolbar-box	{ color:#666; }
#davidwalshtoolbar-button-mootools		{ list-style-image:url("mootools.png"); min-width:100px; }
#davidwalshtoolbar-button-friends-csstricks	{ list-style-image:url("csstricks.png"); }
#davidwalshtoolbar-button-mootools > .toolbarbutton-menubutton-button { -moz-box-orient: horizontal; }

The XML / XUL

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://davidwalshtoolbar/skin/davidwalshtoolbar.css" type="text/css"?>
<overlay id="davidwalshtoolbar-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
	<script type="application/x-javascript" src="chrome://davidwalshtoolbar/content/davidwalshtoolbar.js" />
	<toolbox id="navigator-toolbox">
		<toolbar id="davidwalshtoolbar-toolbar" context="toolbar-context-menu" accesskey="d" class="chromeclass-toolbar" toolbarname="David Walsh Blog Toolbar" hidden="false" persist="hidden">
			
			<!-- Home -->
			<toolbarbutton label="David Walsh Blog" id="davidwalshtoolbar-button-home" accesskey="d" image="chrome://davidwalshtoolbar/skin/logo.png" oncommand="dwb_loadURL('http://davidwalsh.name');" tooltiptext="Click here to go to the David Walsh Blog homepage." />
			
			<!-- Sugar Menus -->
			<toolbarbutton label="Topics" id="davidwalshtoolbar-button-sugar" type="menu" accesskey="o" image="chrome://davidwalshtoolbar/skin/sugar.png" tooltiptext="Which sugar would you like to learn more about?">
				<menupopup>
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/htaccess');" label=".htaccess" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/ajax');" label="AJAX" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/apache-server');" label="Apache / Server" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/apis');" label="APIs" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/blog');" label="Blog" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/bookmarking');" label="Bookmarking / Social" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/books');" label="Books" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/browsers');" label="Browsers" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/css-design');" label="CSS / Design" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/google');" label="Google" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/guest-blogger');" label="Guest Blogger" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/hosting-domain');" label="Hosting / Domain" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/javascript');" label="Javascript" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/jquery');" label="jQuery" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/link');" label="link()" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/microsoft');" label="Microsoft" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/mootools');" label="MooTools" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/mysql');" label="MySQL" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/optimization');" label="Optimization" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/php');" label="PHP" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/poll');" label="Poll" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/rand');" label="rand()" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/security');" label="Security" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/shell');" label="Shell" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/theory-ideas');" label="Theory / Ideas" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/usability-accessibility');" label="Usability / Accessibility" />
					<menuitem oncommand="dwb_loadURL('http://davidwalsh.name/sugar/xml-xhtml');" label="XML / XHTML" />
				</menupopup>
			</toolbarbutton>
			
			<!-- Twitter -->
			<toolbarbutton label="Twitter" id="davidwalshtoolbar-button-twitter" accesskey="t" image="chrome://davidwalshtoolbar/skin/twitter.png" oncommand="dwb_loadURL('http://twitter.com/davidwalshblog');" tooltiptext="Follow the blog on Twitter!" />
			
			<!-- GitHub -->
			<toolbarbutton label="GitHub" id="davidwalshtoolbar-button-github" accesskey="g" image="chrome://davidwalshtoolbar/skin/git.png" oncommand="dwb_loadURL('http://github.com/darkwing');" tooltiptext="Grab my code on GitHub." />
			
			<!-- Chat -->
			<toolbarbutton label="Chat" id="davidwalshtoolbar-button-chat" accesskey="h" image="chrome://davidwalshtoolbar/skin/chat.png" oncommand="dwb_loadURL('http://davidwalsh.name/chat');" tooltiptext="Join #davidwalshblog chat on IRC!" />
			
			<!-- Contact -->
			<toolbarbutton label="Contact David Walsh" id="davidwalshtoolbar-button-chat" accesskey="n" image="chrome://davidwalshtoolbar/skin/contact.png" oncommand="dwb_loadURL('http://davidwalsh.name/contact');" tooltiptext="Get a hold of me." />
			
			<!-- (sep) -->
			<toolbarseparator />
			
			<!-- MooTools -->
			<toolbaritem>
				 <toolbarbutton label="MooTools" id="davidwalshtoolbar-button-mootools" type="menu-button" accesskey="m" oncommand="dwb_loadURL('http://mootools.net');" tooltiptext="Visit the MooTools website.">
					  <menupopup>
							<menuitem label="Download MooTools Core" class="menuitem-iconic" tooltiptext="Create a custom build of the MooTools Core." oncommand="dwb_loadURL('http://mootools.net/core'); event.stopPropagation();" />
							<menuitem label="Download MooTools More" class="menuitem-iconic" tooltiptext="Create a custom build of the MooTools More." oncommand="dwb_loadURL('http://mootools.net/more'); event.stopPropagation();" />
							<menuitem label="David Walsh MooTools Plugin Downloader" class="menuitem-iconic" tooltiptext="Download David Walsh's MooTools Plugins" oncommand="dwb_loadURL('http://davidwalsh.name/js'); event.stopPropagation();" />
							<menuitem label="MooTools on GitHub" class="menuitem-iconic" tooltiptext="Fork the MooTools project or browse the source!" oncommand="dwb_loadURL('http://github.com/mootools'); event.stopPropagation();" />
							<menuitem label="MooTools' LightHouse" class="menuitem-iconic" tooltiptext="File a ticket or submit a patch." oncommand="dwb_loadURL('http://mootools.lighthouseapp.com/'); event.stopPropagation();" />
							<menuitem label="MooTools Users Group" class="menuitem-iconic" tooltiptext="Connect with other MooTools users." oncommand="dwb_loadURL('http://groups.google.com/group/mootools-users'); event.stopPropagation();" />
							<menuitem label="The MooTools Team" class="menuitem-iconic" tooltiptext="Learn about the people behind the project." oncommand="dwb_loadURL('http://mootools.net/developers'); event.stopPropagation();" />
					  </menupopup>
				 </toolbarbutton>
			</toolbaritem>
			
			<!-- (sep) -->
			<toolbarseparator />
			
			<!-- Search -->
			<toolbaritem id="davidwalshtoolbar-search-toolbar-item" persist="width">
				 <textbox id="davidwalshtoolbar-search-toolbar-box" value="Search the blog..." flex="1" minwidth="100" width="150" onfocus="dwb_focus(true);" onblur="dwb_focus(false);" onkeypress="dwb_keypress(event);" />
			</toolbaritem>
			<toolbaritem flex="0">
				 <toolbarbutton id="davidwalshtoolbar-search-toolbar-button" label="Blog Search" tooltiptext="Search the David Walsh Blog" image="chrome://davidwalshtoolbar/skin/search.png" oncommand="dwb_searchBlog(event);event.stopPropagation();" />
			</toolbaritem>
			
			<!-- (sep) -->
			<toolbarseparator />
			
			<!-- Script n Style -->
			<toolbarbutton label="Script & Style" id="davidwalshtoolbar-button-sns" accesskey="s" image="chrome://davidwalshtoolbar/skin/sns.png" oncommand="dwb_loadURL('http://scriptandstyle.com');" tooltiptext="Great JavaScript and CSS articles submitted by you!" />
			
			<!-- Friends -->
			<toolbarbutton label="Friends" id="davidwalshtoolbar-button-friends" type="menu" accesskey="f" image="chrome://davidwalshtoolbar/skin/friends.png" tooltiptext="Check out these great sites.">
				<menupopup>
					<menuitem class="menuitem-iconic" oncommand="dwb_loadURL('http://clientcide.com');" label="ClientCide" image="chrome://davidwalshtoolbar/skin/clientcide.png" />
					<menuitem class="menuitem-iconic" oncommand="dwb_loadURL('http://og5.net/christoph');" label="Christoph Pojer" image="chrome://davidwalshtoolbar/skin/zilence.png" />
					<menuitem id="davidwalshtoolbar-button-friends-csstricks" label="CSS-Tricks" class="menuitem-iconic" tooltiptext="Chris Coyier's Blog" image="chrome://davidwalshtoolbar/skin/csstricks.png" oncommand="dwb_loadURL('http://css-tricks.com');" />
					<menuitem class="menuitem-iconic" oncommand="dwb_loadURL('http://eriwen.com');" label="Eric Wendelin" image="chrome://davidwalshtoolbar/skin/eriwen.png" />
				</menupopup>
			</toolbarbutton>
			
		</toolbar>
	</toolbox>
</overlay>

The JavaScript

/* forwards document to new URL */
function dwb_loadURL(url)
{
    window._content.document.location = url;
    window.content.focus();
}

/* executes the search */
function dwb_searchBlog()
{
	var term = document.getElementById('davidwalshtoolbar-search-toolbar-box').value;
	if(term.length > 0 && term != 'Search the blog...') dwb_loadURL('http://davidwalsh.name/?s=' + encodeURIComponent(term));
}

/* listen for focus/blur on the search box */
function dwb_focus(state)
{
	var box = document.getElementById('davidwalshtoolbar-search-toolbar-box');
	if(state) { //focus
		if(box.value == 'Search the blog...') box.value = '';
		box.select();
      box.style.color = '#000000';
	}
	else {
		if(box.value == '') {
			box.value = 'Search the blog...';
			box.style.color = '#666666';
		}
	}
}

/* listen for search commit via keyboard */
function dwb_keypress(event)
{
	if (event.keyCode == event.DOM_VK_RETURN) dwb_searchBlog();
}

Go ahead and download the toolbar if only to see what I put together. To install the toolbar in Firefox, click "File" >> "Open File," and Firefox will ask you to install the plugin.

I hope it sparks a desire for you to create your own Mozilla extension. Keep in mind the toolbar is version 0.1. Please share your thoughts and ideas!

Track.js Error Reporting

Recent Features

  • From Webcam to Animated GIF: the Secret Behind chat.meatspac.es!

    My team mate Edna Piranha is not only an awesome hacker; she's also a fantastic philosopher! Communication and online interactions is a subject that has kept her mind busy for a long time, and it has also resulted in a bunch of interesting experimental projects...

  • Create Namespaced Classes with MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each to their own.  In any event,...

Incredible Demos

  • Implement the Google AJAX Search API

    Let's be honest...WordPress' search functionality isn't great. Let's be more honest...no search functionality is better than Google's. Luckily for us, Google provides an awesome method by which we can use their search for our own site: the Google AJAX Search API....

  • Geolocation API

    One interesting aspect of web development is geolocation; where is your user viewing your website from? You can base your language locale on that data or show certain products in your store based on the user's location. Let's examine how you can...

Discussion

  1. Ahmed

    Sweet, now I know how to make a Firefox toolbar…
    I wish I could also know how to make search boxes or forms with checkboxes. Where’s the documentation?

  2. I’ve added a MIME type for .xpi to my server so that it will install the toolbar when you click it. Sweet!

  3. @David Walsh, how did you compile all of that into an .xpi? If you could explain that towards the end of the post that would really complete this. Thank you very much for sharing!

  4. Ahmed

    @David Walsh

    This is so cool! I’m so getting something similar done for my website heh :D

  5. @Dan: More to come. I couldn’t fit it into one post so I wanted to get this toolbar out first. Look forward to future articles breaking things down.

  6. Hi David,
    I think that this is one of the best articles/tutorial/snippet you wrote… I like it a lot
    Nunzio

  7. Nice work!! Great to see you hacking a Firefox add-on together! :D

  8. Very nice! I tried to make a Firefox addon last year and had hard time with it. Using this, I might be able to get somewhere next time.

  9. @Ryan: Apart from David’s excellent article, I’d recommend looking at this recent posting by Robert Nyman:

    http://robertnyman.com/2009/01/24/how-to-develop-a-firefox-extension/

  10. @Ryan: Thank you, but this is only the release post. I’ll have many more about creating a plugin to come. I promise to explain this better.

    @Rey Bango: Thank you for sharing!

  11. Great!!! I was curious about a subject but did not try at all. I think I can do a few experiments now. Thank you!!!

  12. Shrike

    Do you know how to do a periodical ajax request for example for check messages like google toolbar?

    Thanks

    ps. I suggest you to add the updateUrl in the install.rdf for check updates ;)

    https://developer.mozilla.org/en/Extension_Versioning,_Update_and_Compatibility

  13. Thank you for the inspiration. Here is a preview of mine. http://twitpic.com/5a7p4

  14. Great addition,

    Already install it and made one for my site using yours as a template.

    I hope you continue with this and add a mini tutorial for adding login support to a page.

    Regards,
    Alex

  15. Spooky

    Not working with FF 3.5 :(

  16. I recently came across your blog and have been reading along. I thought I would leave my first comment. I don’t know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often.

    Susan

    http://8080proxy.com

  17. You need to update the maximum version of Firefox your toolbar can be installed on. I put my toolbar to Firefox version 8.*.* . Try that and it will save you time updating it every time for users to use.

  18. Could you please update the version number. It will not install on Firefox 3.6.13

  19. Your GitHub link is 404ing :(

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • OSCON Portland:  Conference  Discount!

    O'Reilly puts on the best web industry conferences in the world.  These conferences include Fluent Conference, Velocity Conference, and the upcoming OSCON in Portland, Oregon from July 20-24.  Open Source Convention (OSCON) is a conference that focuses specifically on open source developers and the tools and possibilities...

  • Follow Redirects with cURL

    I love playing around with cURL. There's something about loading websites via command line that makes me feel like some type of smug hacker, just like tweeting from command line does. I recently cURL'd the Google homepage and saw the following: I found it weird that Google...

  • Developers Have WordPress, Amateurs Have Squarespace, Professional Designers Have the NEW Webydo!

    Web design platforms have traditionally come in one of two varieties. There are the solutions like WordPress and Drupal that are incredibly powerful, but an understanding of web development and coding is required to be able to use those platforms effectively. On the other side of the...

  • Chris Coyierâs Favorite CodePen Demos II

    Hey everyone! Before we get started, I just want to say it’s damn hard to pick this few favorites on CodePen. Not because, as a co-founder of CodePen, I feel like a dad picking which kid he likes best (RUDE). But because there is just so...

  • GSAP + SVG For Power Users: Motion Along A Path

    Now that the GreenSock API is picking up steam, there are many tutorials and Getting Started guides out there to provide good introductions to the library, not to mention GreenSock’s own Forum and Documentation. This article isn’t intended for beginners, but rather a...