if ( 'undefined' == typeof( console ) )
console = { "log": function(str){}, "debug": function(str){} };
if ( 'undefined' == typeof( _qoptions ) || null == _qoptions )
var _qoptions = {};
var Gravatar = {
/* All loaded profiles, keyed off ghash */
"profile_stack": {},
// Mapping of ghash to the "currently waiting" dom_id of where to render it
"profile_map": {},
/* Timeouts for hovering over and off Gravatar images */
"overTimeout": false,
"outTimeout": false,
/* If true, show_card will bail */
"stopOver": false,
/* The img element, hash and ID of the Gravatar that is being hovered over */
"active_grav": false,
"active_hash": false,
"active_id": false,
/* The clone of the Gravatar img element that is being hovered over. */
"active_grav_clone": false,
/* Callback function for once a profile is loaded */
"profile_cb": null,
/* Queue of stats objects to send */
"stats_queue": [],
/* Wating throbber */
"throbber": null,
/* Has a custom background image been added to the card? */
"has_bg": false,
"disabled":false,
"disable": function() {
Gravatar.disabled = true;
Gravatar.hide_card();
var d = new Date( 2100, 1, 1, 1, 1, 1 );
Gravatar.stat( 'disable' );
if ( -1 == window.location.host.search( /wordpress.com/i ) ) {
document.cookie = 'nohovercard=1; expires=' + d.toUTCString() + ';';
} else {
document.cookie = 'nohovercard=1; expires=' + d.toUTCString() + '; domain=.wordpress.com; path=/';
}
},
"mouseOut": function(e) {
e.stopImmediatePropagation();
Gravatar.stopOver = true;
// console.debug( ':set out' );
Gravatar.outTimeout = setTimeout( function() {
// console.debug( ':do out' );
Gravatar.hide_card();
}, 300 );
},
"init": function() {
var ca = document.cookie.split( ';' ), i, c;
for ( i = 0; i < ca.length; i++ ) {
c = ca[i];
while ( ' ' == c.charAt(0) ) {
c=c.substring( 1, c.length );
}
if ( 0 == c.indexOf( 'nohovercard=1' ) ) {
return;
}
}
/* Locate all Gravatar images and attach profile links to them. */
this.attach_profiles();
/* Add CSS */
this.add_card_css();
/* Find and show a hovercard when hovering over a Gravatar. */
jQuery('img.grav-hashed').live( 'mouseenter.gravatar mouseleave.gravatar', function(e) {
if ( Gravatar.disabled ) { return; }
e.preventDefault();
e.stopPropagation();
if ( 'mouseleave' == e.type || 'mouseout' == e.type ) {
// console.debug( 'grav out' );
return Gravatar.mouseOut.call( this, e );
}
Gravatar.stopOver = false;
// console.debug( 'grav enter' );
/* Get and store the hash and ID for the active Gravatar */
Gravatar.active_id = jQuery(this).attr('id');
Gravatar.active_hash = Gravatar.active_id.split('-')[1];
Gravatar.untilt_gravatar();
// console.debug( ':clear over1' );
clearTimeout( Gravatar.overTimeout );
// No profile data - see fetch_profile_error
if ( false === Gravatar.profile_map[ 'g' + Gravatar.active_hash ] ) {
return;
}
Gravatar.stat( 'hover' );
// console.debug( ':clear out' );
clearTimeout( Gravatar.outTimeout );
Gravatar.tilt_gravatar();
Gravatar.fetch_profile_by_hash( Gravatar.active_hash, Gravatar.active_id );
// console.debug( ':set over' );
Gravatar.overTimeout = setTimeout( function() {
Gravatar.show_card();
}, 600 );
});
/* Maintain hovercard state when rolling over a hovercard or cloned image */
jQuery('div.gcard, img.grav-clone').live( 'mouseenter.gravatar mouseleave.gravatar', function(e) {
if ( Gravatar.disabled ) { return; }
e.preventDefault();
e.stopPropagation();
if ( e.type == 'mouseenter' || e.type == 'mouseover' ) {
Gravatar.stopOver = false;
// console.debug( 'clone enter' );
// console.debug( ':clear out2' );
clearTimeout( Gravatar.outTimeout );
} else {
// console.debug( 'clone out' );
Gravatar.mouseOut.call( this, e );
}
});
/* Cancel a hovercard when scrolling. */
jQuery(window).bind( 'scroll', function() {
if ( !Gravatar.active_hash.length )
return;
Gravatar.hide_card();
});
},
"attach_profiles": function( container ) {
setInterval( Gravatar.send_stats, 3000 );
/* Locate all Gravatar images and add profiles to them */
container = "undefined" == typeof( container ) ? "body" : container;
jQuery( container + ' img[src*=gravatar.com/avatar]' ).not( '.no-grav, .no-grav img' ).each( function() {
hash = Gravatar.extract_hash( this );
/* Add unique ID to image so we can reference it directly */
uniq = 0;
if ( jQuery( '#grav-' + hash + '-' + uniq ).length ) {
while ( jQuery( '#grav-' + hash + '-' + uniq ).length )
uniq++;
}
/* Remove the hover titles for sanity */
var g = jQuery( this ).attr( 'id', 'grav-' + hash + '-' + uniq ).attr( 'title', '' ).removeAttr( 'title' );
if ( g.parent( 'a' ).size() )
g.parent( 'a' ).attr( 'title', '' ).removeAttr( 'title' );
g.addClass( 'grav-hashed' );
if ( g.parents( '#comments, .comments, #commentlist, .commentlist, .grav-hijack' ).size() || !g.parents( 'a:first' ).size() ) {
g.addClass( 'grav-hijack' );
}
});
},
"show_card": function() {
if ( Gravatar.stopOver ) {
return;
}
dom_id = this.profile_map[ 'g' + Gravatar.active_hash ];
// Close any existing cards
jQuery( '.gcard' ).hide();
// Bail if we're waiting on a fetch
if ( 'fetching' == this.profile_stack[ 'g' + Gravatar.active_hash ] ) {
Gravatar.show_throbber();
this.listen( Gravatar.active_hash, 'show_card' );
Gravatar.stat( 'wait' );
// console.log( 'still fetching ' + hash );
return;
}
// If we haven't fetched this profile yet, do it now and do this later
if ( 'undefined' == typeof( this.profile_stack[ 'g' + Gravatar.active_hash ] ) ) {
Gravatar.show_throbber();
this.listen( Gravatar.active_hash, 'show_card' );
// console.log( 'need to start fetching ' + hash + '@' + dom_id );
this.fetch_profile_by_hash( Gravatar.active_hash, dom_id );
return;
}
Gravatar.stat( 'show' );
Gravatar.hide_throbber();
// console.log( 'show_card: hash: ' + hash + ', DOM ID: ' + dom_id );
// No HTML? build it
if ( !jQuery( '#profile-' + this.active_hash ).length )
this.build_card( this.active_hash, this.profile_stack[ 'g' + this.active_hash ] );
this.render_card( this.active_grav, 'profile-' + this.active_hash );
},
"hide_card": function() {
// console.debug( ':clear over3' );
clearTimeout( Gravatar.overTimeout );
/* Untilt the Gravatar image */
this.untilt_gravatar();
grav_resize.current_image = false
jQuery( 'div.gcard' ).filter( '#profile-' + this.active_hash ).fadeOut(120, function() {
jQuery('img.grav-large').stop().remove();
} ).end().not( '#profile-' + this.active_hash ).hide();
},
"render_card": function( grav, card_id ) {
var card_el = jQuery( '#' + card_id ).stop();
// console.log( 'render_card for ' + grav_id + ', ' + card_id );
// Change CSS positioning based on where grav_id is in the page
var grav_el = grav;
var grav_pos = grav_el.offset();
if ( null != grav_pos ) {
var grav_width = grav_el.width();
var grav_height = grav_el.height();
var grav_space = 5 + ( grav_width * .4 );
var card_width = card_el.width();
var card_height = card_el.height();
if ( card_width == jQuery(window).width() ) {
card_width = 400;
card_height = 200;
}
/*
console.log( grav_pos );
console.log( 'grav_width = ' + grav_width + "\n" +
'grav_height = ' + grav_height + "\n" +
'grav_space = ' + grav_space + "\n" +
'card_width = ' + card_width + "\n" +
'card_height = ' + card_height + "\n" );
*/
/* Position to the right of the element */
var left = grav_pos.left + grav_width + grav_space;
var top = grav_pos.top;
var grav_pos_class = 'pos-right';
/* Position to the left of the element if space on the right is not enough. */
if ( grav_pos.left + grav_width + grav_space + card_width > jQuery(window).width() + jQuery(window).scrollLeft() ) {
left = grav_pos.left - ( card_width + grav_space );
grav_pos_class = 'pos-left';
}
/* Reposition the card itself */
var top_offset = grav_height * .25;
jQuery( '#' + card_id ).removeClass( 'pos-right pos-left' ).addClass( grav_pos_class ).css( { 'top': ( top - top_offset ) + 'px', 'left': left + 'px' } );
/* Position of the small arrow in relation to the Gravatar */
var arrow_offset = ( grav_height / 2 );
if ( arrow_offset > card_height )
arrow_offset = card_height / 2;
if ( arrow_offset > ( card_height / 2 ) - 6 )
arrow_offset = ( card_height / 2 ) - 6;
if ( arrow_offset > 53 )
arrow_offset = 53; // Max
if ( this.has_bg )
arrow_offset = arrow_offset - 8;
if ( arrow_offset < 0 )
arrow_offset = 0; // Min
var css = {
'height': ( ( grav_height * 1.5 ) + top_offset ) + 'px'
};
if ( 'pos-right' == grav_pos_class ) {
css['right'] = 'auto';
css['left'] = '-7px';
css['background-position'] = '0px ' + arrow_offset + 'px';
} else {
css['right'] = '-10px';
css['left'] = 'auto';
css['background-position'] = '0px ' + arrow_offset + 'px';
}
jQuery( '#' + card_id + ' .grav-cardarrow' ).css( css );
}
card_el.stop().css( { opacity: 0 } ).show().animate( { opacity: 1 }, 150, 'linear', function() {
jQuery( this ).css( { opacity: 'auto' } ); // IE7 hack
jQuery( this ).stop();
grav_resize.init( card_id );
grav_gallery.init( card_id );
// Load QC directly to make sure it's always triggered
_qoptions = { qacct:'p-18-mFEk4J448M', labels:'type.gravatar.hovercard' };
var new_script = document.createElement( 'script' );
var qp = 'http';
if ( 'https:' == window.location.protocol )
qp += 's';
new_script.src = qp + '://edge.quantserve.com/quant.js';
new_script.type = 'text/javascript';
document.getElementsByTagName( 'head' )[0].appendChild( new_script );
});
},
"build_card": function( hash, profile ) {
Object.size = function( obj ) {
var size = 0, key;
for ( key in obj ) {
if ( obj.hasOwnProperty( key ) ) size++;
}
return size;
};
// console.log( 'Build profile card for: ' + hash );
// console.log( profile );
GProfile.init( profile );
var urls = GProfile.get( 'urls' );
var photos = GProfile.get( 'photos' );
var services = GProfile.get( 'accounts' );
var limit = 100;
if ( Object.size( urls ) > 3 )
limit += 90;
else
limit += 10 + ( 20 * Object.size( urls ) );
if ( Object.size( services ) > 0 )
limit += 30;
var description = GProfile.get( 'aboutMe' );
description = description.replace( /<[^>]+>/ig, '' );
description = description.toString().substr( 0, limit );
if ( limit == description.length )
description += '…';
var card_class = 'grav-inner';
// console.log( Gravatar.my_hash, hash );
if ( Gravatar.my_hash && hash == Gravatar.my_hash ) {
card_class += ' grav-is-user';
if ( !description.length ) {
description = "
Want a better profile? Click here.
";
}
}
if ( description.length ) {
card_class += ' gcard-about';
}
name = GProfile.get( 'displayName' );
if ( !name.length )
name = GProfile.get( 'preferredUsername' );
var card = ' \
\
\
\
\
' + description + ' \
\
\
';
if ( Object.size( urls ) || Object.size( services ) ) {
card_class += ' gcard-links';
}
card += '
Personal Links
\
';
// console.log( 'Services to include in card:' );
// console.log( services );
if ( Object.size( services ) ) {
card_class += ' gcard-services';
}
card += '
';
var services_out = 0;
for ( var s in services ) {
if ( !services[s]['url'] )
continue;
if ( services_out >= 6 )
break;
card += ' ';
services_out++;
}
card += '
';
card += '
'; // right col
if ( Object.size( photos ) > 1 ) {
card_class += ' gcard-gallery';
}
card += '
\
Previous \
\
';
for ( var p in photos ) {
if ( !photos[p]['value'] )
continue;
card += ' ';
}
card += '
\
\
Next \
'; // gallery
card += '
\
\
';
card += '
Turn off hovercards
';
card += '
'; // .grav-inner, .gcard
// console.log( 'Finished building card for ' + dom_id );
jQuery( 'body' ).append( jQuery( card ) );
jQuery( '#profile-' + hash + ' .grav-inner' ).addClass( card_class );
// Custom Background
this.has_bg = false;
var bg = GProfile.get( 'profileBackground' );
if ( Object.size( bg ) ) {
this.has_bg = true;
var bg_css = {
padding: '8px 0'
};
if ( bg.color )
bg_css['background-color'] = bg.color;
if ( bg.url )
bg_css['background-image'] = 'url(' + bg.url + ')';
if ( bg.position )
bg_css['background-position'] = bg.position;
if ( bg.repeat )
bg_css['background-repeat'] = bg.repeat;
jQuery( '#profile-' + hash ).css( bg_css );
}
// Resize card based on what's visible
if ( !jQuery( '#profile-' + hash + ' .gcard-links' ).length && !jQuery( '#profile-' + hash + ' .gcard-services' ).length )
jQuery( '#profile-' + hash + ' .grav-rightcol' ).css( { 'width': 'auto' } );
if ( !jQuery( '#profile-' + hash + ' .gcard-about' ).length )
jQuery( '#profile-' + hash + ' .grav-leftcol' ).css( { 'width': 'auto' } );
// Trigger callback if defined
if ( jQuery.isFunction( Gravatar.profile_cb ) ) {
Gravatar.loaded_js( hash, 'profile-' + hash );
}
// Stats handlers
jQuery( '#profile-' + hash + ' .grav-gallery img' ).click( function() {
Gravatar.stat( 'click_photo' );
} );
jQuery( '#profile-' + hash + ' a.grav-extra-comments' ).click( function(e) {
return Gravatar.stat( 'click_comment', e );
} );
jQuery( '#profile-' + hash + ' a.grav-extra-likes' ).click( function(e) {
return Gravatar.stat( 'click_like', e );
} );
jQuery( '#profile-' + hash + ' .grav-links a' ).click( function(e) {
return Gravatar.stat( 'click_link', e );
} );
jQuery( '#profile-' + hash + ' .grav-services a' ).click( function(e) {
return Gravatar.stat( 'click_service', e );
} );
jQuery( '#profile-' + hash + ' h4 a' ).click( function(e) {
return Gravatar.stat( 'to_profile', e );
} );
jQuery( '#profile-' + hash + ' .grav-tag a' ).click( function(e) {
if ( 3 == e.which || 2 == e.button || e.altKey || e.metaKey || e.ctrlKey ) {
e.preventDefault();
e.stopImmediatePropagation();
Gravatar.stat( 'egg' );
return Gravatar.whee();
}
return Gravatar.stat( 'to_gravatar', e );
} ).bind( 'contextmenu', function(e) {
e.preventDefault();
e.stopImmediatePropagation();
Gravatar.stat( 'egg' );
return Gravatar.whee();
} );
jQuery( '#profile-' + hash + ' a.grav-edit-profile' ).click( function(e) {
return Gravatar.stat( 'click_edit_profile', e );
} );
},
"tilt_gravatar": function() {
/* Set the active gravatar */
this.active_grav = jQuery('img#' + this.active_id);
if ( jQuery('img#grav-clone-' + this.active_hash).length )
return;
/* Clone the image */
this.active_grav_clone = this.active_grav.clone().attr( 'id', 'grav-clone-' + this.active_hash ).addClass('grav-clone');
var top = this.active_grav.offset().top;
var left = this.active_grav.offset().left;
/*
top -= 2;
left -= 2;
*/
/* Style clone */
var fancyCSS = {
'-webkit-transform': 'rotate(-4deg) scale(1.3)',
'-moz-transform': 'rotate(-4deg) scale(1.3)',
'-o-transform': 'rotate(-4deg) scale(1.3)',
'transform': 'rotate(-4deg) scale(1.3)',
'-webkit-box-shadow': '0 0 4px #aaa',
'-moz-box-shadow': '0 0 4px #aaa',
'box-shadow': '0 0 4px #aaa',
'border-width': '2px 2px ' + ( this.active_grav.height() / 5 ) + 'px 2px',
'border-color': '#fff',
'border-style': 'solid',
'padding': '0px'
};
if ( jQuery.browser.msie && 9 > jQuery.browser.version ) {
fancyCSS['filter'] = "progid:DXImageTransform.Microsoft.Matrix(M11='1.29683327', M12='0.0906834159', M21='-0.0906834159', M22='1.29683327', SizingMethod='auto expand') progid:DXImageTransform.Microsoft.Glow(Color='#aaaaaa', strength='2'";
top -= 5;
left -= 6;
}
if ( this.active_grav.hasClass( 'grav-hijack' ) ) {
var aWrap ='';
} else {
var aWrap = this.active_grav.parents( 'a:first' ).clone( true ).empty();
}
var appendix = this.active_grav_clone.css( fancyCSS ).wrap( aWrap ).parent().css( {
'position': 'absolute',
'top': top + 'px',
'left': left + 'px',
'z-index': 15,
'border': 'none',
'text-decoration': 'none'
} );
/* Append the clone on top of the original */
jQuery('body').append( appendix );
this.active_grav_clone.removeClass('grav-hashed');
},
"untilt_gravatar": function() {
jQuery('img.grav-clone, a.grav-clone-a').remove();
Gravatar.hide_throbber();
},
"show_throbber": function() {
// console.log( 'throbbing...' );
if ( !Gravatar.throbber ) {
Gravatar.throbber = jQuery( '' );
}
jQuery( 'body' ).append( Gravatar.throbber );
var offset = jQuery('#' + Gravatar.active_id).offset();
Gravatar.throbber.css( {
top: offset.top + 2 + 'px',
left: offset.left + 1 + 'px'
} );
},
"hide_throbber": function() {
// Remove the throbber if it exists.
if ( !Gravatar.throbber ) {
return;
}
// console.log( 'stopped throbbing.' );
Gravatar.throbber.remove();
},
/***
* Helper Methods
*/
"fetch_profile_by_email": function( email ) {
// console.debug( 'fetch_profile_by_email' );
return this.fetch_profile_by_hash( this.md5( email ) );
},
"fetch_profile_by_hash": function( hash, dom_id ) {
// This is so that we know which specific Grav is waiting on us
this.profile_map[ 'g' + hash ] = dom_id;
// console.log( this.profile_map );
// If we already have it, no point getting it again, so just return it and notify any listeners
if ( this.profile_stack[ 'g' + hash ] && 'object' == typeof( this.profile_stack[ 'g' + hash ] ) )
return this.profile_stack[ 'g' + hash ];
// console.log( 'fetch_profile_by_hash: ' + hash, dom_id );
this.profile_stack[ 'g' + hash ] = 'fetching';
// Not using $.getJSON because it won't call an error handler for remote URLs
Gravatar.stat( 'fetch' );
this.load_js( 'http://en.gravatar.com/' + hash + '.json?callback=Gravatar.fetch_profile_callback', function() {
Gravatar.fetch_profile_error( hash, dom_id );
} );
},
"fetch_profile_callback": function( profile ) {
if ( !profile || 'object' != typeof( profile ) )
return;
// console.log( 'Received profile via callback:' );
// console.log( profile );
this.profile_stack[ 'g' + profile.entry[0].hash ] = profile;
this.notify( profile.entry[0].hash );
},
"fetch_profile_error": function( hash, dom_id ) {
Gravatar.stat( 'profile_404' );
Gravatar.profile_map[ 'g' + hash ] = false;
var grav = jQuery( '#' + dom_id );
if ( grav.parent( 'a[href=http://gravatar.com/' + hash + ']' ).size() ) {
grav.unwrap();
}
// console.debug( dom_id, Gravatar.active_id );
if ( dom_id == Gravatar.active_id ) {
Gravatar.hide_card();
}
},
"listen": function( key, callback ) {
if ( !this.notify_stack )
this.notify_stack = {};
key = 'g' + key; // Force valid first char
// console.log( 'listening for: ' + key );
if ( !this.notify_stack[ key ] )
this.notify_stack[ key ] = [];
// Make sure it's not already queued
for ( a = 0; a < this.notify_stack[ key ].length; a++ ) {
if ( callback == this.notify_stack[ key ][ a ] ) {
// console.log( 'already' );
return;
}
}
this.notify_stack[ key ][ this.notify_stack[ key ].length ] = callback;
// console.log( 'added listener: ' + key + ' => ' + callback );
// console.log( this.notify_stack );
},
"notify": function( key ) {
// console.log( 'trigger notification: ' + key );
if ( !this.notify_stack )
this.notify_stack = {};
key = 'g' + key; // Force valid first char
if ( !this.notify_stack[ key ] )
this.notify_stack[ key ] = [];
// Reverse it so that notifications are sent in the order they were queued
// console.log( 'notifying key: ' + key + ' (with ' + this.notify_stack[ key ].length + ' listeners)' );
for ( a = 0; a < this.notify_stack[ key ].length; a++ ) {
if ( false == this.notify_stack[ key ][ a ] || "undefined" == typeof( this.notify_stack[ key ][ a ] ) )
continue;
// console.log( 'send notification to: ' + this.notify_stack[ key ][ a ] );
Gravatar[ this.notify_stack[ key ][ a ] ]( key.substr( 1 ) );
this.notify_stack[ key ][ a ] = false;
}
},
"extract_hash": function( str ) {
// Get hash from img src
hash = /gravatar.com\/avatar\/([0-9a-f]{32})/.exec( jQuery( str ).attr( 'src' ) );
if ( null != hash && "object" == typeof( hash ) && 2 == hash.length ) {
hash = hash[1];
} else {
hash = /gravatar_id\=([0-9a-f]{32})/.exec( jQuery( str ).attr( 'src' ) );
if ( null !== hash && "object" == typeof( hash ) && 2 == hash.length ) {
hash = hash[1];
} else {
return false;
}
}
return hash;
},
"load_js": function( src, error_handler ) {
if ( !this.loaded_scripts )
this.loaded_scripts = [];
if ( this.loaded_scripts[ src ] )
return;
this.loaded_scripts[ src ] = true;
var new_script = document.createElement( 'script' );
new_script.src = src;
new_script.type = 'text/javascript';
if ( jQuery.isFunction( error_handler ) ) {
new_script.onerror = error_handler;
}
// console.log( src );
document.getElementsByTagName( 'head' )[0].appendChild( new_script );
},
"loaded_js": function( hash, dom_id ) {
Gravatar.profile_cb( hash, dom_id );
},
"add_card_css": function() {
if ( jQuery( '#gravatar-card-css' ).length )
return;
var urlS = jQuery( 'script[src*=gravatar.com/js/gprofiles.js]' ), url;
if ( urlS.size() )
url = urlS.attr( 'src' ).replace( /\/js\/gprofiles\.js.*$/, '' );
else
url = 'http://s.gravatar.com';
new_css = "";
new_css += "";
jQuery( 'head' ).append( new_css );
// console.log( 'Added CSS for profile cards to DOM' );
},
"md5": function( str ) {
return hex_md5( str );
},
"autofill": function( email, map ) {
// console.log('autofill');
if ( !email.length || -1 == email.indexOf( '@' ) )
return;
this.autofill_map = map;
hash = this.md5( email );
// console.log( this.profile_stack[ 'g' + hash ] );
if ( "undefined" == typeof( this.profile_stack[ 'g' + hash ] ) ) {
this.listen( hash, 'autofill_data' );
this.fetch_profile_by_hash( hash );
} else {
// console.log( 'stack: ' + this.profile_stack[ 'g' + hash ] );
this.autofill_data( hash );
}
},
"autofill_data": function( hash ) {
// console.log( this.autofill_map );
// console.log( this.profile_stack[ 'g' + hash ] );
GProfile.init( this.profile_stack[ 'g' + hash ] );
for ( var m in this.autofill_map ) {
// console.log( m );
// console.log( this.autofill_map[ m ] );
switch ( m ) {
case 'url':
link = GProfile.get( 'urls' );
// console.log( link );
jQuery( '#' + this.autofill_map[ m ] ).val( link[0][ 'value' ] );
break;
case 'urls':
links = GProfile.get( 'urls' );
links_str = '';
// console.log( links );
for ( l = 0; l < links.length; l++ ) {
links_str += links[ l ][ 'value' ] + "\n";
}
jQuery( '#' + this.autofill_map[ m ] ).val( links_str );
break;
default:
parts = m.split( /\./ );
if ( parts[ 1 ] ) {
val = GProfile.get( m );
switch ( parts[ 0 ] ) {
case 'ims':
case 'phoneNumbers':
val = val.value;
break;
case 'emails':
val = val[0].value;
case 'accounts':
val = val.url;
break;
}
jQuery( '#' + this.autofill_map[ m ] ).val( val );
} else {
jQuery( '#' + this.autofill_map[ m ] ).val( GProfile.get( m ) );
}
}
}
},
"whee": function() {
if ( Gravatar.whee.didWhee ) {
return;
}
Gravatar.whee.didWhee = true;
if ( document.styleSheets[0].addRule ) {
document.styleSheets[0].addRule( '.grav-tag a', 'background-position: 22px 100% !important' );
} else {
jQuery( '.grav-tag a' ).css( 'background-position', '22px 100%' );
}
jQuery( 'img[src*=gravatar.com/]' ).addClass( 'grav-whee' ).css( {
'-webkit-box-shadow': '1px 1px 3px #aaa',
'-moz-box-shadow': '1px 1px 3px #aaa',
'box-shadow': '1px 1px 3px #aaa',
'border': '2px white solid'
} );
var i = 0;
setInterval( function() {
jQuery( '.grav-whee' ).css( {
'-webkit-transform': 'rotate(-' + i + 'deg) scale(1.3)',
'-moz-transform': 'rotate(-' + i + 'deg) scale(1.3)',
'transform': 'rotate(-' + i + 'deg) scale(1.3)'
});
i++;
if ( 360 == i ) {
i = 0;
}
}, 6 );
return false;
},
"stat": function( stat, e ) {
Gravatar.stats_queue.push( stat );
if ( e ) {
var diffWindow = e.metaKey || '_blank' == jQuery( e.currentTarget ).attr( 'target' );
Gravatar.send_stats( function() {
if ( diffWindow ) {
return;
}
document.location = e.currentTarget.href;
} );
return diffWindow;
}
if ( Gravatar.stats_queue.length > 10 ) {
Gravatar.send_stats();
}
},
"send_stats": function( cb ) {
if ( !document.images ) {
return;
}
var stats = Gravatar.stats_queue;
if ( !stats.length ) {
return;
}
var date = new Date();
Gravatar.stats_queue = [];
var url = 'http://stats.wordpress.com/g.gif?v=wpcom&x_grav-hover=' + stats.join( ',' ) + '&rand=' + Math.random().toString() + '-' + date.getTime();
var img = new Image(1,1);
if ( jQuery.isFunction( cb ) ) {
img.onload = cb;
}
img.src = url;
}
}
jQuery( function() {
Gravatar.init();
});
/**
* Provides an interface for acceseing profile data returned from Gravatar.com.
* Use GProfile.init() to set up data, based on the JSON returned from Gravatar,
* then GProfile.get() to access data more easily.
*/
var GProfile = {
"data": {},
"init": function( data ) {
if ( 'fetching' == data )
return false;
if ( 'undefined' == typeof( data.entry[0] ) )
return false;
GProfile.data = data.entry[0];
},
/**
* Returns a value from the profile data.
* @param string attr The name of the attribute you want
* @param int num (Optional) 0-based array index of the value from this attribute. Use 0 if you're not sure
* @return Mixed value of the attribute, or empty string.
*/
"get": function( attr ) {
// Handle x.y references
if ( -1 != attr.indexOf( '.' ) ) {
parts = attr.split( /\./ );
// console.log(parts);
if ( GProfile.data[ parts[ 0 ] ] ) {
if ( GProfile.data[ parts[ 0 ] ][ parts[ 1 ] ] )
return GProfile.data[ parts[ 0 ] ][ parts[ 1 ] ]
for ( i = 0, s = GProfile.data[ parts[ 0 ] ].length; i < s; i++ ) {
if ( GProfile.data[ parts[ 0 ] ][ i ].type && parts[ 1 ] == GProfile.data[ parts[ 0 ] ][ i ].type // phoneNumbers | ims
|| GProfile.data[ parts[ 0 ] ][ i ].shortname && parts[ 1 ] == GProfile.data[ parts[ 0 ] ][ i ].shortname // accounts
|| GProfile.data[ parts[ 0 ] ][ i ].primary && parts[ 1 ] == 'primary' ) { // emails
return GProfile.data[ parts[ 0 ] ][ i ];
}
}
}
return '';
}
// Handle "top-level" elements
if ( GProfile.data[ attr ] )
return GProfile.data[ attr ];
// And some "aliases"
if ( 'url' == attr ) {
if ( GProfile.data.urls.length )
return GProfile.data.urls[0].value;
}
return '';
}
};
var grav_resize = {
card_id: '',
orig_width: 0,
orig_height: 0,
orig_top: 0,
orig_left: 0,
current_image: false,
init: function( card_id ) {
grav_resize.card_id = card_id;
grav_resize.bind_enlarge();
},
enlarge: function( el ) {
/* Remove any enlarged images */
if ( jQuery('img.grav-large').stop().remove().size() ) {
grav_resize.current_image = false;
return;
}
grav_resize.current_image = el.attr( 'src' );
/* Preload the larger version of the image */
jQuery( '#' + grav_resize.card_id + ' .grav-tag a' ).css( 'background-position', '22px 100%' );
var fullsize = jQuery('').attr( 'src', grav_resize.current_image + '&size=400' ).load( function() {
jQuery( '#' + grav_resize.card_id + ' .grav-tag a' ).css( 'background-position', '22px 0' );
} );
/* Clone the image */
var the_clone = el.clone();
the_clone.css({
'position': 'absolute',
'top': grav_resize.orig_top,
'left': grav_resize.orig_left,
'background-color': '#333',
'width': grav_resize.orig_width,
'height': grav_resize.orig_height,
'border-color': '#555'
});
the_clone.appendTo(el.parent());
/* Get the image ratio */
var horiz_padding = 0;
var vert_padding = 0;
var border_width = 6;
var card = jQuery( '#' + grav_resize.card_id + ' .grav-inner' );
if ( el.width() > el.height() ) {
var ratio = el.height() / el.width();
var width = card.outerWidth();
var height = ( width * ratio );
var vert_padding = ( card.outerHeight() - height ) / 2;
// if height it too big resize it width wise.
if ( height > card.outerHeight() ) {
var ratio = el.width() / el.height();
var height = card.outerHeight();
var width = ( height * ratio );
var horiz_padding = ( card.outerWidth() - width ) / 2;
}
} else {
var ratio = el.width() / el.height();
var height = card.outerHeight();
var width = ( height * ratio );
var horiz_padding = ( card.outerWidth() - width ) / 2;
}
the_clone.stop().animate({
'top': 0,
'left': 0,
'width': width - border_width + 'px',
'height': height - border_width + 'px',
'z-index': 99,
'padding-left': horiz_padding + 'px',
'padding-right': horiz_padding + 'px',
'padding-top': vert_padding + 'px',
'padding-bottom': vert_padding + 'px'
}, 250, function() {
/* Make the clone the fullsize image that was preloaded */
the_clone.addClass('grav-large');
the_clone.attr('src', fullsize.attr('src') );
/* Add the close button */
the_clone.parent().append('X
');
jQuery('.grav-large-close').hide().fadeIn(100);
} );
jQuery('#'+grav_resize.card_id+' .grav-gallery img').unbind('click');
jQuery('.grav-large-close' ).live( 'click', function() {
grav_resize.reduce( the_clone );
});
jQuery(the_clone).click( function() {
grav_resize.reduce( the_clone );
});
},
reduce: function( el ) {
jQuery('.grav-large-close').remove();
el.stop().animate({
'top': grav_resize.orig_top,
'left': grav_resize.orig_left,
'width': grav_resize.orig_width,
'height': grav_resize.orig_height,
'padding-left': 0,
'padding-right': 0,
'padding-top': 0,
'padding-bottom': 0
}, 250, function() {
jQuery('img.grav-large').remove();
grav_resize.bind_enlarge( grav_resize.card_id );
grav_resize.current_image = false;
});
},
bind_enlarge: function() {
jQuery('#' + grav_resize.card_id + ' .grav-gallery img').parent( 'a' ).click( function(e) {
if ( jQuery.browser.msie && jQuery.browser.version < 9.0 )
return;
e.preventDefault();
if ( grav_resize.current_image ) {
return;
}
var img = jQuery(this).find( 'img' ).not( '.grav-large' );
var position = img.position();
grav_resize.orig_width = img.width();
grav_resize.orig_height = img.height();
grav_resize.orig_top = position.top;
grav_resize.orig_left = position.left;
grav_resize.enlarge( img );
});
}
}
var grav_gallery = {
orig_left: 0,
pos: 0,
init: function( card ) {
grav_gallery.bind_arrows( card, true );
/* Also recheck the arrows are correct once the user hovers over the gallery section, in case the images took a while to load */
jQuery('#' + card + ' .grav-gallery').mouseover( function() {
grav_gallery.bind_arrows( card, false );
});
},
bind_arrows: function( card, reset ) {
var gallery_el = jQuery('#' + card + ' .grav-gallery ul');
if ( !gallery_el.size() ) {
return;
}
grav_gallery.orig_left = gallery_el.css('margin-left').replace('px','');
grav_gallery.pos = gallery_el.find( 'li:last').position();
jQuery('#' + card + ' a.grav-gallery-next').live( 'click', function() {
if ( grav_gallery.pos.left > 275 )
gallery_el.animate({'margin-left': parseFloat(grav_gallery.orig_left) - 314 + 'px'}, 300, function() { grav_gallery.highlight_arrows( card, false ); } );
return false;
});
jQuery('#' + card + ' a.grav-gallery-prev').live( 'click', function() {
if ( 0 != grav_gallery.orig_left )
gallery_el.animate({'margin-left': parseFloat(grav_gallery.orig_left) + 314 + 'px'}, 300, function() { grav_gallery.highlight_arrows( card, false ) } );
return false;
});
if ( reset )
jQuery('#' + card + ' .grav-gallery ul').css({'margin-left': 0});
grav_gallery.highlight_arrows( card, true );
},
highlight_arrows: function( card ) {
grav_gallery.orig_left = jQuery('#' + card + ' .grav-gallery ul').css('margin-left').replace('px','');
grav_gallery.last = jQuery('#' + card + ' .grav-gallery ul li:last');
if ( grav_gallery.last.position().left < 275 )
jQuery('#' + card + ' a.grav-gallery-next').css({'background-position': '-39px 0'});
else
jQuery('#' + card + ' a.grav-gallery-next').css({'background-position': '-26px 0'});
if ( 0 != grav_gallery.orig_left )
jQuery('#' + card + ' a.grav-gallery-prev').css({'background-position': '0 0'});
else
jQuery('#' + card + ' a.grav-gallery-prev').css({'background-position': '-13px 0'});
}
}
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
var hexcase=0;var b64pad="";var chrsz=8;function hex_md5(s){return binl2hex(core_md5(str2binl(s),s.length*chrsz))}function b64_md5(s){return binl2b64(core_md5(str2binl(s),s.length*chrsz))}function str_md5(s){return binl2str(core_md5(str2binl(s),s.length*chrsz))}function hex_hmac_md5(a,b){return binl2hex(core_hmac_md5(a,b))}function b64_hmac_md5(a,b){return binl2b64(core_hmac_md5(a,b))}function str_hmac_md5(a,b){return binl2str(core_hmac_md5(a,b))}function md5_vm_test(){return hex_md5("abc")=="900150983cd24fb0d6963f7d28e17f72"}function core_md5(x,e){x[e>>5]|=0x80<<((e)%32);x[(((e+64)>>>9)<<4)+14]=e;var a=1732584193;var b=-271733879;var c=-1732584194;var d=271733878;for(var i=0;i16)c=core_md5(c,a.length*chrsz);var d=Array(16),opad=Array(16);for(var i=0;i<16;i++){d[i]=c[i]^0x36363636;opad[i]=c[i]^0x5C5C5C5C}var e=core_md5(d.concat(str2binl(b)),512+b.length*chrsz);return core_md5(opad.concat(e),512+128)}function safe_add(x,y){var a=(x&0xFFFF)+(y&0xFFFF);var b=(x>>16)+(y>>16)+(a>>16);return(b<<16)|(a&0xFFFF)}function bit_rol(a,b){return(a<>>(32-b))}function str2binl(a){var b=Array();var c=(1<>5]|=(a.charCodeAt(i/chrsz)&c)<<(i%32);return b}function binl2str(a){var b="";var c=(1<>5]>>>(i%32))&c);return b}function binl2hex(a){var b=hexcase?"0123456789ABCDEF":"0123456789abcdef";var c="";for(var i=0;i>2]>>((i%4)*8+4))&0xF)+b.charAt((a[i>>2]>>((i%4)*8))&0xF)}return c}function binl2b64(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var c="";for(var i=0;i>2]>>8*(i%4))&0xFF)<<16)|(((a[i+1>>2]>>8*((i+1)%4))&0xFF)<<8)|((a[i+2>>2]>>8*((i+2)%4))&0xFF);for(var j=0;j<4;j++){if(i*8+j*6>a.length*32)c+=b64pad;else c+=b.charAt((d>>6*(3-j))&0x3F)}}return c};