Random Photos in Facebook sidebar

From Jimbojw.com

Jump to: navigation, search
Tip: This is part of the Weekly Web Hack article series. If you like it, please subscribe to my blog. Thanks!

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.

What is a bookmarklet / favelet?

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.

Installation

To get the Random Photos bookmarklet:

  1. Drag the following link to your bookmarks / favorites toolbar or directory:
    Random Photos
  2. Visit any Facebook profile and click the Random Photos link from your toolbar/bookmarks/favorites.

That's it!

What does it do?

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.

The Code

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.

random-photos.js
(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!