Source for "Flickr EXIF Decorator"

By Simon Whitaker
Has 3 other scripts.


// ==UserScript==
// @name            Flickr Exif Decorator
// @namespace       http://netcetera.org
// @include         http://*flickr.com/photos/*
// @description     Decorates photos on Flickr with Exif data (Aperture, Exposure, ISO Speed, etc)

window.addEventListener("load", function() { FED_decorate_photo() }, false);

function FED_decorate_photo() {

    var FED_isInFlickrDialog = function(obj) {
        var re = /.*DialogDiv$/;
        while (obj) {
            if (obj.id && obj.id.match(re))
                return true;
            obj = obj.parentNode;
        }
        return false;
    };

    var FED_showOverlay = function(overlay, obj) {
        var pos = FED_getPos(obj);
        overlay.style.left       = pos[0];
        overlay.style.top        = pos[1];
        overlay.style.visibility = 'visible';
    };

    var FED_getPos = function(obj) {
        var x = 0;
        var y = 0;
        if (obj.offsetParent) {
            x = obj.offsetLeft
            y = obj.offsetTop
            while (obj = obj.offsetParent) {
                x += obj.offsetLeft
                y += obj.offsetTop
            }
        }
        return [x,y];
    };

    var FED_mouseInsideObj = function(e, obj) {
        var posx = 0;
    	var posy = 0;
    	if (!e) return false;

    	if (e.pageX || e.pageY) {
    		posx = e.pageX;
    		posy = e.pageY;
    	}
    	else if (e.clientX || e.clientY) {
    		posx = e.clientX + document.body.scrollLeft
    			+ document.documentElement.scrollLeft;
    		posy = e.clientY + document.body.scrollTop
    			+ document.documentElement.scrollTop;
    	}
    	
    	// get image coordinates
    	var objpos  = FED_getPos(obj);
    	var x       = objpos[0];
    	var y       = objpos[1];
    	
    	// if the mouse pointer is within the bounds
    	// of the object, return true
    	return posx >= x 
            && posx <= (x + obj.offsetWidth - 1)
    	    && posy >= y
    	    && posy <= (y + obj.offsetHeight - 1);
    };
    
    photo_id = location.pathname.split('/')[3];
    var img = document.getElementById('photoImgDiv' + photo_id);
    
    GM_xmlhttpRequest({
        method: 'GET',
        url:    'http://api.flickr.com/services/rest/?method=flickr.photos.getExif'
               +'&api_key=45d5d4b7dff9bc653c8eb3e73271c10c'
               +'&format=json&nojsoncallback=1'
               +'&photo_id=' + photo_id,
               
        onload: function(responseDetails) {
            var data        = eval('(' + responseDetails.responseText + ')');
            var exif_array  = data.photo.exif;
            var exif        = new Array();
            var rawexif     = new Array();
            
            for (i in exif_array) {
                var e = exif_array[i];
                var key = e.label;
                
                rawexif[key] = e.raw._content;
                
                if (e.clean) {
                    exif[key] = e.clean._content;
                }
                else if (!exif[key]) {
                    exif[key] = e.raw._content;
                }
            }
            
            var exif_keys = ['Aperture', 'Exposure', 'ISO Speed', 'Focal Length'];

            // Don't decorate unless there's some Exif data worth showing
            var keep_going = exif['Model'] ? true : false;
            for (i in exif_keys) {
                if (exif[exif_keys[i]]) {
                    keep_going = true;
                }
            }
            if (!keep_going) {
                return;
            }
            
            // Main overlay element
            var overlay = document.createElement('div');
            overlay.setAttribute('id', 'FED_overlay');
            overlay.style.position      = 'absolute';
            overlay.style.top           = '0px';
            overlay.style.left          = '0px';
            overlay.style.visibility    = 'hidden';
            document.body.appendChild(overlay);

            // Add translucent background
            var obg = document.createElement('div');
            obg.setAttribute('id', 'FED_obg');
            obg.style.backgroundColor   = '#000';
            obg.style.opacity           = '0.75';
            obg.style.MozBorderRadiusBottomright = '8px';
            obg.style.position          = 'absolute';
            obg.style.top               = '0px';
            obg.style.left              = '0px';
            overlay.appendChild(obg);

            // Add overlay text element
            var ot = document.createElement('div');
            ot.setAttribute('id', 'FED_ot');
            ot.style.color              = '#fff';
            ot.style.fontSize           = '11px';
            ot.style.opacity            = '1.0';
            ot.style.position           = 'absolute';
            ot.style.top                = '0px';
            ot.style.left               = '0px';
            ot.style.fontFamily         = '"Gill Sans", "Gill Sans MT", Tahoma, Helvetica, Arial';
            ot.style.padding            = '4px 8px 4px 4px';
            ot.style.textAlign          = 'left';
            overlay.appendChild(ot);
            
            var first = true;
            var h = '<nobr>';            
            var flash_arrow_src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAACV0RVh0U29mdHdhcmUATWFjcm9tZWRpYSBGaXJld29ya3MgTVggMjAwNId2rM8AAAAVdEVYdENyZWF0aW9uIFRpbWUAMjcvNS8wNyp/1lcAAABcSURBVHicjY7BDYAwDAOviM7SlWBCWCmfLNJH+DRSUxWKX5Fzsp3MjF4icuScL4Ba61lKuQG2P1AAR8g9/yevVtW4ocmT997we7nxDVpWfybOoAD2G0domjiDAB4i61DU2xUj8QAAAABJRU5ErkJggg==";
            
            if (exif['Model'] || exif['Flash']) {
                if (exif['Model']) {
                    if (exif['Make'] && !exif['Model'].match(new RegExp(exif['Make'], 'i'))) {
                        h += exif['Make'] + ' ' + exif['Model'];
                    }
                    else {
                        h += exif['Model'];
                    }
                }
                // LSB of Flash Exif param's raw value is
                // 1: flash fired, 0: flash didn't fire
                if (exif['Flash'] && rawexif['Flash'] & 1) {
                    h += '<img src="' + flash_arrow_src + '" hspace="10" />';
                }
                h += '</nobr><br/><nobr>';
            }   
            
            for (i in exif_keys) {
                var key = exif_keys[i];
                if (exif[key]) {
                    if (first) { first = false;}
                    else { h += ', '; }
                    if (key == 'ISO Speed')
                        h += 'ISO ';
                    h += exif[key];
                }
            }
            h += ' (<a style="color: #fff" href="http://www.flickr.com/photo_exif.gne?id=' + photo_id + '">more</a>)';
            h += '</nobr>';
            ot.innerHTML = h;
            
            obg.style.width  = ot.offsetWidth  + 'px';
            obg.style.height = ot.offsetHeight + 'px';

            // Event listeners to display the overlay when we
            // move over an image
            function mouseMoveListener(e) {
                if (overlay.style.visibility == 'hidden') {
                    FED_showOverlay(overlay, img);
                }
                // Only want this listener to fire once - to get the
                // overlay displayed if the page loads while the mouse
                // is moving over the image. Once it's fired we can
                // remove it.
                img.removeEventListener('mousemove', mouseMoveListener, false);
            }
            
            function mouseOutListener(e) {
                // don't want to hide the overlay if the mouseout
                // event happened because we moved into another
                // element over the image, e.g. a note
                // Do hide for flickr dialogs though (e.g. Add To Group
                // drop-down) because otherwise overlay can obscure it
                // according to correspondence on Flickr Hacks group.
                if (FED_mouseInsideObj(e, img) && !FED_isInFlickrDialog(e.relatedTarget)) {
                    return;
                }            	
                overlay.style.visibility = 'hidden';
            }
            
            function mouseOverListener(e) {
                if (overlay.style.visibility == 'hidden') {
                    FED_showOverlay(overlay, img);
                }
            }
            
            img.addEventListener('mousemove', mouseMoveListener, false);
            img.addEventListener('mouseout', mouseOutListener, false);
            img.addEventListener('mouseover', mouseOverListener, false);
            overlay.addEventListener('mouseout', mouseOutListener, false);
        }
    });
}