TinyURL Bookmarklet

TinyURL bookmarklet in action

TinyURL bookmarklet in action

If you just want to try this out, drag the link below to your bookmarks toolbar, then click the new bookmark. I’ve only tested in Firefox 3.04 so far so your mileage may vary if you use another browser. Let me know in the comments if you find this useful or have any problems.

Tiny

(v1.1 updated Dec 6th: The generated tiny url is now automatically selected ready to be copied)

Read on for a description of how it works…

What it does
Inspired by the WTFramework bookmarklet I decided to create a TinyURL bookmarklet that would generate a shortened url without opening a new browser window and without navigating the user away from the current page. It took me a little while to figure out how to define a callback function within a bookmarklet (thanks to Dion Almaer for a useful tutorial) but I got it working in a couple of hours and I quite like it. Thanks also to Oskar Krawczyk for the CSS which I “borrowed” from the aforementioned WTFramework.

How it works
When you click the bookmarklet, I first check whether the UI element is visible and if it is, remove it:
[code lang="jscript"]
var el=document.getElementById('__tiny');
if (el){
document.body.removeChild(el);
}
[/code]
This makes the bookmarklet act as a toggle: Click once to show the UI, click again to remove it. The WTFramework bookmarklet also removes the UI when the user clicks on the UI element itself  but I removed that functionality from this bookmarklet as the user is likely to want to click and select the tinyurl to copy it which would be difficut if the UI disappears on mouse click.

If the UI is not present, I generate a URL which is called via script injection to circumvent the browser’s same origin policy (i.e. I generate as script tag, set its src attribute and add the tag to the DOM):
[code lang="jscript"]
var scriptTag = document.createElement('script');
scriptTag.type='text/javascript';
scriptTag.src='http://json-tinyurl.appspot.com/?callback=window.tinyCallback&url=' + document.location;
scriptTag.id='__tinyURL_script';
document.body.appendChild(scriptTag);
[/code]
The response is a JSONP formatted string. TinyURL provides a very simple API (e.g. http://tinyurl.com/api-create.php?url=http://www.droza.net/blog) but doesn’t offer a JSONP interface – I was going to create one with Yahoo Pipes, but found that a suitable JSONP wrapper for TinyURL already exists, hosted in Google’s AppEngine (e.g. http://json-tinyurl.appspot.com/?callback=window.tinyCallback&url=http://www.droza.net/blog) so I use that instead (thanks Simon!).

After the script tag is added to the page, the browser will call the API and the response will invoke the tinyCallback function (I check to see whether the function already exists before declaring it to prevent declaring it twice if the bookmarklet is used multiple times on the same page). The callback constructs a semi-transparent UI element positioned in the top-right of the browser page and sets its content to be the generated tiny url. The bulk of the code is CSS:
[code lang="jscript"]
window.tinyCallback = function(data) {
var c=document.createElement('span');
c.id='__tiny';
c.style.opacity='0.7';
c.style.filter='alpha(opacity=70)';
c.style.border='solid 2px %23fff';
c.style.textDecoration='none';
c.style.textAlign='left';
c.style.position='fixed';
c.style.zIndex='9000';
c.style.top='15px';
c.style.right='20px';
c.style.background='#000';
c.style.styleFloat='right';
c.style.padding='7px 10px';
c.style.color='%23fff';
c.style.font='12px Lucida Grande,Helvetica,Tahoma';
c.style.MozBorderRadius='5px';
c.style.WebkitBorderRadius='5px';
c.style.WebkitBoxShadow='0px 0px 20px %23000';
c.style.MozBoxShadow='0px 0px 20px %23000';
document.body.appendChild(c);
c.innerHTML=data.tinyurl;
[/code]

It then removes the script tag that it added to the DOM, just to keep things tidy:
[code lang="jscript"]
var x=document.getElementById('__tinyURL_script');
if (x){
document.body.removeChild(x);
}
[/code]

After creating the script I used Dean Edward’s packer to minify the code to a single line sans-whitespace suitable for using in the href attribute of an a tag.

The full code
For reference, the listing below is the full non-minified sourcecode

[code lang="jscript"]
var el=document.getElementById('__tiny');
if (el){
document.body.removeChild(el);
} else {
var scriptTag = document.createElement('script');
scriptTag.type='text/javascript';
scriptTag.src='http://json-tinyurl.appspot.com/?callback=window.tinyCallback&url=' + document.location;
scriptTag.id='__tinyURL_script';
document.body.appendChild(scriptTag);
}
if (!window['tinyCallback']) {
window.tinyCallback = function(data) {
var c=document.createElement('span');
c.id='__tiny';
c.style.opacity='0.7';
c.style.filter='alpha(opacity=70)';
c.style.border='solid 2px %23fff';
c.style.textDecoration='none';
c.style.textAlign='left';
c.style.position='fixed';
c.style.zIndex='9000';
c.style.top='15px';
c.style.right='20px';
c.style.background='#000';
c.style.styleFloat='right';
c.style.padding='7px 10px';
c.style.color='%23fff';
c.style.font='12px Lucida Grande,Helvetica,Tahoma';
c.style.MozBorderRadius='5px';
c.style.WebkitBorderRadius='5px';
c.style.WebkitBoxShadow='0px 0px 20px %23000';
c.style.MozBoxShadow='0px 0px 20px %23000';
document.body.appendChild(c);
c.innerHTML=data.tinyurl;
var x=document.getElementById('__tinyURL_script');
if (x){
document.body.removeChild(x);
}
}
}
void(0);
[/code]

3 Comments to “TinyURL Bookmarklet”

  1. Oskar Krawczyk 4 December 2008 at 12:45 pm #

    You, sir, are a genius! Very cool idea indeed. Two things I would suggest:

    1) Why not is.gd? (even shorter!)
    2) The inner element might be an INPUT which gets pre-selected on creation – that would be awesome!

    Best,
    Oskar

  2. tdroza 4 December 2008 at 8:53 pm #

    Thanks Oskar! Both great ideas.
    1) If I can find (or create) a JSONP API for is.gd then I’ll create an is.gd version.
    2) I’ll definitely do this and update the bookmarklet linked from the post.

  3. tdroza 7 December 2008 at 9:12 pm #

    I’ve now updated the bookmarklet so that the generated tiny url is now automatically selected ready to be copied as Oskar suggested above.


Leave a Reply