Adding icons to bookmarklets … again

Show simple Demo

Yesterday I got a question on how to make my Bookmarklet-with-icon code work and sadly, it seems to be broken now. So I set out to find another method and strangely enough the solution that works with modern Firefox versions is quite simple and elegant:

Open the bookmarklet in "page mode" once after the user has added it as bookmarklet. This may sound like something that’s terribly hard to detect, but with a few simple tricks it’s not much of an issue: Mainly because you can make it so that the user barely notices if it fires to often.

  1. Just like the original bookmarklet-with-icon code, adding icons still relies on the behavior that a javascript: url which returns a string will cause the browser to display that string as a HTML document. So, the first step (again) is saving the HTML string somewhere. Of course, you can still add a bit of randomness, but for simplicity’s sake we’ll leave it out for now:
    <script>
      top["bookmarkletv2sample@tapper-ware.net"] = ''
        +'<!DOCTYPE html>'
        +'<html>'
          +'<head>'
            +'<title>My Bookmarklet</title>'
          +'</head>'
          +'<body></body>'
        +'</html>'
      ;
    </script>

  2. Now, we add the magic favicon sauce:
    <script>
      top["bookmarkletv2sample@tapper-ware.net"] = ''
        +'<!DOCTYPE html>'
        +'<html>'
          +'<head>'
            +'<title>My Bookmarklet</title>'
            +'<link rel="icon" href="http://www.my.domain/favicon.ico" />'
          +'</head>'
          +'<body></body>'
        +'</html>'
      ;
    </script>

  3. Like I said, we want that page to only appear very briefly, so we add a history.back(); call that will take us right back to the previous page. I’ve added a timeout as well, which is probably not necessary, but with hacks like that it’s better to err on the side of caution. It’s also a good idea to split the closing script tag to prevent any browser from misinterpreting it as the end of the current script block:
    <script>
      top["bookmarkletv2sample@tapper-ware.net"] = ''
        +'<!DOCTYPE html>'
        +'<html>'
          +'<head>'
            +'<title>My Bookmarklet</title>'
            +'<link rel="icon" href="http://www.my.domain/favicon.ico" />'
          +'</head>'
          +'<body>'
            +'<script>'
              +'window.onload=function(){'
                +'window.setTimeout(function(){'
                  +'history.back();'
                +'},250);'
              +'};'
            +'</scr'+'ipt>'
          +'</body>'
        +'</html>'
      ;
    </script>

  4. And that’s pretty much it for our magic assign-icon-from-within-bookmarklet page. Now we just have to change the actual bookmarklet to return that HTML string instead of running the bookmarklet code whenever a thusly-named HTML string exists on the current page. Assuming our bookmarlet is a plain old alert("This is my bookmarklet");void(0);, we have to wrap it into a little if-block like this:
    if(top["bookmarkletv2sample@tapper-ware.net"]){
       top["bookmarkletv2sample@tapper-ware.net"];
    }else{	
       alert('This is my bookmarklet');
      void(0);
    }


    which, written as a bookmarklet one-liner, turns into

    <a href="javascript:if(top['bookmarkletv2sample@tapper-ware.net']){top['bookmarkletv2sample@tapper-ware.net'];}else{alert('This%20is%20my%20bookmarklet');void(0);}">My Bookmarklet</a>

  5. If you put those blocks somewhere on your page it will already work… sort of: If you drag the link to your bookmarks-toolbar, then click it, you’ll briefly see an empty page and the icon will appear. Now, all we have to automate is that one click. Luckily, all we have to do for that is listen for a dragend event, which occurs whenever the user drags the link anywhere. It also occurs during any other drag operation but since that brief refresh is barely noticeable it doesn’t really matter if we try to assign the icon too often. All we have to do for that is add an ondragend attribute to the a element:
    ondragend="this.click();"


    Which finally turns our “A” element into this:

    <a ondragend="this.click();" href="javascript:if(top['bookmarkletv2sample@tapper-ware.net']){top['bookmarkletv2sample@tapper-ware.net'];}else{alert('This%20is%20my%20bookmarklet');void(0);}">My Bookmarklet</a>

And that’s all there is to it. Include the link and the script element on your page, tell the users that they should add it by dragging the link and that it won’t work on the current page, adjust favicon-url and exchange the example with your own JS code. Done.

This entry was written by Hans Schmucker , posted on Tuesday February 14 2012at 12:02 am , filed under Default Category and tagged . Bookmark the permalink . Post a comment below or leave a trackback: Trackback URL.

4 Responses to “Adding icons to bookmarklets … again”

  • [...] 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. [...]

  • kb says:

    Hi,
    Your example is working fine on the latest Firefox. However it’s not working on ie8 and the latest Opera, Maxthon and Chrome. (tested on windows 7). Is there a solution?

    I added the following code to set the favicon when the user saves it with “right click”->”bookmark this link” (working in FF):

    <a oncontextmenu="rgtclick(event,this)"…. (in the url)

    function rgtclick(e,t){
    $(window).one(“focus”,function(){
    t.click();
    });
    }

    kb

  • Hans Schmucker says:

    I’m not at my PC right now, but you could combine it with the technique from the previous article to make it compatible with all Firefox version… but I don’t think that will help chrome, opera or ie/maxthon.

  • Amigo Omega says:

    I find the easiest way is to hijack a bookmark. Just bookmark a page that has a favicon that you want to use. You may need to click on the bookmark to have it load the favicon from the site that it links to. Once you have the favicon, then, go to the bookmark, right click, and choose properties. You can then change the “location” to the javascript code for the bookmarklet you want to have associated with the favicon. Tip: To differentiate a bookmarklet from a bookmark, I change the “name” in the properties tab to whatever preceeded by M:, so for example, if the bookmarklet was for creating a shortened URL using goo.gl, I would name that “M:Goo.gl”

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*