In this short Weekly Web Hack article, I'll show how to add a new sidebar to Facebook for displaying random photos. The techniques herein could be easily extended for more elaborate functional enhancements.
A bookmarklet is a bookmark whose protocol is 'javascript:' rather than the usual 'http:' or 'https:'. By using the javascript protocol, a bookmarklet actually executes JavaScript code within the context of the currently viewed page.
This makes them potentially very powerful and also potentially dangerous. By clicking a bookmarklet, you are authorizing the executed script to do whatever it wishes - this could include collecting private information and sending it off to a third party, or possibly (if the developer is clever enough) stealing your credentials by giving you new contact information in some way. BE CAREFUL
That said, the bookmarklet demoed here is meant to be totally innocuous and benign. In fact, I invite you to review the code until you're satisfied that it's trustworthy.
To get the Random Photos bookmarklet:
That's it!
In short, Random Photos will visit the "View Photos of..." link directly below the persons profile and inject 5 random images found therein into a new div placed underneath the left-hand sidebar navigation items.
For your viewing pleasure, here is the raw JavaScript source for the random photos bookmarklet. You'll notice that it uses some of Facebook's JavaScript infrastructure such as the $() function and the Ajax object.
(function(){ var pics = $('pics'); if (!pics) { var style = document.createElement('style'); style.innerHTML = '.advert, .seeall, .sponsors, .sponsor_absolute { display: none !important; }' + '#pics img { background: white; border: 1px solid #ccc; padding: 3px; }' + '#pics { text-align: center; background: #f7f7f7; border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; }'; document.getElementsByTagName('head')[0].appendChild(style); pics = document.createElement('div'); pics.id = 'pics'; pics.className = 'app_list'; pics.innerHTML = '<h2><a href="/photo_search.php?view=all&id=' + PROFILE_OWNER_ID + '">Random Photos</a></h2>' + '<div style="text-size:small" id="picsloading">loading...</div>'; $('sidebar').appendChild(pics); } var ajax = new Ajax; ajax.onDone = function (ajaxObj, responseText) { $('picsloading').style.display = 'none'; var start = responseText.indexOf('<div'); var end = responseText.indexOf('</body'); var div = document.createElement('div'); div.innerHTML = responseText.substring(start, end); var images = [], tables = div.getElementsByTagName('table'); for (var j=0; j<tables.length; j++) { var imgnodes = tables[j].getElementsByTagName('img'); for (var i=0; i<imgnodes.length; i++) { images.push(imgnodes[i]); } } var selected = []; selected.contains = function(item) { for (var j=0; j<this.length; j++) if (this[j]==x) return true; return false }; while (selected.length < imgnodes.length && selected.length < 5 ) { var x = Math.floor(Math.random() * imgnodes.length); while (selected.contains(x)) x++; selected.push(x); } for (var i=0; i<selected.length; i++) { $('pics').appendChild(images[selected[i]].parentNode); } }; ajax.get('/photo_search.php?view=all&id=' + PROFILE_OWNER_ID); })();
Enjoy!