garann means > totes profesh

a defunct web development blog

an exciting morning with bookmarklets

Fri, 30 Jan 2009 17:49:34 +0000
Developing bookmarklets is an arcane little science. I've been working on getting one released for like two months now, and have discovered in the process lots of weird browser caveats. Modern browsers let you drag the bookmarklet to install it, while in IE you still have to right-click. People wrap these things in all sorts of different closures. Or don't.. And Safari seems to have more than its share of quirks when it comes to bookmarklets. I ran into some issues early on with Safari regarding an external script taking too long to run while the rest of the bookmarklet code continued along merrily, resulting in a lot of errors with undefined variables. But I didn't think that was anywhere near as weird as noticing that once I'd received and implemented the final design for the bookmarklet's distribution point (you know, the thing you drag), Safari wouldn't let me drag it anymore. I couldn't find one peep about this problem on the web, so I went back to my previous tests. The difference was that in the old version I was styling text with a border and rounded corners. The current version used text-indent to replace the text with an image, and I suspected that was the problem. I tried adding a span inside the link and using display:none, but Safari wasn't having any of that, either. Visibility:hidden? Nope. Safari required that the text of the link be visible and my mouse be on it before it would let me drag it to the toolbar. This made me really upset, because I already told the graphic designer that the PNG I'd cut the images from was all I needed and now I was gonna have to go back and take the text off the button so it could serve as a background to nasty aliased Arial. It occurs to me now that I could have put the original image inside the link, but I hate doing that. Fortunately, I thought of something else, that being the opacity property. I made the text of the link match the text on the button pretty closely, then used opacity to make it just-visible. And it worked in Safari! Yay! Success! ..But of course it broke in IE. I'd added the zoom property to force the opacity to display, and my redundant text was hidden alright, but it was no longer clickable. Only the area of the button outside of the text could be clicked or added to Favorites. Removing zoom made it clickable, but the extra text also showed up at 100% opacity. I had the bright idea to shrink the text on hover, allowing the user to access the link's surface, but that would just break Safari again. I couldn't think of any answer that would work across all browsers, so finally I used a conditional stylesheet to hide the text again from IE. Still not as elegant as I wanted, but functional, at least. For (mostly my own) reference, here's the structure of the bookmarklet: <a href="javascript:(function(){var r='http://mysite.com';var f, d=document,v=d.createElement('script');v.src=r+'/JavaScript/Bookmarklet/doExcitingStuff.js';d.body.appendChild(v);f=function(){var u=doStuff(r);var x=window;if(!x.open(u,'doSomething'))x.location=u;};setTimeout(f,10);})();"><span>Drag me!</span></a>