Offering Bookmarklets with icons

Update: This doesn’t work as intended anymore. A new article offering an alternative method that works for modern Firefox versions has been posted here.

Note: this is tested only in Firefox. It works perfectly there, but in other browsers you may either get the icon only temporary (if the bookmark icon cache is part of the normal cache) or no icon at all. However it won’t break anything anywhere, so that’s no reason to not use it.

I investigated this a while back and it’s really quite simple, but apparently few people are aware of it:

First of all (in case you don’t know what a bookmarklet is): Bookmarklets are tiny Javascript programs that you store in Bookmarks which when you open the bookmark will run on whatever page you are currently viewing… for example copying a snippet from an article and pasting it into your blog or highlighting images or … well just about anything that a website can do. Pretty much any popular site (Google, Facebook, …) offers bookmarks for various purposes.

The problem is that apparently very few Bookmarklet developers know how to provide icons. Hopefully my little post can change that at least a bit 🙂

It’s really quite simple: Bookmarklets usually have this form:

javascript:alert(“My functionality”);void(0);

Most people put that void(0); there automatically, but it’s important to realize what it actually does: It prevents the code from returning anything. Why do we do that? Because otherwise we’d trigger another behaviour of javascript: urls. Something that I usually like to call “poor man’s data: urls”. You see, anything a javascript url call returns is processed as HTML. So javascript:”<!DOCTYPE html><html><head><title>Hello World</title></head><body>Hello World</body></html>”; actually sends you to a HTML document.

So, let’s recap: A javascript: url can either be a bookmarklet or a document. Well, that’s not quite correct, it’s actually always both, we just use one of these functions at a time. We can actually have both at the same time in various ways, the one that’s most important in our case is that we want the javascript: url to behave like a document when the user clicks in on the webpage, but like a bookmarklet after the user has added it as one. The reason being that documents can have icons. And since the url will be identical, so will the bookmarklet.

So first set up a document javascript: url with an icon:

javascript:'<!DOCTYPE html><html><head><title>Hello World</title><link rel=”icon” type=”image/png” href=”http://www.tapper-ware.net/devel/js/JS.Bookmarklets/icons/next.png” /></head><body>Hello World</body></html>’;

Go ahead, click it 🙂 . You’ll see a nice little play button as icon. Drag the title bar onto the bookmarks toolbar and you’ll see that it retains the icon and as an added bonus the title. Don’t worry about the HTML code bloating up your Bookmarklet, we won’t have to include it directly in the final version, but it’s easier to understand this way.

So, now we need a branch so that it will show the content only when clicked on the original page. Again, there are different ways, for now we’ll just stick with the easiest one of checking for a variable that we are reasonably sure will only exist on the original page:

javascript:window[‘bm.dummy@tapper-ware.net’]=true;void(0);

javascript:if(window[‘bm.dummy@tapper-ware.net’]){ ‘<!DOCTYPE html><html><body>My document</body></html>’; }else{ alert(‘My functionality’); void(0); }

Now, we only need the document content if the variable exists, so we can use it to transport the content instead of including it literally in the bookmarklet, bringing the size of the Bookmarklet down dramatically and freeing us from the requirement to have really compact HTML:

javascript:window[‘bm.dummy@tapper-ware.net’]='<!DOCTYPE html><html><body>My document</body></html>’;void(0);

javascript:var bmi=window[‘bm.dummy@tapper-ware.net’]; if(bmi) bmi; else{ alert(‘My functionality’); void(0); }

You could of course also introduce some randomness into the id if you’re afraid websites will try to block it, I’ll leave that up to you.

At the end of the day, you’re whole bookmarklet could then look something like this:

javascript:

var id=’bm.next.’+((Math.random()*9999)|0)+’@tapper-ware.net’;

window[id]='<!DOCTYPE html><html><head><title>Next</title><link rel=”icon” type=”image/png” href=”http://www.tapper-ware.net/devel/js/JS.Bookmarklets/icons/next.png” /></head><body>This is a bookmarklet. Drag its tab to your bookmarks toolbar to add it. Click the resulting button on any page to automatically find links containing the word next</body></html>’;

document.location=’javascript: if(window[“‘+id+'”]){window[“‘+id+'”]; }else{ (function(){ var f=function(e){ return !!(/next/i).exec(e.textContent)}; var l=document.querySelectorAll(“a”); for(var i=0;i<l.length;i++) if(f(l[i])) document.location=l[i].href; })(); void(0); }’;

void(0);

There are numerous way to automate this or make it prettier, but I’ll leave that to you. So long 🙂

18 thoughts on “Offering Bookmarklets with icons”

  1. I would love to know if there is such a thing as a favicon generator for JS bookmarklets. I have all my bookmarklets in a folder on the Firefox bookmarks bar, and I’m always clicking the wrong name.

  2. Where do I put in my functionality? Right now the bookmarklet just takes you to the original page…. (is the “next” functionality supposed to work in this example?)

    Any help greatly appreciated.
    Kyle

  3. never mind, I was testing in chrome…
    Though in my version of FF6, the icon does not show up.

    It was a good idea though….

    Cheers.

  4. It’s actually still working in Firefox 9 … sort of: Since the drag-tab-to-bookmark functionality is gone, you now have to add the bookmark manually with Ctrl+D, which seems to load the icon the first time the bookmarklet is opened.

    So now the sequence is:
    1. Open bookmarklet page
    2. Bookmark that
    3. Run it once to obtain the icon

  5. yeah, I figured that out when I tried it out in FF. But when I tried to replace that function with my own (which is just a snippet to open email client with a mailto:), I couldn’t get it to work. But maybe that’s outside the scope of this post…

    Thanks.

  6. I want to thank you for this informative read, I actually appreciate sharing this good post. Maintain up your work.

  7. last example doesn’t work??? all of it should be in bookmarklet? including the variable & html code???

    and what about that randomness, I’m not good at javascript but can’t “evil” page just use any value of id to block the bookmarklet

  8. There is. And it even seems to work much better for newer Firefox versions. I’ve added a new article and added a link to the top of this post.

  9. I’m trying to add an icon to my bookmarklet, im a bit confused if in the end there is an functional solution or not.

    please advise.

  10. The description posted here does not work anymore for newer Firefox versions, however the one described in the new article (link is at the top of the post) does.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.