Skip to content

Instantly share code, notes, and snippets.

@dgs700
Last active December 17, 2015 08:38
Show Gist options
  • Save dgs700/5581232 to your computer and use it in GitHub Desktop.
Save dgs700/5581232 to your computer and use it in GitHub Desktop.
Tibbr App Framework bootstrap code - Angularjs and some bare metal js
//Tibbr plugins html directives and associated controllers
(function () {
'use strict';
//declare the plugins module with dependancies
var tibbrPlugins = angular.module('TibbrPlugins', [
'TibbrFilters',
'Tibbr',
'EventsBus',
'PageBus',
'TibbrAPI',
'LoginCheck',
'Params',
'ProxyCallbacks'
]);
//"Like" component directive
tibbrPlugins.directive('tibrLikeInline', [
'$window',
'$_tibbr',
function factory($window, $_tibbr) {
return {
template: '<a href="javascript:void(0);">' +
'<i ng-class="likeClass" class="like-link" ng-click="toggleLike()" style="background-image: url(' +
$_tibbr.host +
'/connect/stylesheets/images/widget.png)"></i>' +
'<span class="mid-dot">·</span>' +
'<span class="count">{{likeCount}}</span>' +
'</a>',
//priority: 0,
controller: 'LikeController',
link: function postLink(scope, elm, attrs) {
}
};
}]);
tibbrPlugins.controller('LikeController', [
'$scope',
'$_tibbr',
'$_tibbrAPI',
'$_constants',
function factory($scope, $_tibbr, $_tibbrAPI, $_constants) {
//api call for likes
$scope.snippet = '';
$scope.likeCount = 0;
$scope.publish = function (params) {
$_tibbrAPI({
url: $_constants.URLS.publish,
method: "POST",
params: params
}, $scope).then(function (data) {
$scope.onLikeResponse(data.r);
},
function(data){
console.warn(data);
});
};
//api call for unlike
$scope.unpublish = function (id, responseHandler) {
$_tibbrAPI({
url: '/actions/' + id + '/unpublish',
method: "DELETE"
}, $scope).then(function (data) {
$scope.onLikeResponse(data.r);
},
function(data){
console.warn(data);
});
};
//callback function passed as a param to the like api methods
$scope.onLikeResponse = function (data, rc) {
data = data || {};
//be sure to reset any necessary vars
//var user = {};
if (data.id) { //eog action id
$scope.liked = true;
$scope.likeClass = 'like-link liked';
$scope.likeCount++;
$scope.likedActionId = data.id;
} else {
$scope.liked = false;
$scope.likeClass = 'like-link unliked';
$scope.likeCount--;
$scope.likedActionId = null;
}
};
$scope.toggleLike = function () {
var params = {};
if ($scope.liked) {
$scope.unpublish($scope.likedActionId, $scope.onLikeResponse);
$scope.liked = false;
} else {
params = {
resource: $scope.resource,
action_type: 'og:like',
client_id: $_tibbr.client_id
};
$scope.publish(params, $scope.onLikeResponse);
$scope.liked = true;
}
};
}]);
//Comments and replies component plugin
tibbrPlugins.directive('tibrCommentInline', [
'$window',
'$_tibbr',
function factory($window, $_tibbr) {
return {
template: '<a href="javascript:void(0);">' +
'<i class="reply-link" ng-click="toggleComments()" style="background-image: url(' +
$_tibbr.host +
'/connect/stylesheets/images/widget.png)"></i>' +
'<span class="mid-dot">·</span>' +
'<span class="count">{{commentCount}}</span>' +
'<div class="post-section {{direction}}" ng-show="commentContainer" ng-bind-html-unsafe="commentContainer"></div>' +
'</a>',
//priority: 0,
controller: 'CommentController',
link: function postLink(scope, elm, attrs) {
}
};
}]);
tibbrPlugins.controller('CommentController', [
'$scope',
'$_tibbr',
'$_pagebus',
'$_constants',
'$_params',
'$_proxyCallbacks',
function factory($scope, $_tibbr, $_pagebus, $_constants, $_params, $_proxyCallbacks) {
$scope.c_iframe = {
width: "625px",
scrolling: "no",
allowtransparency: "true",
frameborder: "0",
visibility: "visible",
style: "visibility: visible; border: 1px solid transparent; background-image: none; background-color: transparent; height: 600px;"
};
$scope.toggleComments = function () {
$scope.loginCheck();
if ($scope.commentContainer || $scope.commentContainerInline) {
$scope.commentContainer = $scope.commentContainerInline = '';
} else {
$scope.shareContainer = $scope.shareContainerInline = ''; //need to emit? and have the container handle?
var id = "comments_box_proxy" + Math.floor((Math.random() * 100) + 1); //create unique id since multiple comments boxes may co exist
$scope.c_iframe.id = id;
//including all comments options by default for now
var params = {
resource: $scope.resource,
client_id: $_tibbr.client_id,
prefixUrl: $_tibbr.host,
file: true,
link: true,
profile_hover: true,
show_pbox: 1
};
var proxyOpts = {
url: $_tibbr.host + $_constants.URLS.commentsPlugin + $_params(params),
id: id,
container: undefined,
frameOptions: $scope.c_iframe,
onConnect: function () {
var handlerId = "tibbr:" + id + ":call";
$_pagebus.subscribe(handlerId, function (data) {
$scope.$apply(function () {
//this is pretty flimsy
$scope.c_iframe.height = $_proxyCallbacks[data.func]($scope, id, data.args, handlerId);
$scope.$c_frame.attr('height', $scope.c_iframe.height);
});
});
}
}
$scope.c_frame = $scope.c_frame || $_tibbr.createProxyClient(proxyOpts); //create the proxy first time only
$scope.$c_frame = angular.element($scope.c_frame); //jqlite ref for setting height
if ($scope.inline) {
$scope.commentContainerInline = $scope.c_frame;
} else {
$scope.commentContainer = $scope.c_frame;
}
}
};
}]);
//share component
tibbrPlugins.directive('tibrShareInline', [
'$window',
'$_tibbr',
function factory($window, $_tibbr) {
return {
template: '<a href="javascript:void(0);">' +
'<i class="ui-inline-icon share-icon" ng-click="toggleShareBox()" style="background-image: url(' +
$_tibbr.host +
'/connect/stylesheets/images/widget.png)"></i>' +
'<span class="mid-dot">·</span>' +
'<span class="count">{{shareCount}}</span>' +
'<div class="post-section {{direction}}" ng-show="shareContainer" ng-bind-html-unsafe="shareContainer"></div>' +
'</a>',
//priority: 0,
controller: 'ShareController',
link: function postLink(scope, elm, attrs) {
}
};
}]);
tibbrPlugins.controller('ShareController', [
'$scope',
'$_tibbr',
'$_pagebus',
'$_constants',
'$_params',
'$_proxyCallbacks',
function factory($scope, $_tibbr, $_pagebus, $_constants, $_params, $_proxyCallbacks) {
$scope.s_iframe = {
width: "625px",
scrolling: "no",
allowtransparency: "true",
frameborder: "0",
visibility: "visible",
style: "visibility: visible; border: 1px solid transparent; background-image: none; background-color: transparent; height: 600px;"
};
$scope.toggleShareBox = function () {
if ($scope.shareContainer || $scope.shareContainerInline) {
$scope.shareContainer = $scope.shareContainerInline = '';
} else {
$scope.loginCheck();
$scope.commentContainer = $scope.commentContainerInline = '';
var id = "share_box_proxy" + Math.floor((Math.random() * 100) + 1); //create unique id since multiple comments boxes may co exist
$scope.s_iframe.id = id;
//including all comments options by default for now
var params = {
resource: $scope.resource,
client_id: $_tibbr.client_id,
prefixUrl: $_tibbr.host
};
var proxyOpts = {
url: $_tibbr.host + $_constants.URLS.sharePlugin + $_params(params),
id: id,
container: undefined,
frameOptions: $scope.s_iframe,
onConnect: function () {
var handlerId = "tibbr:" + id + ":call";
$_pagebus.subscribe(handlerId, function (data) {
$scope.$apply(function () {
$scope.s_iframe.height = $_proxyCallbacks[data.func]($scope, id, data.args, handlerId);
$scope.$s_frame.attr('height', $scope.s_iframe.height);
});
});
}
}
$scope.s_frame = $scope.s_frame || $_tibbr.createProxyClient(proxyOpts); //create the proxy first time only
$scope.$s_frame = angular.element($scope.s_frame); //jqlite ref for setting height
if ($scope.inline) {
$scope.shareContainerInline = $scope.s_frame;
} else {
$scope.shareContainer = $scope.s_frame;
}
}
};
}]);
//code to run when a social bar is encountered
tibbrPlugins.directive('tibrSocialBar', [
'$window',
function factory($window) {
var directiveDefinitionObject = {
//use inline template for production to avoid cross frame html loading restrictions
template: '<div class="social">' +
'<div class="table-footer" colspan="4">' +
'<ul class="stats">' +
'<li ng-show="showLike"><span tibr-like-inline></span></li>' +
'<li ng-show="showComment"><span tibr-comment-inline></span></li>' +
'<li ng-show="showShare"><span tibr-share-inline></span></li>' +
'</ul>' +
'</div>' +
'<div class="post-section-inline" ng-bind-html-unsafe="commentContainerInline" style="position:static"></div>' +
'<div class="post-section-inline" ng-bind-html-unsafe="shareContainerInline" style="position:static"></div>' +
'</div>',
//templateUrl: $_tibbr.host + $_tibbr.scriptsBasePath + 'partials/social_bar.html',
replace: true,
scope: {},
controller: 'SocialController',
compile: function (elm, attrs) {
return function postLink(scope, elm, attrs) {
//pull the resource info form the tag attributes
scope.resource = {
id: attrs.ogId || null, //required if exists
//or for dirty resource
url: attrs.ogUrl || $window.location.href, //required, default
key: attrs.ogKey || null,
title: attrs.ogTitle || null,
image: attrs.ogImage || null,
description: attrs.ogDescription || null,
type: attrs.ogType || "og:link"
};
//see which pluging are wanted
if (attrs.include) {
var plugins = attrs.include;
if (plugins.indexOf('like') != -1)
scope.showLike = true;
if (plugins.indexOf('comment') != -1)
scope.showComment = true;
if (plugins.indexOf('share') != -1)
scope.showShare = true;
}
//the default display for iframes is inline
if (attrs.inline == 'false') {
scope.inline = false;
}
//internal tibbr passed in attributes
scope.likeCount = (attrs.likeCount) ? attrs.likeCount : 0;
scope.shareCount = (attrs.shareCount) ? attrs.shareCount : 0;
scope.commentCount = (attrs.commentCount) ? attrs.commentCount : 0;
scope.likedActionId = attrs.likedActionId;
if (scope.likedActionId) {
scope.liked = true;
scope.showLike = true;
scope.likeClass = 'like-link liked';
}
scope.shared = attrs.shared;
if (scope.shared) {
scope.shared = true;
scope.showShare = true;
}
scope.commented = attrs.commented;
if (scope.commented) {
scope.commented = true;
scope.showComment = true;
}
scope.initialApiObj.params.resource = scope.resource;
//this is required to avoid an unnecessary api call for initial info
//if we are injecting any action data
if (attrs.initialized) {
scope.initialized = true;
} else {
scope.init();
}
};
}
//link: function postLink(scope, elm, attrs) {...}
};
return directiveDefinitionObject;
}]);
//app logic and template vars for the like template
tibbrPlugins.controller('SocialController', [
'$scope',
'$_tibbr',
'$_events',
'$_tibbrAPI',
'$_loginCheck',
'$_constants',
function factory($scope, $_tibbr, $_events, $_tibbrAPI, $_loginCheck, $_constants) {
//set some default values for the template vars
$scope.loginCheck = $_loginCheck;
//$scope.showLike = false;
var socialModel = {
currentUser: $_tibbr.currentUser,
host: $_tibbr.host,
resourceType: "og:link",
//following: false,
//followStatus: 'follow',
//canFollow: false, // can user follow
likeCount: 0,
likedActionId: null, //needs to be included in tibbr resource object
liked: false,
likeClass: 'like-link unliked',
commentCount: 0,
commented: false,
commentContainer: '',
commentContainerInline: '',
shareCount: 0,
shared: false,
shareContainer: '',
shareContainerInline: '',
inline: true, //display any iframes inline with the social bar vs as a pop-up
direction: 'south-east'
//see_detail: "see_detail"
};
angular.extend($scope, socialModel);
// legacy code depends on an outside login event for proper functioning
// get the resource profile info when this comp is created
$scope.initialApiObj = {
url: $_constants.URLS.profile,
params: {
resource: $scope.resource,
client_id: $_tibbr.client_id,
include_user_actions: "og:like,og:share,og:comment", //,og:follow",
include_action_count: "og:like,og:share,og:comment", //,og:follow",
include_actions: "og:like,og:share,og:comment", //,og:follow",
per_page: 5
},
method: "GET",
onResponse: function (data, status) {
$scope.resourceObj = data;
$scope.userPermission = data.actions;
$scope.userPerformedActions = data.og_action_performed;
$scope.likeCount = data.action_counts.og_like;
$scope.shareCount = data.action_counts.og_share;
$scope.commentCount = data.action_counts.og_comment;
if (data.og_action_performed.indexOf("og:like") != -1) {
$scope.liked = true;
$scope.likeClass = 'like-link liked';
$scope.likedActionId = data.user_action_list.og_like.items[0].id; //change to dot notation on next update
}
if ($scope.userPermission.indexOf("unfollow") != -1) {
$scope.canFollow = true;
$scope.following = true;
}
if ($scope.userPermission.indexOf("follow") != -1) {
$scope.canFollow = true;
}
$scope.currentUser = $_tibbr.currentUser;
}
};
//make an api call for initial info if not already injected
//social components in 3rd party pages will typically need to call this
$scope.init = function () {
if (!$scope.initialized) {
$_events.on('login', function (data) {
$_tibbrAPI($scope.initialApiObj, $scope).then(function (data) {
$scope.initialApiObj.onResponse(data.r);
},function(data){
console.warn(data);
});
$scope.initialized = true;
});
}
};
}]);
})();
//tibbr services (wrappers around XDM/ajax for now) and filters
(function () {
'use strict';
/* Services - most of these are just stubs or wrappers for now*/
//grab an angular reference to global TIBR (for now)
angular.module('Tibbr', []).factory('$_tibbr', function ($window) {
var PB = $window.TIBR;
return PB;
});
// get tibbr api resource info either passed in by param or scrapped from meta tags
angular.module('EventsBus', ['Tibbr']).factory('$_events', function ($_tibbr) {
var evts = $_tibbr.events;
return evts;
});
// get tibbr api resource info either passed in by param or scrapped from meta tags
angular.module('PageBus', ['Tibbr']).factory('$_pagebus', function ($_tibbr) {
var pagebus = $_tibbr.PageBus;
return pagebus;
});
// get tibbr api resource info either passed in by param or scrapped from meta tags
angular.module('LoginCheck', ['Tibbr']).factory('$_loginCheck', function ($_tibbr) {
var loginCheck = function (callback) {
if ($_tibbr.loggedIn) {
return true;
} else {
$_tibbr.login(callback);
return false;
}
};
return loginCheck;
});
//grab an angular reference to global TIBR.api
//required params - a params object that includes a url, method
//returns a scoped promise
angular.module('TibbrAPI', [
'Tibbr',
'PageBus',
'LoginCheck'
]).factory('$_tibbrAPI', function ($_tibbr, $_pagebus, $_loginCheck, $q) {
var api = function (args, scope) {
var deferred = $q.defer();
if (!args || !scope) {
//return function () {
console.warn('No arguments or scope object passed to tibbr.api()');
deferred.reject('No arguments or scope object passed to tibbr.api()');
return deferred.promise;
//};
}
if (!$_tibbr.loggedIn) {
$_loginCheck();
deferred.reject('Not logged in.');
return deferred.promise;
}
//args.onResponse = args.onResponse || function () {
//};
var handlerId = args.handlerId = "api:response:" + Math.floor(Math.random() * 1111);
args.url = $_tibbr.host + "" + args.url;
// assign client id in each api call if not provided by end user
if (args.params && !args.params.client_id && $_tibbr.client_id) {
args.params.client_id = $_tibbr.client_id;
}
var params = {
u: args.url,
m: args.method,
t: args.type,
d: args.params,
hid: handlerId
};
$_pagebus.subscribe(handlerId, function (data) {
if (data.rc == 200) {
scope.$apply(function () {
deferred.resolve(data);
});
}else{
scope.$apply(function () {
deferred.reject(data);
});
}
$_pagebus.unsubscribe(handlerId);
});
$_pagebus.publish("api:call", params);
return deferred.promise;
};
return api;
});
// get tibbr api resource info either passed in by param or scrapped from meta tags
//not used currently
angular.module('ResourcePrep', ['Tibbr']).factory('$_resourcePrep', function ($_tibbrAPI, $_tibbr, $_events) {
var resourcePrep = function (scope, resourceId) {
resourceId = resourceId || {
id: 24
};
// add code to pull the info from meta tags or use the config or build a default
var resource = resourceId;
$_events.on('login', function (data) {
$_tibbrAPI({
url: "/resources/profile",
params: {
resource: resourceId,
client_id: $_tibbr.client_id,
include_user_actions: "og:like,og:share,og:comment",
include_action_count: "og:like,og:share,og:comment",
include_actions: "og:like,og:share,og:comment",
per_page: 5
},
method: "GET"
}, scope).then(function(data){
//do call back stuff
});
});
return resource;
};
return resourcePrep;
});
//things to do when info returns from the client proxy frame
angular.module('ProxyCallbacks', ['Tibbr']).factory('$_proxyCallbacks', function ($_tibbrAPI, $_tibbr, $_events, $_constants) {
//add any subscribe evt handlers to listen for any function invoke requests from any child iframes
//the function name must match and so should the args
var proxyCallbacks = {
setheight: function (scope, id, height) {
//do any other stuff here
return height;
},
resetsharebox: function (scope, id, args, handl) {
//do any other stuff here
$_tibbr.PageBus.unsubscribe(handl);
},
updatesharecount: function (scope, id, resource) {
$_tibbr.api({
url: $_constants.URLS.shareCount,
method: "GET",
params: {
resource: resource
}
}, scope).then(function(data){
//do call back stuff
});
},
resourceclicked: function (scope, id, obj) {
//if (_onResourceClickHandlers[id]) {
// _onResourceClickHandlers[id](obj);
//}
},
onMeetingCreate: function (scope, id, obj){}
};
return proxyCallbacks;
});
// get tibbr api resource info either passed in by param or scrapped from meta tags
angular.module('Params', []).factory('$_params', function () {
function buildParams(prefix, obj, add) {
var name, i, l, rbracket;
rbracket = /\[\]$/;
if (obj instanceof Array) {
for (i = 0, l = obj.length; i < l; i++) {
if (rbracket.test(prefix)) {
add(prefix, obj[i]);
} else {
buildParams(prefix + "[" + ( typeof obj[i] === "object" ? i : "" ) + "]", obj[i], add);
}
}
} else if (typeof obj == "object") {
// Serialize object item.
for (name in obj) {
buildParams(prefix + "[" + name + "]", obj[ name ], add);
}
} else {
// Serialize scalar item.
add(prefix, obj);
}
}
return function (a) {
var prefix, s, add, name, r20, output;
s = [];
r20 = /%20/g;
add = function (key, value) {
// If value is a function, invoke it and return its value
value = ( typeof value == 'function' ) ? value() : ( value == null ? "" : value );
s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
};
if (a instanceof Array) {
for (name in a) {
add(name, a[name]);
}
} else {
for (prefix in a) {
buildParams(prefix, a[ prefix ], add);
}
}
output = s.join("&").replace(r20, "+");
return output;
};
});
//filters like i18n
angular.module('TibbrFilters', ['Constants']).filter('translate', function ($_constants) {
return function (input) {
var out = ($_constants.I18N[input]) ? $_constants.I18N[input] : input;
return out;
}
});
//TIBR strings (don't inject any dependancies here)
angular.module('Constants', []).factory('$_constants', function () {
var isNotIE8 = (function () {
var rv = 100;
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null) {
rv = parseFloat(RegExp.$1);
}
}
return (rv >= 9) ? true : false;
})();
var JS_PATH = "/connect/js/";
var TIBBR_PATH = "";
return {
//javascript
PAGEBUS: JS_PATH + ((isNotIE8) ? 'pagebus-ie8plus-min' : 'pagebus'),
TIB_MIN: JS_PATH + "tib-min",
PLUGINS: JS_PATH + "plugins",
PARENT_CONNECTOR: JS_PATH + 'parent_connector',
//html, css
PLUGIN_CSS: "/connect/stylesheets/tibbr_share-min.css",
CONNECT_PROXY: '/connect/connect_proxy_min',
//api urls
USERS_URL: "/users/find_by_session",
I18N_URL: "/plugins/connect_translate",
I18N: {
share: "Share",
follow: "Follow",
unfollow: "Unfollow",
like: "Like",
unlike: "Unlike",
first_one: "Be the first one to like this",
you: "You",
and: " and ",
like_this: " like this",
likes_this: " likes this",
one_other: " and 1 other like this",
others: " others like this",
not_logged_in: "You need to login to tibbr.",
login: " Click <a href='#' class='tib-login-link'>here</a> to login.",
see_detail: "See detail"
},
URLS: {
share: "/plugins/#!/share",
sharePlugin: "/plugins/#!/share?ojbref=TIBR&",
shareCount: "/plugins/share_count",
comments: "/resources/comments",
commentCount: "/plugins/comments_count", //????
commentsPlugin: "/plugins/#!/comments?ojbref=TIBR&",
publish: "/actions/publish",
unpublish: "/actions/id/unpublish",
post_like: "/plugins/like",
get_like: "/plugins/get_like",
followResource: "/resources/follow",
unfollowResource: "/resources/unfollow",
unfollow: "/resources/unfollow",
followerList: "/resources/followers",
getResourcePermissions: "/resources/user_permissions",
userPermissions: "/resources/user_permissions",
userActions: "/resources/user_actions",
actionUser: "/actions/users",
follow: "/resources/follow",
actionCount: "/actions/count",
profile: "/resources/profile.json"
}
}
});
})();
//head.js minimal scritp loader
(function(f,w){function m(){}function g(a,b){if(a){"object"===typeof a&&(a=[].slice.call(a));for(var c=0,d=a.length;c<d;c++)b.call(a,a[c],c)}}function v(a,b){var c=Object.prototype.toString.call(b).slice(8,-1);return b!==w&&null!==b&&c===a}function k(a){return v("Function",a)}function h(a){a=a||m;a._done||(a(),a._done=1)}function n(a){var b={};if("object"===typeof a)for(var c in a)a[c]&&(b={name:c,url:a[c]});else b=a.split("/"),b=b[b.length-1],c=b.indexOf("?"),b={name:-1!==c?b.substring(0,c):b,url:a};
return(a=p[b.name])&&a.url===b.url?a:p[b.name]=b}function q(a){var a=a||p,b;for(b in a)if(a.hasOwnProperty(b)&&a[b].state!==r)return!1;return!0}function s(a,b){b=b||m;a.state===r?b():a.state===x?d.ready(a.name,b):a.state===y?a.onpreload.push(function(){s(a,b)}):(a.state=x,z(a,function(){a.state=r;b();g(l[a.name],function(a){h(a)});j&&q()&&g(l.ALL,function(a){h(a)})}))}function z(a,b){var b=b||m,c;/\.css[^\.]*$/.test(a.url)?(c=e.createElement("link"),c.type="text/"+(a.type||"css"),c.rel="stylesheet",
c.href=a.url):(c=e.createElement("script"),c.type="text/"+(a.type||"javascript"),c.src=a.url);c.onload=c.onreadystatechange=function(a){a=a||f.event;if("load"===a.type||/loaded|complete/.test(c.readyState)&&(!e.documentMode||9>e.documentMode))c.onload=c.onreadystatechange=c.onerror=null,b()};c.onerror=function(){c.onload=c.onreadystatechange=c.onerror=null;b()};c.async=!1;c.defer=!1;var d=e.head||e.getElementsByTagName("head")[0];d.insertBefore(c,d.lastChild)}function i(){e.body?j||(j=!0,g(A,function(a){h(a)})):
(f.clearTimeout(d.readyTimeout),d.readyTimeout=f.setTimeout(i,50))}function t(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",t,!1),i()):"complete"===e.readyState&&(e.detachEvent("onreadystatechange",t),i())}var e=f.document,A=[],B=[],l={},p={},E="async"in e.createElement("script")||"MozAppearance"in e.documentElement.style||f.opera,C,j,D=f.head_conf&&f.head_conf.head||"head",d=f[D]=f[D]||function(){d.ready.apply(null,arguments)},y=1,x=3,r=4;d.load=E?function(){var a=arguments,b=a[a.length-
1],c={};k(b)||(b=null);g(a,function(d,e){d!==b&&(d=n(d),c[d.name]=d,s(d,b&&e===a.length-2?function(){q(c)&&h(b)}:null))});return d}:function(){var a=arguments,b=[].slice.call(a,1),c=b[0];if(!C)return B.push(function(){d.load.apply(null,a)}),d;c?(g(b,function(a){if(!k(a)){var b=n(a);b.state===w&&(b.state=y,b.onpreload=[],z({url:b.url,type:"cache"},function(){b.state=2;g(b.onpreload,function(a){a.call()})}))}}),s(n(a[0]),k(c)?c:function(){d.load.apply(null,b)})):s(n(a[0]));return d};d.js=d.load;d.test=
function(a,b,c,e){a="object"===typeof a?a:{test:a,success:b?v("Array",b)?b:[b]:!1,failure:c?v("Array",c)?c:[c]:!1,callback:e||m};(b=!!a.test)&&a.success?(a.success.push(a.callback),d.load.apply(null,a.success)):!b&&a.failure?(a.failure.push(a.callback),d.load.apply(null,a.failure)):e();return d};d.ready=function(a,b){if(a===e)return j?h(b):A.push(b),d;k(a)&&(b=a,a="ALL");if("string"!==typeof a||!k(b))return d;var c=p[a];if(c&&c.state===r||"ALL"===a&&q()&&j)return h(b),d;(c=l[a])?c.push(b):l[a]=[b];
return d};d.ready(e,function(){q()&&g(l.ALL,function(a){h(a)});d.feature&&d.feature("domloaded",!0)});if("complete"===e.readyState)i();else if(e.addEventListener)e.addEventListener("DOMContentLoaded",t,!1),f.addEventListener("load",i,!1);else{e.attachEvent("onreadystatechange",t);f.attachEvent("onload",i);var u=!1;try{u=null==f.frameElement&&e.documentElement}catch(F){}u&&u.doScroll&&function b(){if(!j){try{u.doScroll("left")}catch(c){f.clearTimeout(d.readyTimeout);d.readyTimeout=f.setTimeout(b,50);
return}i()}}()}setTimeout(function(){C=!0;g(B,function(b){b()})},300)})(window);
(function (global) {
//PLACE ALL STING DEPENDENCIES AT THE TOP OF THIS FILE SO CHANGES ARE LESS PAINFUL
var TIBR = global.TIBR || {};
if(TIBR.initialized)
return;
TIBR.scriptsBasePath = "/connect/js/";
//set to true if the browser is not IE 8 or below to load the most minimal
//standards complient XDM and toolkits
var isNotIE8 = (function () {
var rv = 100;
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null) {
rv = parseFloat(RegExp.$1);
}
}
return (rv >= 9) ? true : false;
})();
//filenames for various combos of connect scripts and css to be loaded based on specific app needs
var tibIncludes = {
pagebus: (isNotIE8) ? 'pagebus-ie8plus-min' : 'pagebus-min',
tibbrPagebus: 'tibbr.pagebus-min',
socialCSS: "/connect/stylesheets/tibbr_social.css",
connectProxy: (isNotIE8) ? '/connect/connect_proxy_min' : '/connect/connect_proxy_ie',
angularjs: 'angular.min',
app: 'app',
services: 'services',
jquery: 'jquery.min'
};
//url path strings
var tibURLs = {
usersBySession: "/users/find_by_session",
pluginsTranslate: "/plugins/connect_translate",
connectConfig: "/plugins/connect_config",
tibbrPath: "/tibbr", //default url path to tibbr server instance
scriptsPath: _scriptsBasePath
};
var tibTopics = {
proxyConnected: "tibbr:proxy:connected",
loginRequest: "tibbr:login:request",
loginResponse: "tibbr:login:response",
};
var i18n = {
share: "Share",
follow: "Follow",
unfollow: "Unfollow",
like: "Like",
unlike: "Unlike",
not_logged_in: "You need to login to tibbr.",
login: " Click <a href='#' class='tib-login-link'>here</a> to login."
};
var that = this;
/* define TIB object */
// var TIB = global[objName] = function () {
// };
TIBR.topics = tibTopics;
TIBR.tibURLs = tibURLs;
TIBR.pagebusClients = {};
TIBR.host = "";
TIBR.currentUser = null;
TIBR.loggedIn = false;
TIBR.logger = global.console;
TIBR.events = (function () {
var eventQueue = {};
return {
on: function (name, callback) {
eventQueue[name] = eventQueue[name] || [];
eventQueue[name].push(callback);
},
trigger: function () {
var name = arguments[0];
var args = [].slice.call(arguments, 1);
var cq = eventQueue[name] || [];
for (var i in cq) {
if (typeof(cq[i]) === "function") {
cq[i](args);
}
}
},
off: function (name) {
eventQueue[name] = [];
},
debug: function () {
console.warn(eventQueue);
}
}
})();
TIBR.apiResponseHandler = function (data, params) {
params.onResponse(data.r, data.rc);
TIBR.PageBus.unsubscribe(params.handlerId);
};
TIBR.api = function (args) {
args.handlerId2 = "api:response:" + Math.floor(Math.random() * 1111);
args.url = TIBR.host + "" + args.url;
/* assign client id in each api call if not provided by end user */
if (args.params && !args.params.client_id && TIBR.client_id) {
args.params.client_id = TIBR.client_id;
}
var params = {
u: args.url,
m: args.method,
t: args.type,
d: args.params,
hid: args.handlerId2
};
TIBR.PageBus.publish("api:call", params);
TIBR.PageBus.subscribe(args.handlerId2, function (data) {
args.onResponse(data.r, data.rc);
TIBR.PageBus.unsubscribe(args.handlerId2);
});
};
TIBR.login = function (callback) {
TIBR.PageBus.publish(tibTopics.loginRequest);
if (callback) {
TIBR.onLogin(callback);
}
TIBR.PageBus.subscribe(tibTopics.loginResponse, function (data) {
TIBR.api({
url: tibURLs.usersBySession,
method: "GET",
onResponse: function (data) {
if (data && data.id) {
TIBR.currentUser = data;
TIBR.loggedIn = true;
TIBR.events.trigger("login", data);
}
if (typeof callback === "function") {
callback();
}
}
})
TIBR.PageBus.unsubscribe(tibTopics.loginResponse);
});
return true;
};
TIBR.onInit = function (callback) {
TIBR.events.on("initialize", callback);
};
TIBR.initPlugin = function (type, plugin) {
TIBR.events.on("initialize", function () {
TIBR.Plugins[type](plugin); //hard dependency on plugins.js - replace with angular code
});
};
TIBR.initialized = false;
TIBR.onLogin = function (callback) {
TIBR.events.on("login", callback);
};
TIBR.initializedChannel = function (onSetup) {
/* when tibbr:proxy connected do init stuff*/
TIBR.PageBus.subscribe(tibTopics.proxyConnected, function () {
/* load translation files */
TIBR.proxyConnected = true;
if (TIBR.pluginsEnabled === true) {
TIBR.api({
url: tibURLs.connectConfig,
method: "GET",
onResponse: function (data) {
if (!data.errors) {
TIBR.translate = data.locales;
TIBR.serverConfig = data.config;
/* use default client id when client ID is not given while init*/
if (!TIBR.client_id) {
TIBR.client_id = TIBR.serverConfig.default_client_id;
}
}
}
});
}
TIBR.api({
url: tibURLs.usersBySession,
method: "GET",
onResponse: function (data) {
if (data && data.id) {
TIBR.currentUser = data;
TIBR.loggedIn = true;
TIBR.events.trigger("login", data);
}
if (typeof onSetup == "function") {
onSetup();
}
}
});
TIBR.PageBus.unsubscribe(tibTopics.proxyConnected);
});
};
TIBR.createProxyClient = function (options) {
var url = options.url || '/';
var id = options.id || 'proxyConnect';
var container = options.container || document.createElement("div");
var onConnect = options.onConnect || function () {
};
var frameOptions = options.frameOptions || {
scrolling: "no",
style: {
border: "white solid 1px",
width: "0",
height: "0",
visibility: "hidden",
display: "none"
}
};
/* remove the exiting iframe client matiching with id, avoid duplicate cliet pagebus error */
if (TIBR.pagebusClients[id]) {
TIBR.removeProxyClient(id);
}
var client = new TIBR.OpenAjax.hub.IframeContainer(TIBR.tibbrConnectManagedHub, id,
{
Container: {
onSecurityAlert: function (source, alertType) {
TIBR.parentApp = {}; //remove parentApp proxy functions
console.log(source, alertType, 'pagebus connect failure');
},
onConnect: function () {
onConnect.call();
//this assumes we removed the proxy created by TIB
if (TIB.cb) {
TIB.cb.call();
}
}
},
IframeContainer: {
parent: container,
iframeAttrs: frameOptions,
uri: url,
tunnelURI: TIBR.tunnelUrl
}
});
TIBR.pagebusClients[id] = client;
return client._iframe;
};
TIBR.removeProxyClient = function (id, callback) {
try {
TIBR.PageBus.disconnectContainer(TIBR.pagebusClients[id]);
if (typeof(callback) === "function") {
callback();
}
}
catch (e) {
}
};
TIBR.setup = function (onSetup) {
// possible scenarios
//non-tibbr managed window
//non-tibbr managed window w/ plugins
//tibbr managed window - non tibbr iframe
//window.postMessage support vs ie7
var path = TIBR.host + TIBR.scriptsBasePath;
if (TIBR.pluginsEnabled) {
if(isNotIE8){
//ie really stinks
head.js( (!global.jQuery) ? {jquery: path + tibIncludes.jquery + '.js'} : {} );
}
head.js(
{pcss: TIBR.host + tibIncludes.socialCSS},
(!global.angular) ? {angular: path + tibIncludes.angularjs + '.js'} : {},
{pbus: path + tibIncludes.pagebus + '.js'},
{tpbus: path + tibIncludes.tibbrPagebus + '.js'},
{services: path + tibIncludes.services + '.js'},
{app: path + tibIncludes.app + '.js'}
);
} else if (TIBR.parentTibbr) {
head.js(
{pbus: path + tibIncludes.pagebus + '.js'},
{tpbus: path + tibIncludes.tibbrPagebus + '.js'}
//{pconn: path + tibIncludes.parentConnector + '.js'}
);
} else {
head.js(
{pbus: path + tibIncludes.pagebus + '.js'},
{tpbus: path + tibIncludes.tibbrPagebus + '.js'}
);
}
// in all cases after js has loaded
head.ready(function () {
TIBR.PageBus.init();
var cont = document.createElement("div");
var cb = function () {
TIBR.initializedChannel(onSetup);
};
cont.id = "tib-connet-proxy";
var hostprefix = encodeURIComponent(TIBR.host);
var acc_token = TIBR.accessToken || "";
TIBR.proxyConnected = false; //will be set to true in the callback cb
var proxyConnect = TIBR.createProxyClient({
url: TIBR.host + tibIncludes.connectProxy + ".html?obref=" + 'TIBR' + "&acctkn=" + acc_token + "&hpfx=" + hostprefix,
id: "proxyConnect",
container: document.getElementsByTagName("body")[0],
onConnect: cb
});
if (typeof onTibrLoad == 'function') {
onTibrLoad();
}
//this will only initialize angular plugins already in the page
// if the elements / directives are created dynamically then call angular.bootstrap after
if (TIBR.pluginsEnabled) {
angular.element(document).ready(function () {
angular.bootstrap(document, ["TibbrPlugins"]);
});
}
});
};
var hostString = (function (location) {
var host = location.protocol + '//' + location.hostname;
if (location.port) {
host = host + ':' + location.port;
}
host = host + location.pathname;
return host;
})(global.location);
//we only want to run this function once
TIBR.init = (function () {
if (TIBR.initialized) {
return function () {
console.warn('TIBR already initialized');
};
} else {
TIBR.initialized = true;
return function (conf) {
TIBR.accessToken = conf.access_token || null;
//form now on the host config param needs to contain: protocal, hostname, path_to_tibbr_instance
//i.e. https://tibbr.mycompany.com/tibbr
TIBR.host = conf.host || hostString;
TIBR.host = TIBR.host.replace(/\/$/, '');
TIBR.tunnelUrl = conf.tunnelUrl + "?objname=" + 'TIBR';
if (conf.host.indexOf('https') != -1) {
TIBR.ssl = true
}
TIBR.client_id = conf.client_id || null;
TIBR.parentTibbr = conf.renderInTibbr || null;
if (conf.plugins) {
TIBR.pluginsEnabled = true;
}
//dgs - allows developer to initalize plugins async by just declaring a plugin property object literal
//now supports multiple of the same plugin type by including their config objects in an array
var initPlugins = function (plugins) {
for (var plugin in plugins) {
if (plugins[plugin] instanceof Array) {
var type = plugin;
for (var z = 0, y = plugins[plugin].length; z < y; z++) {
TIBR.initPlugin(type, plugins[plugin][z]);
}
} else if (typeof plugins[plugin] === 'object') {
TIBR.initPlugin(plugin, plugins[plugin]); //hard dep on plugins.js -> angular
} else {
console.warn('failed to initialize ' + plugin + 'plugin');
}
}
};
if (typeof conf.plugins === 'object') {
initPlugins(conf.plugins);
}
var onSetup = function () {
TIBR.events.trigger("initialize");
if (typeof(conf.onInitialize) === "function") {
conf.onInitialize();
}
}
TIBR.setup(onSetup);
}
}
})();
global.TIBR = TIBR;
if (global.tibr_init) {
TIBR.init(global.tibr_init);
}
})(window);
(function (global) {
var PageBus = (function (TIBR) {
return {
debug: false,
log: function () {
// if (TIB.PageBus.debug === false) return;
TIBR.logger.log("PageBus:", arguments);
},
hub: function () {
return TIBR.__hub;
},
publish: function (eventName, data) {
TIBR.__hub.publish(eventName, data);
TIBR.PageBus.log("Publish", eventName);
},
subscribe: function (eventName, callBackFunction) {
var _cb = function (topic, data, subscriberData) {
callBackFunction(data);
}
TIBR.__hub.subscribe(eventName, _cb, null, null, null); //new TIB.OpenAjax.hub.InlineHubClient
TIBR.PageBus.log("Subscribe", eventName);
},
unsubscribe: function (eventName) {
TIBR.__hub.subscribe(eventName);
},
checkDebug: function () {
if (window.location.href.indexOf("tdebug") > 0 || TIBR.PageBus.debug)
TIBR.PageBus.debug = true;
},
init: function (callBack) {
//checking if same domain in iframe
TIBR.PageBus.checkDebug();
if (window.location.href.indexOf("ifmain") < 0) { //Same domain iframe
try {
if (!TIBR.tibbrConnectManagedHub) { //Case where gadget domain and parent window domain are same but pagebus is not initialized in parent window/
var manageHub = TIBR.PageBus.setup();
TIBR.tibbrConnectManagedHub = manageHub;
} else { //Case where gadget domain and parent window domain are same and pagebus is already initialized in parent window
manageHub = TIBR.tibbrConnectManagedHub;
}
TIBR.PageBus.inLine(manageHub, callBack);
TIBR.PageBus.log("init", "Same domain ")
} catch (e) { //Parent window and gadget are not in same domain
try { //Case where parent window initialized gadget using pagebus API
TIBR.PageBus.ifFrame(callBack);
TIBR.PageBus.log("init", "Different domain ");
}
catch (e) { //Case where gadget is not initialized with pagebus even though they fall in different domains
TIBR.tibbrConnectManagedHub = TIBR.PageBus.setup();
TIBR.PageBus.inLine(TIBR.tibbrConnectManagedHub, callBack);
TIBR.PageBus.log("init", "Different domains, gadget not created with pagebus, communication would not work");
}
}
} else {
TIBR.PageBus.log("init", "Same domain but using iframe");
TIBR.PageBus.ifFrame(callBack);
}
},
setup: function () {
TIBR.OpenAjax.hub.enableDebug = TIBR.PageBus.debug;
var managedHubParams = {
onPublish: function (topic, data, pcon, scon) {
return true;
},
onSubscribe: function (topic, scon) {
return true;
},
onSecurityAlert: function (source, alertType) {
TIBR.PageBus.log("setup", source, alertType);
}
};
TIBR.PageBus.log("setup: managedHubParams");
return new TIBR.OpenAjax.hub.ManagedHub(managedHubParams);
},
disconnectContainer: function (container) {
TIBR.tibbrConnectManagedHub.removeContainer(container);
},
//should we handle security exceptions from PB?
inLine: function (tibbrConnectManagedHub, callBack) {
TIBR.PageBus.log("InLine", "called");
var inline = new TIBR.OpenAjax.hub.InlineContainer(tibbrConnectManagedHub, "inline" + Math.floor(Math.random() * 1111), {
Container: {
onSecurityAlert: function (source, alertType) {
}},
InlineContainer: {}
});
var hubClient = new TIBR.OpenAjax.hub.InlineHubClient(
{HubClient: {
onSecurityAlert: function (source, alertType) {
}
}, InlineHubClient: {
container: inline
}
});
hubClient.connect(function (hc, suc, err) {
if (suc) {
TIBR.PageBus.log("InLine hub client connection is succeeded");
TIBR.__hub = hubClient;
if (typeof(callBack) === "function") {
try {
callBack();
} catch (e) {
}
} else {
TIBR.PageBus.log("InLineHubConnectedError", err);
}
} else {
TIBR.log("Error inLine Hub Client Connection");
}
});
},
ifFrame: function (callBack) {
var hubClient = new TIBR.OpenAjax.hub.IframeHubClient({
HubClient: {
onSecurityAlert: function (src, atyp) {
TIBR.log(atyp);
}
}
});
TIBR.PageBus.log("iFrame Hub client is called");
hubClient.connect(function (hc, suc, err) {
if (suc) {
TIBR.PageBus.log("iframe hub client connection is succeeded");
TIBR.__hub = hubClient;
if (typeof(callBack) === "function") {
try {
callBack();
} catch (e) {
}
}
TIBR.PageBus.log("iframe hub client connection is succeeded: before trigger");
TIBR.PageBus.log("iframe hub client connection is succeeded: after trigger");
} else {
TIBR.log("Error iFrame Hub Client Connection");
}
});
TIBR.PageBus.log("iframe hub client is called");
}
};
})(global.TIBR || {});
if (global.TIBR) {
global.TIBR.PageBus = PageBus;
//may as well add this tidbit of parent frame comm here
(function (TIBR) {
TIBR.parentApp = {};
//publish info that the parent frame should listen for
TIBR.parentApp.setFrameHeight = function (height) {
TIBR.PageBus.publish("parent:invoke:call", {
fname: "setHeight",
args: {
height: height
}
});
};
TIBR.parentApp.sendFileIo = function (file) {
TIBR.PageBus.publish("parent:invoke:call", {
fname: "sendFile",
args: {
file: file.object,
src: file.srcViewId
}
});
};
//event handler for parent frame when a meeting is created
//client app invokes this with the meeting info (json object)
TIBR.parentApp.onMeetingAdd = function (meeting) {
TIBR.PageBus.publish("parent:invoke:call", {
fname: "onMeetingAdd",
args: {
meeting: meeting
}
});
};
//event handler for parent frame when a meeting is created
//client app invokes this with the meeting info (json object)
TIBR.parentApp.onInstantMeetingCreate = function (meeting) {
TIBR.PageBus.publish("parent:invoke:call", {
fname: "onInstantMeetingCreate",
args: {
meeting: meeting
}
});
//close iframe window
//open meeting iframe
// /oauth/authorize?client_id=12&url_type=launch&meeting_id=123
};
//ask the parent frame to run any function
//parent frame must be listening for that function
TIBR.parentApp.invokeFunction = function (func, args) {
TIBR.PageBus.publish("parent:invoke:call", {
fname: func,
args: args
})
};
})(global.TIBR);
}
})(window);
.social * {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
.social ol, .social ul {
list-style: none;
}
.social blockquote{
quotes: none;
}
.social blockquote:before, .social blockquote:after {
content: '';
content: none;
}
.social ins {
text-decoration: none;
}
.social del {
text-decoration: line-through;
}
.social table {
border-collapse: collapse;
border-spacing: 0;
}
.social .container{
width: 400px;
margin: 100px auto 0;
}
.social {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
position: relative;
width: 500px;
}
.social .table-footer {
background: none repeat scroll 0 0 #E5E5E5;
border-right: 0 none;
display: inline-block;
padding: 5px 0 5px 10px;
text-align: right;
}
.social a {
color: #777;
cursor: pointer;
font-weight: bold;
display: inline-block;
text-decoration: none;
}
.social .stats li {
border-right: 2px solid #D8D8D8;
cursor: pointer;
display: inline;
font-size: 13px;
line-height: 1;
margin: 0 10px 0 0;
padding: 0 10px 0 0;
position: relative;
}
.social .stats li:hover a{
color: #006699;
}
.social .stats li:last-child{
margin-right: 5px;
border-right: none;
}
.social .mid-dot {
margin: 0 5px;
vertical-align: middle;
}
.social .stats .count {
vertical-align: middle;
}
.social .post-section {
background: #fff;
border: 1px solid #ccc;
display: block;
/*margin: 10px 0 0 0;*/
padding: 10px;
position: absolute !important;
overflow: visible;
width: 625px;
z-index: 1000;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
/* style for tib in pop-over */
.social .post-section::before,.social .post-section::after{
border-style: solid;
border-width: 10px;
content: "";
position: absolute;
width: 0;
height: 0;
border-color: #fff;
display: block;
}
.social .post-section::before{
border-width: 11px;
border-color: #999;
}
.social .post-section.north-west::after{
border-color: transparent transparent transparent #fff;
top: 50%;
left: 100%;
margin-top: -9px;
border-right-width: 0;
}
.social .post-section.north-west::before{
border-color: transparent transparent transparent #cccccc;
top: 50%;
left: 100%;
margin-top: -10px;
border-right-width: 0;
}
.social .post-section.south-east::after{
border-color: transparent #fff transparent transparent;
top: 50%;
right: 100%;
margin-top: -9px;
border-left-width: 0;
}
.social .post-section.south-east::before{
border-color: transparent #cccccc transparent transparent;
top: 50%;
right: 100%;
margin-top: -10px;
border-left-width: 0;
}
.social .post-section.south-west::after{
border-color: transparent transparent #fff transparent;
bottom: 100%;
left: 50%;
margin-left: -9px;
border-top-width: 0;
}
.social .post-section.south-west::before{
border-color: transparent transparent #cccccc transparent;
bottom: 100%;
left: 50%;
margin-left: -10px;
border-top-width: 0;
}
.social .post-section.north-east::after{
border-color: #fff transparent transparent transparent;
border-bottom-width: 0;
top: 100%;
left: 50%;
margin-left: -9px;
}
.social .post-section.north-east::before{
border-color: #ccc transparent transparent transparent;
border-bottom-width: 0;
top: 100%;
left: 50%;
margin-left: -10px;
}
/* end of tib pop-over*/
/* positioning pop-overs */
.social .post-section.north-east{
bottom: 0;
right: 0;
margin: 0 0 20px 0;
}
.social .post-section.north-west{
bottom: 0;
left: 0;
margin: 0 0 20px 0;
}
.social .post-section.south-east{
right: 0;
top: 0;
margin: 20px 0 0 0;
}
.social .post-section.south-west{
left: 0;
top: 0;
margin: 20px 0 0 0;
}
/* end of positioning pop-overs*/
.social .post-section iframe .tib-box{
padding: 10px;
}
.social #posting-tab-wrap{
padding: 10px;
}
/*common for all icon*/
.social .ui-inline-icon {
background-repeat: no-repeat;
color: transparent;
display: inline-block;
font-size: 0;
height: 16px;
vertical-align: middle;
width: 20px;
}
/* all - icons*/
.social .like-link,
.reply-link,
.reply-like,
.reply-icon,
.share-icon{
display: inline-block;
vertical-align: middle;
}
/*like-block*/
.social .like-link{
background-position: 0 0;
height: 15px;
width: 17px;
}
.social .stats li:hover .like-link{
background-position: 0 -30px;
}
/*reply-block*/
.social .reply-link {
background-position: -30px 0;
height: 15px;
width: 17px;
}
.social .stats li:hover .reply-link{
background-position: -30px -30px;
}
/* share-block*/
.social .share-icon {
background-position: -60px 0;
height: 13px;
width: 17px;
}
.social .stats li:hover .share-icon{
background-position: -60px -30px;
}
@dgs700
Copy link
Author

dgs700 commented May 15, 2013

Tibbr developer Javascript API and plugin component code minus the less interesting tidbits. Uses Angularjs for custom, self-contained html/js/css components, head.js for a minimal async loader, and Tibco's Pagebus for x-frame communication (should be replaced with easyXDM).

3rd party developers only need include a minimal js config object and a few custom attributes in an html page to include social plugins from their Tibbr instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment