Shortest Tutorial for Firefox Extension/Toolbar Development!

ADVERTISEMENTS

About This Tutorial: From long time I wanted to write this but was always running out of time as the topic is complicated and too long! I always like to come-up with simple ways of doing geekish things as this Devils Workshop have great variance in its audience. So writing a post for all is always cumbersome but still lets see how it goes.

Who Should Read This: This is for anyone who is new to firefox extension development. More accurately for the geeks who haven’t coded any extension for firefox yet! This is just to build foundation, to kick-start yourself!

About Example Covered: The example covered with this tutorial is a toolbar with just one feature: Google Search! And lets call it: GoogBar! (You can Download Source here)

Following Points are Covered: Firefox extension development can easily swamp many books (with scary volume numbers) we will try to cover following points…

  • Section 0: Prerequisites, Tools & References
  • Section 1: Basic File Structure Layout
  • Section 2: Creating Metadata - Dealing with Important files
  • Section 3: Creating Graphical User Interface - GUI
  • Section 4: Implementing Backend functions
  • Section 5: Packaging Extension for distribution!
  • Section 6: Installing & Testing Your Extension!

Section 0: Prerequisites, Tools & References!

Prerequisites: Little knowledge of HTML/XHTML, XML, JavaScript, and CSS.

Tools: Any text-editor which supports HTML/Javascript/CSS syntax-highlighting will be great. I use vi/gedit (on Linux) and notepad (on Windows)

References: I started with tutorial at BornGeeK and still find it useful. In fact its greatness will reflect throughout this post. Still you may find these useful

Section 1: Basic File Structure Layout

Lets go other way round - Outside-In!

Firefox extensions filename ends with xpi extension. For time being assume xpi = zip. In fact xpi is just zip archive! So what this archive contains?

It will contain atleast: 2 files - install.rdf & chrome.manifest + 1 folder - usually named chrome!

Firefox extensions require a specific internal file structure. To ensure this few files/folders will always have fixed place while optional files/components have little freedom to move around. Lets move ahead with an example extension: GoogBar so as keep track of extension development! Lets start by creating a directory - GoogBar and other files/folder structure under it as shown below…

+- GoogBar/
    +- content/
    +- install.rdf
    +- chrome.manifest

install.rdf & chrome.manifest are just plain-text file so create two empty text files and rename them to install.rdf & chrome.manifest.

Important Note: Be careful while renaming files on windows as extension part often remains unchanged. Make sure to rename something like new.txt to install.rdf and not install.rdf.txt!

Section 2: Creating Metadata - Dealing with Important files

Metadata means data about data! All the metadata is stored in install.rdf & chrome.manifest.

A. install.rdf file

This is XML file. It contains metadata identifying the addon, providing information about who created it, where more information can be found about it, which versions of what applications it is compatible with, how it should be updated, and so on. We have already created empty install.rdf file. Its time to fill it up!

+- GoogBar/
    +- content/
    +- install.rdf
    +- chrome.manifest

Given below is sample installer manifest. Copy it to your install.rdf file and edit highlighted fields!

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<!-- Required Items -->
<em:id>extensionname@yourdomain.com</em:id>
<em:name>Extension's Name</em:name>
<em:version>1.0</em:version>

<em:targetApplication>
     <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>1.5</em:minVersion>
         <em:maxVersion>3.0.*</em:maxVersion>
     </Description>
</em:targetApplication>

<!-- Optional Items -->
<em:creator>Your Name</em:creator>
<em:description>A description of the extension</em:description>
<em:homepageURL>http://www.yoursite.com/</em:homepageURL>
</Description>
</RDF>

Explanation of Highlighted Fields:

extensionname@yourdomain.com: This must be unique as this is id of your extension. So make sure you chose an extension/domain name pair which is not in use by others! Ex. GoogBar@devilsworkshop.org (Note: You do not need to purchase a domain to make this unique! Use any domain like yourfullname.com or microsoft.com (I don’t think they have sportsman spirit to develop anything for firefox)

Extension’s Name: This is name of your extension seen by humans! So use something nice & descriptive!

version: The only point I can tell you about version numbers here is they always goes on increasing with updates. So do not bother about this too much at this point.

targetApplication - minVersion & maxVersion: These are minimum and maximum versions of firefox you are targeting!

Optional Items: I guess all have descriptive name. Also there are more than shown in this example. So keep this tutorial short I am skipping details about this optional items!

Important Note: Do not change value {ec8030f7-c20a-464f-9b0e-13a3a9e97384} in above sample! It is GUID of Firefox!

So GoogBar’s install.rdf will look like…

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<!-- Required Items -->
<em:id>googbar@devilsworkshop.org</em:id>
<em:name>GoogBar</em:name>
<em:version>1.0</em:version>

<em:targetApplication>
     <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>1.5</em:minVersion>
         <em:maxVersion>3.0.*</em:maxVersion>
     </Description>
</em:targetApplication>

<!-- Optional Items -->
<em:creator>Rahul Bansal</em:creator>
<em:description>A Firefox toolbar with Google Search facility!</em:description>
<em:homepageURL>http://www.devilsworkshop.org/</em:homepageURL>
</Description>
</RDF>

Additional Resources: http://developer.mozilla.org/en/docs/Install_Manifests

B. chrome.manifest file

A chrome manifest is how we tell Firefox what packages and overlays our extension provides. In simple words it tells firefox what our extension does! Now its time to fill up chrome.manifest

+- GoogBar/
    +- content/
    +- install.rdf
    +- chrome.manifest

Let us again take a look at a sample file. This sample is particularly taken for this tutorial as chrome.manifest may contains lots of other information too! Replace highlighted extensionname with your extension name!

content extensionname content/
overlay chrome://browser/content/browser.xul chrome://extensionname/content/overlay.xul

So final Googbar’s chrome.manifest file will look like

content googbar content/
overlay chrome://browser/content/browser.xul chrome://googbar/content/googbar.xul

Let me give you a little more explanation about above two lines…

Line 1 tells: content (Read Functions) by this extension are in content/ directory! All functions which we will be implementing soon as javascript files will be kept in content/ directory!

Line 2 tells: overlay (Read User Interface) information for this extension is in googbar.xul file in content subdirectory! We will be creating goobar.xul soon! In fact we can create XUL file with any other name!

Additional Resources: http://developer.mozilla.org/en/docs/Chrome_Manifest

Section 3: Creating Graphical User Interface - GUI

Most Firefox extensions have one goal in common: wanting to add or change some graphical element(s) in Firefox. Fortunately adding and modifying GUIs is quite easy. But this ease comes with a dedicated language developed for firefox GUI called XUL (pronounced “zool”). XUL stands for XML User-Interface Language, so if you know XML then I bet you can learn XUL in few minutes!

Enough chit-chat, now its time for creating googbar.xul under content subdirectory! So our tree will look like…

+- GoogBar/
    +- content/
       +- googbar.xul
    +- install.rdf
    +- chrome.manifest

First write (copy) following non-optional XML declaration as it is…

<?xml version="1.0"?>
<overlay id="Scrapper-Overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
</overlay>

Then comes script tag! Let me brief first scripts coming into picture. Note the sequence of event!

  1. In this XUL file we will be adding a toolbar with one text field and a button.
  2. We want some code to be executed when someone press the button.
  3. So pressing button should call the code. Now we can write code in
    • this XUL file itself: OK for small code but bad practice!
    • in separate JS file

At this point we made decision to create a separate JS file but this XUL file should be aware of it so that it can associate buttons with JS file code. For this we will be using script tag! Just paste following code before </overlay> tag.

<script type="application/x-javascript" src="chrome://googbar/content/googbar.js" />

Note googbar.js filename above. We will be creating it soon.

Now time come to create toolbar using following XUL code!

All toolbars in Firefox should live within a toolbox element which gets placed inside the overlay element we created moments ago:

<toolbox id="navigator-toolbox"></toolbox>

We will place toolbar and its component inside the toolbox we just specified. Toolbar is basically row of buttons, text-field & labels. Here comes our toolbar with one label (to show toolbars name), one textbox (to specify search query) & one button (to fire search request):

<toolbar id="GoogBarToolbar" toolbarname="GoogBar Toolbar" >
       <label value="GoogBar Toolbar: "/>
       <textbox id="GoogBarQuery" cols="1" size="50" />
       <toolbarbutton id="GoogBarButton"
         label="Search" oncommand="GoogBarSearch(event)" />
</toolbar>

Some attribute values are important as they might be used from elsewhere. In that regard attribute values to note are:

  • GoogBarSearch(event) value in toolbarbutton elements oncommand attribute
  • GoogBarQuery value in textbox elements id attribute

We will be shortly using these in our next file googbar.js as we are done with googbar.xul which finally looks like…

<?xml version="1.0"?>
<overlay id="Scrapper-Overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"><script type="application/x-javascript" src="chrome://googbar/content/googbar.js" />
<toolbox id="navigator-toolbox">
   <toolbar id="GoogBarToolbar" toolbarname="GoogBar Toolbar" >
       <label value="GoogBar Toolbar: "/>
       <textbox id="GoogBarQuery" cols="1" size="50" />
       <toolbarbutton id="GoogBarButton"
         label="Search" oncommand="GoogBarSearch(event)" />
   </toolbar>
</toolbox>
</overlay>

Important Note: All id/name attribute must be unique as they will be going to global by default! That’s why everytime we need to name something we prefixed it with GoogBar!

Additional Resources:

Section 4: Implementing Backend Functions

Let’s now create our JavaScript file - googbar.js in the content directory! That will make our structure look like…

+- GoogBar/
    +- content/
       +- googbar.xul
       +- googbar.js
    +- install.rdf
    +- chrome.manifest

As we highlighted in previous section we will now implement GoogBarSearch(event) function which will make use of GoogBarQuery id. This function will perform following steps:

  1. Access user query written in textbox using textbox id GoogBarQuery.
  2. Use that value to shoot Google Search Query!

This can be accomplished with following codes. Also thats all googbar.js will have!

function GoogBarSearch(event){
    var query = document.getElementById("GoogBarQuery").value;
    window._content.document.location  = "http://www.google.com/search?q=" + encodeURI(query);
}

Section 5: Packaging Extension for distribution!

Yes we are done! So lets pack the things the way firefox like! Your aim is to create a archive which contains everything inside GoogBar excluding GoogBar itself! Then to make sure that archive has xpi extension!

Packaging on Linux:

  • From shell execute zip command with format:
zip <extensionname>.xpi chrome.manifest install.rdf content/* <optional files>
  • In our case command needs to be fired is:
zip googbar.xpi chrome.manifest install.rdf content/*

Packaging on Windows:

  • Use any zip utility to create a zip file which consists everything inside top-level extension directory! DO NOT include top-level directory itself! OR just select files and folder(s) using control+click and then right-click on selection, select Send To >> compressed (zipped) folder! You will get a zip file with name like googbar.zip or content.zip or something like that!
  • Just rename it to googbar.xpi (i.e. extensionname.xpi). Also ensure renaming operation as from Windows explorer you may end up renaming file to something like googbar.xpi.zip!

Thats it! Its time to test our work! :-)

Section 6: Installing & Testing Your Extension!

Just drag-n-drop googbar.xpi on Firefox. OR Go to Firefox, execute File >> Open (or press ctrl+O) and navigate to location of googbar.xpi and open it up! This will open a pop-up, click Install Now to proceed and restart firefox to complete installation!

After restarting you will see GoogBar below Navigation Toolbar. Also check View >> Toolbars in firefox to confirm it further!

Successful Installtion - Firefox Extension Development Tutorial by Devils Workshop

Type something in text-box and press search! DO NOT just type & hit enter as we havent configured text-box to process any keyboard event so you won’t get any result until you press search button! Well that we can easily do by modifying googbar.xul and goobar.js!

Example Search - - Firefox Extension Development Tutorial by Devils Workshop

If you are feeling cheated by my words Shortest Tutorial then go anywhere on the web and try finding a shorter version of this! ;-)

As ususal comments, suggestion, question, etc are all welcome! :-)

Next part in series - Setting Up Firefox as IDE for Firefox Extension Development

Links: Download Source for Googbar

Share and Enjoy:
  • Digg
  • del.icio.us
  • IndianPad
  • StumbleUpon
  • Technorati
  • YahooMyWeb
  • Furl
  • Reddit
  • Google
  • TwitThis
  • Facebook
  • Slashdot
  • SphereIt
  • blogmarks
  • MisterWong

Comment RSS · TrackBack URI

51 Comments (including Pingbacks/Trackbacks) so far »

  1. #
    Pablo on October 10, 2007

    The bar doesn’t appear in my browser. Nor in View->Toolbars. It does appear as installed in Web->Add-ons

  2. #
    Rahul Bansal on October 10, 2007

    I guess there might be some mistake!
    Can you send me your XPI file so that I can check it for errors…
    Mail me that on my email id: rahul@devilsworkshop.org :-)

  3. #
    Mark R. on October 23, 2007

    Very helpful, thanks mate :)

  4. #
    Searcher on November 9, 2007
  5. #
    Rahul Bansal on November 14, 2007

    @Mark
    Ur welcome buddy! :-)

  6. #
    Rahul Bansal on November 14, 2007

    Seems Nice… Wil have a look at it soon! :-)

  7. #
    Allan Miller on December 10, 2007

    How do you debug the javascript code? I can’t get Firebug to show it.

  8. #
    Rahul Bansal on December 11, 2007

    @Allan
    I wonder if firebug will show you javascript code embedded in extension.

    But you can choose to write debug messages to Error console or use alert() or develop code iteratively!

    Also google for live firefox development! :-)

    By the way thanx 4 ur comment! I guess we need to explore this debugging topic further!

  9. #
    rav on December 21, 2007

    thank you so much! it work perfectly!

  10. #
    Rahul Bansal on December 21, 2007

    @rav
    Ur welcome buddy! :-)

  11. #
    Allan Miller on December 21, 2007

    OK, I think the answer is that there’s no way to get Firebug to do this. I appreciate the suggestions for using printf-style debugging, but I really can’t work without a real debugger. Anyway, the good news is that the Venkman debugger can debug the toolbar, as long as you tell it to show ALL modules. So, I think that’s probably the real answer.

  12. #
    Hari on January 5, 2008

    Is I put some js functions inside googbar.js, shall I access from html page? (from script tag)

  13. #
    Rahul Bansal on January 9, 2008

    @Hari
    First Sorry for late reply as I went offline for a 5-days vacations! :-(

    Now I am sorry to say this but I am not able to get what you are trying to accomplish. :-(

    Script tag in HTML pages…
    there is src attribute by which .js files are loaded. Now src needs URL and js files bundled within firefox extensions may not be accessed this way!

    If you want to execute js on some HTML pages…
    You can use event handling. It gives you maximum control.

    There is more but I afraid I will end up confusing you without anymore inputs from you…
    So do write in details!

    -Rahul :-)

  14. #
    Allan Miller on January 11, 2008

    So, I got back to this, and yes, the answer is to use Venkman. When you run Venkman, under the “Debug” menu, uncheck the setting that says “Exclude Browser Files”, and then you can debug the toolbar. I don’t believe there is any equivalent function in Firebug.

  15. #
    Rahul Bansal on January 11, 2008

    @Allan
    Thanks Allan for finding Venkman and posting about it here… :-)
    I will be writing part 2 of this post soon where I will post about your finding…
    thanks again.. :-)

    -Rahul

  16. #
    tbankar on January 14, 2008

    Hi Rahul,
    That was very nicely presented tutorial and
    Indeed a shorter one!!! :D

    Many thanks !!!

    So taking a inspiration from this tutorial, I m planning to develop my own extensions. To just start with i m planning make a extension which will popup at the browser’s bottom right hand corner whenever I make changes to my website.
    Any ideas how should i go with?? Any links/resources you would like to suggest??

    Thanks again and keep posting such simple and shorter tutorials… Best wishes to you.

  17. #
    Rahul Bansal on January 14, 2008

    @tbankar
    First thanks for nice and inspiring comments!

    Now technologywise firefox addon doesnt require much.. (Only Javascript, CSS, XML, HTML)

    Keep google search box handy. And if you want to talk to other developers whenever you encounter errors use #extdev channel on irc server: irc.mozilla.org

    Rest we are here always! :-)

  18. #
    tbankar on January 15, 2008

    Thank you Rahul :D

  19. #
    Rahul Bansal on January 15, 2008

    @tbankar
    Your welcome buddy! :-)

  20. #
    WIndhan on January 17, 2008

    Hi Rahul,

    I tried out Album Hack Script in Orkut.
    It worked for me Yesterday but not working today, hope Orkut rectified it, Can u tell me y its not working for me now?

  21. #
    Rahul Bansal on January 17, 2008

    @WIndhan
    Ya. Orkut rectified it. So right now we do not have any working hack to view albums. Anyway if I find a new hack I will definitely post it here!

    You may subscribe to my RSS feed or email alert to receive automatic updates in future!

    AND PLEASE DO NOT post comments randomly on any topic.

  22. #
    Yu-Teh on January 24, 2008

    the message is like this:

    &lt script type=application/x-javascript
    ^
    src=chrome://googbar/content/googbar.js /&rt

  23. #
    Rahul Bansal on January 24, 2008

    @Yu-Teh
    I am aware of kind of message you are getting!
    Just replace &lt with &lt; [Note semicolon]

    In fact all HTML entities must end with a semicolon :-)

    If problem persists consider emailing your code to me for further discussion!

  24. #
    Yu-Teh on January 24, 2008

    Thanks a lot.
    I have fixed the problem.

  25. #
    jasmeet on January 27, 2008

    hi rahul,
    ur article is really help.
    could u plz povide some help about how i can add a lyrics search engine to my self made firfox toolbar!!!!
    waiting for ur reply
    thank you!!

  26. #
    Rahul Bansal on January 29, 2008

    @Yu-Tech

    First sorry for late reply as I was away on vacation…

    Hope u r enjoying programming firefox addons.. :-)

  27. #
    Rahul Bansal on January 29, 2008

    @jasmeet
    First sorry for late rep as I was on vacations…

    Now about lyrics search engine
    First tell me whether you have any specialized search engine on your mind or you just want to google across lyrics sites.

    All we have to analyze query structure and modify googbar.js file accordingly… :-)

  28. #
    K-CI on January 31, 2008

    Hey. thanks..

    very nice job~!!!

    It’s the one of the nicest articles about FF Extension I’ve ever got~!
    I’m looking forward to the next article :)

    anyhow,
    can I ask a question here??
    I would like to run an windows application.
    I’ve checked out a couple of articles and other extensions. but I haven’t got the answer…
    I think there’s something wrong with the path for the application..

    I just write following code in a function.

    I’m sure the functions is called..
    but it doesn’t work as I expect…

    var file = Components.classes["@mozilla.org/file/local;1"]
    .createInstance(Components.interfaces.nsILocalFile);
    file.initWithPath(C:\Program Files\Daum\something\something.exe);

    // create an nsIProcess
    var process = Components.classes["@mozilla.org/process/util;1"]
    .createInstance(Components.interfaces.nsIProcess);
    process.init(file);

    // Run the process.
    // If first param is true, calling thread will be blocked until
    // called process terminates.
    // Second and third params are used to pass command-line arguments
    // to the process.
    var args = ["argument1", "argument2"];
    process.run(false, args, args.length);

  29. #
    Rahul Bansal on January 31, 2008

    @K-CI
    Sure man… I am planning next article in this series. It will be about speeding up extension development!

    Now about your problem…

    Try changing file.initWithPath(C:\Program Files\Daum\something\something.exe);

    to file.initWithPath(”C:\\Program Files\\Daum\\something\\something.exe”);

    Note quotes ["] around path name as well as ‘\\’ double backslash instead of ‘\’ single backslash…

    Let me know if you need more help… :-)

  30. #
    K-CI on February 1, 2008

    Thanks Rahul

    It does work now..:D

  31. #
    Sina on February 4, 2008

    Best tutorial EVER.
    do you have any more? :)

  32. #
    bbCincinnati on February 8, 2008

    Yes, I agree; this is the best tutorial I have found. Working quite well. Thanks Rahul!

    Also, K-CI, thank you for your comments. They were quite helpful as well.

  33. #
    Rahul Bansal on February 11, 2008

    @K-CI, Sina & bbCincinnati
    Thanks all… for your words of appreciation! :-)

    I have more to share… Just running out of time! :-(

    Anyway will post next tutorial in series soon!

  34. #
    Krishna on February 20, 2008

    That was shortest and coolest extension tutorial and example that one can find on the Internet. Thanks a lot.

  35. #
    Rahul Bansal on February 23, 2008

    @Krishna
    Thanks for your words of appreciation Krishna! :-)

  36. #
    ryan on March 19, 2008

    i have been trying to make a converter tool bar that will allow people to translate some text from a game language(albed) but i have been unable to workout how to do so, would someone be able to help me with my plight? thanks.

  37. #
    Rahul Bansal on March 20, 2008

    @ryan
    Ryan its always good to start with extensions which are somewhat similar to one which we have on our mind!
    I suggest checking translate buttons code in Google Toolbar… :-)

    Also it will be great if you provide more details…

    • Like some resources about language(s) you want to trasnlate
    • If you have done with design/code, details about also can help
    • Where exactly you stuck right now?
    • Anything else… as i don’t know about albed
  38. #
    krunal shah on July 15, 2008

    hello, i have follow all steps, but when i am going to open zip file it is not asking me to install but rather its asking about open file in winzip.rar default or save it

  39. #
    krunal shah on July 15, 2008

    HELLO, thank you for helping people to make some adventure like , I have one question how to put image, i have put but its not working

  40. #
    Rahul Bansal on July 20, 2008

    @Krunal
    You have to change extension from zip to xpi
    sorry for late reply… let me know if you you still have problem

  41. #
    Rahul Bansal on July 20, 2008

    @Krunal
    About images…
    where you want to put it?

  42. #
    martin on July 24, 2008

    Thanks, it was very helpful and very short!!!

    do you know of something like this for IE?

    cheers!!!

  43. #
    Rahul Bansal on July 27, 2008

    @Martin
    Sorry buddy I never worked for any Microsoft product/standard.
    But just Google it and you will find something really useful… :-)

  44. #
    Rico on August 1, 2008

    I’m having the same issue as Pablo. It’s installed correctly but does not show up in FF. Any idea? Thanks!

  45. #
    Rahul Bansal on August 1, 2008

    @Rico
    Can you mail me your extension?
    I will check and let you know.
    My id: rahul@devilsworkshop.org

  46. #
    Conor on October 1, 2008

    Hi Rahul, Thanks for the tutorial. I am currently trying to make a toolbar with 4 buttons, with each button being a graphic instead of text. Would you happen to know of a toolbar builder so that its easier to align the buttons and other graphics instead of writing code?Alternatively, I have designed the toolbar in flash, do you know if it’s possible to convert this flash file into a toolbar some how? Thanks

  47. #
    Rahul Bansal on October 1, 2008

    @Conor
    There is no toolbar builder in my knowledge. Not atleast one which can let you add buttons and all.
    Also sorry to say, I have no knowledge of flash.
    BTW learn XUL, its simple and very similar to XML/HTML. You will find it very easy and useful for future extension development work.

  48. #
    LockeVN on October 22, 2008

    Thanks Rahul,

    I just want to make some very first steps on FF toolbar development and I found and read your article first. After reading some more on other sites, I think I have all info on my first step. You do have a good quality tutorial.

    cheers ;)

  49. #
    Rahul Bansal on November 25, 2008

    @LockeVN -
    Your welcome buddy…. :-) Welcome To Devils Workshop… ;-)

Leave a Comment

 Name (Required)
 E-mail (Required)
 Website

Comment:

  OR Use forum if posting unrelated to this topic.
[Note: All comments will be moderated as per our comments policy.]

Subscribe without commenting


2 Trackbacks/Pingbacks

  1. Setting Up Firefox as IDE for Firefox Extension Development! [Firefox Developers] - Welcome To Devils Workshop on February 19th, 2008
  2. Develop your own Firefox toolbar tutorial. Put Apple Google Obama or your girl friend image on your own toolbar « LockeVN’s PRESS on the wild wild web… on October 22nd, 2008