can3p (can3p) wrote in changelog,
can3p
can3p
changelog

[livejournal] r18452: LJSUP-7759: Native sharing

Committer: dpetrov
LJSUP-7759: Native sharing
U   trunk/htdocs/js/share.js
Modified: trunk/htdocs/js/share.js
===================================================================
--- trunk/htdocs/js/share.js	2011-03-03 05:27:55 UTC (rev 18451)
+++ trunk/htdocs/js/share.js	2011-03-03 05:30:37 UTC (rev 18452)
@@ -1,6 +1,92 @@
 ;(function( window, $ ) {
 
+/**
+* 
+* Livejournal sharing script.
+* 
+* Usage:
+* 
+* .. Somewhere in the head ..
+* <script type="text/javascript">
+* 	//show only three links in popup by default
+* 	LJShare.init({"ml":{"close":"Close","title":"Share"},"links":["facebook","twitter","email"]})
+* </script>
+* 
+* .. Somewhere on the page ..
+* <a href="#">share</a>
+* <script type="text/javascript">
+* 	LJShare.link( {
+* 		"url":"http://community.livejournal.com/news/750.html",
+* 		"title":"Some title",
+* 		"description":"Some description",
+* 		"links": [ "twitter", "vkontakte", "moimir" ] //we want custom buttons there
+* 	});
+* </script>
+* 
+* 
+*/
+
+function preload( srcArr ) {
+	for( var i = srcArr.length; --i;
+		( new Image() ).src = srcArr[ i ] + '?' + Math.random() );
+}
+
+preload( [
+	'/img/popup-cls.gif',
+	'/img/popup-arr.gif',
+	'/img/icons/sharethis.gif'
+] );
+
+function supplant(str, o) {
+	return str.replace(/{([^{}]*)}/g,
+		function (a, b) {
+			var r = o[b];
+			return typeof r === 'string' || typeof r === 'number' ? r : a;
+		}
+	);
+};
+
+var selectors = {
+	close: ".i-popup-close",
+	links: ".b-sharethis-services a",
+	arrow: ".i-popup-arr"
+};
+
+// four arrow positions availible
+var arrow_opts = {
+	className: "i-popup-arr",
+	position: {
+		tl: "i-popup-arrtl",
+		tr: "i-popup-arrtr",
+		bl: "i-popup-arrbl",
+		br: "i-popup-arrbr"
+	}
+};
+
+var template = {
+	//here we take values from global_options.ml object
+	start: ' \
+		<div class="b-sharethis b-popup"> \
+			<div class="b-popup-outer"> \
+				<div class="b-popup-inner"> \
+					<div class="b-sharethis-head">{title}</div> \
+					<div class="b-sharethis-services">',
+	//here we take values from an object made from service object. Availible vars: name, url, title.
+	item: '<span class="b-sharethis-{name}"><a href="{url}" target="_blank">{title}</a></span>',
+	//here we take values from global_options.ml object
+	end: '</div> \
+				</div> \
+				<i class="i-popup-arr i-popup-arrtl"></i><i class="i-popup-close" title="{close}"></i> \
+			</div> \
+		</div>'
+};
+
+//buildLink takes values passed to the url with link method ( title, post url, description )
 var default_options = {
+	ml: {
+		close: "Close",
+		title: "Share"
+	},
 	services: {
 		livejournal: {
 			title: 'LiveJournal', bindLink: 'http://www.livejournal.com/update.bml?repost={url}'
@@ -33,6 +119,7 @@
 			title: 'Odnoklassniki', bindLink: 'http://www.odnoklassniki.ru/dk?st.cmd=addShare&st.s=1&st._surl={url}'
 		}
 	},
+	//list of links wich will be shown, when user will click on share link. Can be overriden in init and link methods.
 	links: [ 'livejournal', 'facebook', 'twitter', 'vkontakte', 'odnoklassniki', 'moimir', 'email', 'digg', 'tumblr', 'stumbleupon' ]
 };
 
@@ -40,13 +127,28 @@
 
 window.LJShare = {};
 
+/**
+* Overrides default options for current page.
+* 
+* @param Object opts Options object, may contain the following fields:
+*    ml - translation strings to use;
+*    services - An Object, that contains configuration fields for services links;
+*    links - array of links that will be shown to the user in popup.
+*/
 window.LJShare.init = function( opts ) {
 	if( opts ) {
-		global_options.services = $.extend( true, {}, default_options.services, opts.services );
+		global_options = $.extend( true, {}, default_options, opts );
 		global_options.links = opts.links || global_options.links;
 	}
 }
 
+/**
+* Bind share popup to the latest link found on the page
+* 
+* @param Object opts Options object, may contain the following fields:
+*    title, description, url - parameters of the page you want to share;
+*    links - array of links that will be shown to the user in popup.
+*/
 window.LJShare.link = function( opts ) {
 	var defaults = {
 		title: '',
@@ -57,33 +159,37 @@
 	var link = jQuery( 'a:last' ),
 		url = link.attr( 'href' ),
 		options = jQuery.extend( {}, defaults, { url: url } , opts ),
-		dom;
+		dom, arrow;
 
-	options.links = ( opts.links ) ? opts.links : global_options.links;
+	var links = ( opts.links ) ? opts.links : global_options.links;
 
 
 	function buildDom() {
-		var list = jQuery( '<ul>', { "class": 'ljshare-service-list' } ),
-			li, a, clickFunc;
+		var str = supplant( template.start, global_options.ml ),
+			serviceName, serviceObj;
 
-		for( var i = 0; i < options.links.length; ++i ) {
-			a = jQuery( '<a>' )
-				.html( global_options.services[ options.links[i] ].title );
+		for( var i = 0; i < links.length; ++i ) {
+			serviceName = links[i];
+			serviceObj = global_options.services[ serviceName ];
 
-			global_options.services[ options.links[i] ].href = a;
-			$( '<li>', { "class": 'ljshare-service-' + options.links[i] } )
-				.append( a )
-				.appendTo( list );
+			str+= supplant( template.item, {
+				name: serviceName,
+				title: serviceObj.title, 
+				url: supplant( serviceObj.bindLink, options )
+			} );
 		}
 
-		dom = $( '<div>', { 'class': 'ljshare-container' } ).css( {
+		str += supplant( template.end, global_options.ml );
+
+		dom = $( str ).css( {
 			position: 'absolute',
 			visibility: 'hidden'
-		} ).append( list );
+		} );
 	}
 
 	function injectDom() {
 		dom.appendTo( $( document.body ) );
+		arrow = dom.find( selectors.arrow );
 	}
 
 	function bindControls() {
@@ -91,57 +197,49 @@
 			ev.stopPropagation();
 		} );
 
-		$( window ).bind( 'click', function( ev ) {
-			togglePopup( false );
-		} );
-
-		for( var i = 0; i < options.links.length; ++i ) {
-			_bindLink( global_options.services[ options.links[i] ] );
-		}
+		dom.find( selectors.close ).bind( 'click', function( ev ) {	togglePopup( false ); } );
+		$( document ).bind( 'click', function( ev ) { togglePopup( false ); } );
+		$( window ).bind( 'resize', function( ev ) { togglePopup( false ); } );
+		dom.find( selectors.links ).click( function() { togglePopup( false ); } );
 	}
 
-	function _bindLink( service ) {
-		if( typeof service.bindLink === "string" ) {
-			callback = function() {
-				togglePopup( false );
-				window.open( service.bindLink.replace( "{url}", encodeURIComponent( options.url ) )
-																		.replace( "{title}", options.title ) );
-			}
-		} else {
-			callback = service.bindLink;
-		}
-		service.href.click( callback );
-	}
-
 	function updatePopupPosition() {
 		var linkPos = link.offset(),
-			linkH = link.height(), linkW = link.width();
+			linkH = link.height(), linkW = link.width(),
+			arrPos = "";
 
-		var scrollOffset = ( window.scrollY !== undefined ) ? scrollY :
-								( window.pageYOffset ) ? pageYOffset :
-								(((t = document.documentElement) || (t = document.body.parentNode)) && typeof t.ScrollTop == 'number' ? t : document.body).ScrollTop;
+		dom.css( { left: "0px", top: "0px" } );
 
+		var scrollOffset = $( window ).scrollTop();
 		var upperSpace = linkPos.top - scrollOffset;
 		var lowerSpace = $( window ).height() - upperSpace - linkH;
 		var domH = dom.height(), domW = dom.width();
 
 		var linkTop = linkPos.top, linkLeft = linkPos.left;
 
+
+		//we decide whether the popup should be shown under or above the link
 		if( lowerSpace < domH && upperSpace > domH ) {
 			linkTop -= domH + 5;
+			arrPos += "b";
 		} else {
 			linkTop += linkH + 5;
+			arrPos += "t";
 		}
 
+		//we decide whether the popup should positioned to the left or to the right from the link
 		var windowW = $( window ).width();
 		if( linkPos.left + domW > windowW ) {
-			linkLeft = windowW - domW - 10;
+			linkLeft = windowW - domW - 8;
+			arrPos += "r";
+		} else {
+			arrPos += "l";
+			linkLeft -= 30;
 		}
 
-		dom.css( {
-			left: linkLeft + "px",
-			top: linkTop + "px"
-		} );
+		arrow.removeClass().addClass( arrow_opts.className ).addClass( arrow_opts.position[ arrPos ] ); 
+
+		dom.css( { left: linkLeft + "px",top: linkTop + "px" } );
 	}
 
 	function togglePopup( show ) {

Tags: can3p, js, livejournal
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 1 comment