Skip to content

Instantly share code, notes, and snippets.

@elisechant
Last active August 29, 2015 13:56
Show Gist options
  • Select an option

  • Save elisechant/8994912 to your computer and use it in GitHub Desktop.

Select an option

Save elisechant/8994912 to your computer and use it in GitHub Desktop.
Social share
var B_CBA = B_CBA || {};
(function ($) {
"use strict";
var $w = $(window),
BU = B_CBA.Util
;
/**
* Sharing Module
*/
B_CBA.Share = {
/**
* Class scope
*
* Initialise to null, set later with a
* jQuery selector
* @type {String}
*/
el: null,
/**
* Get the base url to share without any
* query string params
* @var {String}
*/
// url: 'http://blog.commbank.com.au', // use for test
url: window.location.href.split('?')[0],
network: {
facebook: {
// countApi: "https://api.facebook.com/method/links.getStats?urls={url}&format=json&callback=?",
countApi: "http://graph.facebook.com/?id={url}",
popupTitle: 'Share on Facebook',
width: 900,
height: 500,
href: "http://www.facebook.com/sharer/sharer.php?"
},
twitter: {
countApi: "http://cdn.api.twitter.com/1/urls/count.json?url={url}&callback=?",
popupTitle: 'Share on Twitter',
width: 900,
height: 500,
href: "https://twitter.com/intent/tweet?"
},
googleplus: {
popupTitle: 'Share on Google Plus',
width: 500,
height: 500,
href: "https://plus.google.com/share?"
},
linkedin: {
countApi: "http://www.linkedin.com/countserv/count/share?format=jsonp&url={url}&callback=?",
popupTitle: 'Share on Linked In',
width: 550,
height: 550,
href: "https://www.linkedin.com/cws/share?"
},
email: {
href: 'mailto:?'
}
},
/**
* Identifies the share count element
* @var {String} - jQuery selector
*/
countSelector: '.share-count',
/**
* Runs each instance of the network object in context
*
*/
instance: function() {
this.el = 'social-share';
var me = this,
$scope = $('#' + me.el);
if ( !!( $scope && $scope.length ) == false ) {
return;
}
$.each(me.network, function(network, defaults) {
var $parent = $('#share-' + network),
$countSelector = $parent.children(me.countSelector),
$buttonSelector = $parent.children('button'),
localParams = $buttonSelector.data(),
instance = {};
// create local instance objects
//
instance = $.extend(true, {}, defaults, localParams);
// Run
//
me.init(network, instance, $parent, $countSelector, $buttonSelector);
});
},
/**
* Start the class
*/
init: function(network, instance, $parent, $countSelector, $buttonSelector) {
var me = this,
countVal = 0;
// handle count
//
if (instance.countApi) {
// get the count value
me.getCount(network, instance.countApi);
// set the count value
$w.on('social::newCount', function(e, data) {
// get the right one
if (data.network === network) {
me.setCount(network, $countSelector, data.count);
countVal = $.isNumeric(data.count) ? data.count : '-';
}
});
}
// buttons are ready, enable the buttons
//
$buttonSelector.attr('disabled', false);
// handle url build and popup
//
$buttonSelector.on('click', function() {
var href = me.getHref(network, instance);
// trigger actions
if (network === 'email') {
window.location = href;
} else {
BU.openPopup(href, instance.popupTitle, instance.width, instance.height);
}
// simulate count
setTimeout(function() {
me.setCount(network, $countSelector, countVal+1);
}, 4000);
return false;
});
},
/**
* Get the count value for each network
* @param network
* @param countApi
* @returns Event, Event Object
*/
getCount: function(network, countApi) {
var me = this,
count,
url = me.url,
key = '{url}',
apiEndpoint = countApi ? countApi.replace(key, url) : '';
if (network === 'googleplus') {
return;
}
if (apiEndpoint !== undefined) {
$.getJSON(apiEndpoint, function(data) {
switch (network) {
case 'facebook':
count = data['shares'];
break;
case 'twitter':
count = data['count'];
break;
case 'googleplus':
// not able to process client side
break;
case 'linkedin':
count = data['count'];
break;
}
})
.done(function() {
$w.trigger('social::newCount', [{
network: network,
count: count
}]);
});
}
else {
throw "API url cannot be resolved, check B_CBA.share.url and B_CBA.network.[network].countApi";
}
},
/**
* Set the count value for each network instance
* @param network
* @param selector
* @param count
* @returns DOM update
*/
setCount: function(network, selector, count) {
var me = this;
selector.text(me.shorterTotal(count));
},
/**
* Build the share url for each network instance
* @param network
* @param $selector
* @returns {*}
*/
getHref: function(network, instance) {
var me = this,
href = instance['href'];
// Validate and transform the input
//
instance['url'] = encodeURIComponent(me.url);
instance['text'] = instance['text'] == undefined ? '' : instance['text'];
instance['hashtags'] = instance['hashtags'] == undefined ? '' : instance['hashtags'];
instance['via'] = instance['via'] == undefined ? '' : instance['via'];
instance['subject'] = instance['subject'] == undefined ? instance['text'] : encodeURIComponent(instance['subject']);
instance['body'] = instance['body'] == undefined ? '' : encodeURIComponent(instance['body']);
// append any available params to the share urls
//
switch(network) {
case 'facebook':
if (instance['url'].length) {
href += "u=" + instance['url'];
}
if (instance['text'].length) {
href += "&t="+ instance['text'];
}
break;
case 'twitter':
if (instance['text'].length) {
href += "text="+ instance['text'];
}
if (instance['hashtags'].length) {
href += "&hashtags=" + instance['hashtags'];
}
if (instance['url'].length) {
href += "&url=" + instance['url'];
}
if (instance['via'].length) {
href += "&via=" + instance['via'];
}
break;
case 'googleplus':
if (instance['url'].length) {
href += "url="+ instance['url'];
}
break;
case 'linkedin':
if (instance['url'].length) {
href += "url="+ instance['url'];
}
if (instance['text'].length) {
href += "&title=" + instance['title'];
}
href += "&token=&isFramed=true";
break;
case 'email':
if (instance['subject'].length) {
href += "subject=" + instance['text'];
}
if (instance['body'].length) {
href += "&body=" + instance['body'] + encodeURIComponent(' ') + instance['url'];
} else {
href += " " + instance['url'];
}
}
return href;
},
// utils
/**
* Format total numbers like 1.2k or 5M
* stolen from sharrre.js
* @param num
* @returns {*}
*/
shorterTotal: function (num) {
if (num >= 1e6){
num = (num / 1e6).toFixed(2) + "M"
} else if (num >= 1e3){
num = (num / 1e3).toFixed(1) + "k"
}
return num;
}
};
$($.proxy(B_CBA.Share.instance, B_CBA.Share));
}(jQuery));
<?php // Async loader for API's ?>
<div id="fb-root"></div>
<script type="text/javascript">
(function(doc, script) {
var js,
fjs = doc.getElementsByTagName(script)[0],
add = function(url, id) {
if (doc.getElementById(id)) {return;}
js = doc.createElement(script);
js.src = url;
id && (js.id = id);
fjs.parentNode.insertBefore(js, fjs);
};
// Google+ button
add('//apis.google.com/js/plusone.js');
// Facebook SDK
add('//connect.facebook.net/en_AU/all.js#xfbml=1', 'facebook-jssdk');
// Twitter SDK
add('//platform.twitter.com/widgets.js', 'twitter-wjs');
// Linked in
add('//platform.linkedin.com/in.js');
}(document, 'script'));
</script>
<?php // Open Graph tags (Facebook, Google, Linked In)
// todo - QA tags: http://developers.facebook.com/tools/debug/
$site_name = "Blog.CommBank";
$site_description = 'Primus, mirabilis particulas aegre imperium de nobilis, azureus planeta.';
$twitter_summary = "Twitter summary Who can meet the happiness and";
$twitter_handle = 'blog';
$twitter_author_handle = 'drewunsworth';
$article_title = '';
$article_url = '';
$article_description = '';
$article_image = '';
?>
<meta property="og:site_name" content="<?php echo $site_name ?>">
<meta property="og:title" content="<?php echo !empty($article_title) ? $article_title : $site_name ?>">
<meta property="og:url" content="<?php echo !empty($article_url) ? $article_url : 'http://blog.commbank.com.au/' ?>">
<meta property="og:type" content="<?php echo !empty($article_id) ? 'article' : 'blog' ?> ">
<meta property="og:description" content="<?php echo !empty($article_description) ? $article_description : $site_description ?>"><?php // up to 297 chars ?>
<meta property="og:locale" content="en_au">
<meta property="og:video" content="https://www.youtube.com/v/{{ youtube_id }}?version=3&amp;autohide=1" /><?php // usual youtube iframe ?>
<meta property="og:video:height" content="640" />
<meta property="og:video:width" content="385" />
<meta property=”og:image” content="<?php echo !empty($article_image) ? $article_image : 'favicon-tile' ?>"><?php // must be an absolute image path, min 50x50, ideal bigger than 200x200, max 5MB, linkedin requires w>150 & h>80, linkedin better with rect images (180x110) ?>
<meta property="og:image:type" content="{{ image_mime_type }}"><?php // like image/jpeg ?>
<meta property="og:image:width" content="{{ image_width }}">
<meta property="og:image:height" content="{{ image_height }}">
<?php // Twitter Card tags - todo - QA tags: https://dev.twitter.com/cards
// Twitter falls back to Open Graph if cards fails or there is no card, hence no article ?>
<meta name="twitter:card" content="<?= $twitter_summary ?>">
<meta name="twitter:site" content="<?= $twitter_handle ?>"><?php // like @cba ?>
<meta name="twitter:creator" content="<?= $twitter_author_handle ?>"><?php // handle of content creator/author ?>
<!--<meta name="twitter:account_id" content="14787749"><?php // http://gettwitterid.com/ ?>-->
<meta name="twitter:url" content="{{ article_url }}">
<meta name="twitter:title" content="{{ article_title }}"><?php // max 70 chars ?>
<meta name="twitter:description" content="{{ article_description }}"><?php // max 200 chars ?>
<?php // if video, use video, on fail fallback to twitter:image
// https://dev.twitter.com/docs/cards/types/player-card
// video come first because meta tags take the first valid tag it interprets
?>
<meta name="twitter:image:src" content="{{ article_image }}"><?php // max 1MB, must be an absolute image path ?>
<meta name="twitter:image:width" content="{{ article_image_width }}">
<meta name="twitter:image:height" content="{{ article_image_height }}">
<!--<meta name="twitter:player" content="{{ HTTPS_URL_to_iframe_player }}"><?php // youtube ?>-->
<!--<meta name="twitter:player:width" content="{{ player_width_number }}">-->
<!--<meta name="twitter:player:height" content="{{ player_height_number }}">-->
<?php // Google Plus ?>
<meta itemprop="name" content="{{ article_title }}">
<meta itemprop="description" content="{{ article_description }}">
<meta itemprop="image" content="{{ article_image }}"><?php // height >120, width>100, ratio<3.0 ?>
<ul id="social-share" class="social-share">
<?php
/*
* facebook
* https://developers.facebook.com/docs/plugins/share-button/
*
* google plus
* https://developers.google.com/+/web/share/
*
* Twitter
* https://dev.twitter.com/docs/tweet-button
*
* title - takes from html.title
*
*
* Linked In
* http://developer.linkedin.com/plugins/share-plugin-generator
* http://developer.linkedin.com/share-plugin-reference
*
*/
$custom_twitter_text_otherwise_is_html_title = "My competition is better than yours ";
$custom_hashtags = "awesome, chop"
?>
<li>
<div id="share-facebook" class="social-share__facebook">
<button disabled="true"
data-url="http://blog.commbank.com.au"
data-text="Visus, fiscina, et cobaltum"
><i class="icon icon-facebook"></i></button>
<span class="share-count">0</span>
</div>
</li>
<li>
<div id="share-twitter" class="social-share__twitter">
<button disabled="true"
data-url="http://blog.commbank.com.au"
data-text="horse ate soup"
data-hashtags="tag1, tag2"
data-via="henryunsworth"
><i class="icon icon-twitter"></i></button>
<span class="share-count">0</span>
</div>
</li>
<li>
<div id="share-googleplus" class="social-share__googleplus">
<button disabled="true"
data-url="http://blog.commbank.com.au"
data-text="Google Plus Title"
><i class="icon icon-google-plus"></i></button>
<span class="share-count">-</span>
</div>
</li>
<li>
<div id="share-linkedin" class="social-share__linkedin">
<button disabled="true"
data-url="http://blog.commbank.com.au"
data-text="horse ate soup"
><i class="icon icon-linkedin"></i></button>
<span class="share-count">0</span>
</div>
</li>
<li>
<div id="share-email" class="social-share__email">
<button disabled="true"
data-subject="Email headline text"
data-body="Email body text"
><i class="icon icon-envelope"></i></button>
</div>
</li>
</ul>
/*
|--------------------------------------------------------------------------
| Social share buttons
|--------------------------------------------------------------------------
*/
$INCLUDE_SOCIAL_SHARE_HTML: true;
@mixin share-button-arrow($color) {
position: relative;
//
&:after {
content: '';
position: absolute;
bottom: -8px;
left: 50%;
margin-left: -4px;
@include triangle(8px, $color, down)
}
}
@mixin social-share($layout-direction: 'vertical') {
@include clearfix;
$_layout-is-vertical: if($layout-direction == 'vertical', true, false);
display: block;
li {
width: 2*$h-gutter;
margin-bottom: $BASELINE/2;
margin-right: $h-gutter/2;
@if ($_layout-is-vertical == true) {
display: block;
}
@else {
float: left;
display: inline;
}
}
%social-parent {
.share-count {
display: block;
text-align: center;
display: block;
font-size: 12px;
margin-top: 6px;
font-family: $FONT_BOLD;
}
a,
button {
display: block;
width: 100%;
@include prefixer(appearance, none, webkit moz spec);
border: none;
padding: 6px 8px;
}
i {
color: $COLOR_WHITE;
font-size: 20px;
}
}
.social-share__facebook {
@extend %social-parent;
button {
background-color: $color-facebook;
@include share-button-arrow($color-facebook);
}
}
.social-share__twitter {
@extend %social-parent;
button {
background-color: $color-twitter;
@include share-button-arrow($color-twitter);
}
}
.social-share__googleplus {
@extend %social-parent;
button {
background-color: $color-googleplus;
@include share-button-arrow($color-googleplus);
}
}
.social-share__linkedin {
@extend %social-parent;
button {
background-color: $color-linkedin;
@include share-button-arrow($color-linkedin);
}
}
.social-share__email {
@extend %social-parent;
button {
background-color: $COLOR_SLATE;
}
}
}
// Init
//
@if ($INCLUDE_SOCIAL_SHARE_HTML == true) {
.social-share {
@include social-share;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment