| 8 |
lars |
1 |
'use strict';
|
|
|
2 |
|
|
|
3 |
var $ = require('jquery');
|
|
|
4 |
var url = require('url');
|
|
|
5 |
|
|
|
6 |
var Shariff = function(element, options) {
|
|
|
7 |
var self = this;
|
|
|
8 |
|
|
|
9 |
// the DOM element that will contain the buttons
|
|
|
10 |
this.element = element;
|
|
|
11 |
|
|
|
12 |
// Ensure elemnt is empty
|
|
|
13 |
$(element).empty();
|
|
|
14 |
|
|
|
15 |
this.options = $.extend({}, this.defaults, options, $(element).data());
|
|
|
16 |
|
|
|
17 |
// available services. /!\ Browserify can't require dynamically by now.
|
|
|
18 |
var availableServices = [
|
|
|
19 |
require('./services/addthis'),
|
|
|
20 |
require('./services/diaspora'),
|
|
|
21 |
require('./services/facebook'),
|
|
|
22 |
require('./services/flattr'),
|
|
|
23 |
require('./services/googleplus'),
|
|
|
24 |
require('./services/info'),
|
|
|
25 |
require('./services/linkedin'),
|
|
|
26 |
require('./services/mail'),
|
|
|
27 |
require('./services/pinterest'),
|
|
|
28 |
require('./services/reddit'),
|
|
|
29 |
require('./services/stumbleupon'),
|
|
|
30 |
require('./services/twitter'),
|
|
|
31 |
require('./services/whatsapp'),
|
|
|
32 |
require('./services/xing'),
|
|
|
33 |
require('./services/tumblr'),
|
|
|
34 |
require('./services/threema')
|
|
|
35 |
];
|
|
|
36 |
|
|
|
37 |
// filter available services to those that are enabled and initialize them
|
|
|
38 |
this.services = $.map(this.options.services, function(serviceName) {
|
|
|
39 |
var service;
|
|
|
40 |
availableServices.forEach(function(availableService) {
|
|
|
41 |
availableService = availableService(self);
|
|
|
42 |
if (availableService.name === serviceName) {
|
|
|
43 |
service = availableService;
|
|
|
44 |
return null;
|
|
|
45 |
}
|
|
|
46 |
});
|
|
|
47 |
return service;
|
|
|
48 |
});
|
|
|
49 |
|
|
|
50 |
this._addButtonList();
|
|
|
51 |
|
|
|
52 |
if (this.options.backendUrl !== null) {
|
|
|
53 |
this.getShares().then( $.proxy( this._updateCounts, this ) );
|
|
|
54 |
}
|
|
|
55 |
|
|
|
56 |
};
|
|
|
57 |
|
|
|
58 |
Shariff.prototype = {
|
|
|
59 |
|
|
|
60 |
// Defaults may be over either by passing "options" to constructor method
|
|
|
61 |
// or by setting data attributes.
|
|
|
62 |
defaults: {
|
|
|
63 |
theme : 'color',
|
|
|
64 |
|
|
|
65 |
// URL to backend that requests social counts. null means "disabled"
|
|
|
66 |
backendUrl : null,
|
|
|
67 |
|
|
|
68 |
// Link to the "about" page
|
|
|
69 |
infoUrl: 'http://ct.de/-2467514',
|
|
|
70 |
|
|
|
71 |
// localisation: "de" or "en"
|
|
|
72 |
lang: 'de',
|
|
|
73 |
|
|
|
74 |
// fallback language for not fully localized services
|
|
|
75 |
langFallback: 'en',
|
|
|
76 |
|
|
|
77 |
mailUrl: function() {
|
|
|
78 |
var shareUrl = url.parse(this.getURL(), true);
|
|
|
79 |
shareUrl.query.view = 'mail';
|
|
|
80 |
delete shareUrl.search;
|
|
|
81 |
return url.format(shareUrl);
|
|
|
82 |
},
|
|
|
83 |
|
|
|
84 |
// if
|
|
|
85 |
mailSubject: function() {
|
|
|
86 |
return this.getMeta('DC.title') || this.getTitle();
|
|
|
87 |
},
|
|
|
88 |
|
|
|
89 |
mailBody: function() { return '<' + this.getURL() + '>'; },
|
|
|
90 |
|
|
|
91 |
// Media (e.g. image) URL to be shared
|
|
|
92 |
mediaUrl: null,
|
|
|
93 |
|
|
|
94 |
|
|
|
95 |
// horizontal/vertical
|
|
|
96 |
orientation: 'horizontal',
|
|
|
97 |
|
|
|
98 |
// a string to suffix current URL
|
|
|
99 |
referrerTrack: null,
|
|
|
100 |
|
|
|
101 |
// services to be enabled in the following order
|
|
|
102 |
services : ['twitter', 'facebook', 'googleplus', 'info'],
|
|
|
103 |
|
|
|
104 |
title: function() {
|
|
|
105 |
return $('head title').text();
|
|
|
106 |
},
|
|
|
107 |
|
|
|
108 |
twitterVia: null,
|
|
|
109 |
|
|
|
110 |
flattrUser: null,
|
|
|
111 |
|
|
|
112 |
flattrCategory: null,
|
|
|
113 |
|
|
|
114 |
// build URI from rel="canonical" or document.location
|
|
|
115 |
url: function() {
|
|
|
116 |
var url = global.document.location.href;
|
|
|
117 |
var canonical = $('link[rel=canonical]').attr('href') || this.getMeta('og:url') || '';
|
|
|
118 |
|
|
|
119 |
if (canonical.length > 0) {
|
|
|
120 |
if (canonical.indexOf('http') < 0) {
|
|
|
121 |
canonical = global.document.location.protocol + '//' + global.document.location.host + canonical;
|
|
|
122 |
}
|
|
|
123 |
url = canonical;
|
|
|
124 |
}
|
|
|
125 |
|
|
|
126 |
return url;
|
|
|
127 |
}
|
|
|
128 |
},
|
|
|
129 |
|
|
|
130 |
$socialshareElement: function() {
|
|
|
131 |
return $(this.element);
|
|
|
132 |
},
|
|
|
133 |
|
|
|
134 |
getLocalized: function(data, key) {
|
|
|
135 |
if (typeof data[key] === 'object') {
|
|
|
136 |
if (typeof data[key][this.options.lang] === 'undefined') {
|
|
|
137 |
return data[key][this.options.langFallback];
|
|
|
138 |
} else {
|
|
|
139 |
return data[key][this.options.lang];
|
|
|
140 |
}
|
|
|
141 |
} else if (typeof data[key] === 'string') {
|
|
|
142 |
return data[key];
|
|
|
143 |
}
|
|
|
144 |
return undefined;
|
|
|
145 |
},
|
|
|
146 |
|
|
|
147 |
// returns content of <meta name="" content=""> tags or '' if empty/non existant
|
|
|
148 |
getMeta: function(name) {
|
|
|
149 |
var metaContent = $('meta[name="' + name + '"],[property="' + name + '"]').attr('content');
|
|
|
150 |
return metaContent || '';
|
|
|
151 |
},
|
|
|
152 |
|
|
|
153 |
getInfoUrl: function() {
|
|
|
154 |
return this.options.infoUrl;
|
|
|
155 |
},
|
|
|
156 |
|
|
|
157 |
getURL: function() {
|
|
|
158 |
return this.getOption('url');
|
|
|
159 |
},
|
|
|
160 |
|
|
|
161 |
getOption: function(name) {
|
|
|
162 |
var option = this.options[name];
|
|
|
163 |
return (typeof option === 'function') ? $.proxy(option, this)() : option;
|
|
|
164 |
},
|
|
|
165 |
|
|
|
166 |
getTitle: function() {
|
|
|
167 |
return this.getOption('title');
|
|
|
168 |
},
|
|
|
169 |
|
|
|
170 |
getReferrerTrack: function() {
|
|
|
171 |
return this.options.referrerTrack || '';
|
|
|
172 |
},
|
|
|
173 |
|
|
|
174 |
// returns shareCounts of document
|
|
|
175 |
getShares: function() {
|
|
|
176 |
var baseUrl = url.parse(this.options.backendUrl, true);
|
|
|
177 |
baseUrl.query.url = this.getURL();
|
|
|
178 |
delete baseUrl.search;
|
|
|
179 |
return $.getJSON(url.format(baseUrl));
|
|
|
180 |
},
|
|
|
181 |
|
|
|
182 |
// add value of shares for each service
|
|
|
183 |
_updateCounts: function(data) {
|
|
|
184 |
var self = this;
|
|
|
185 |
$.each(data, function(key, value) {
|
|
|
186 |
if(value >= 1000) {
|
|
|
187 |
value = Math.round(value / 1000) + 'k';
|
|
|
188 |
}
|
|
|
189 |
$(self.element).find('.' + key + ' a').append('<span class="share_count">' + value);
|
|
|
190 |
});
|
|
|
191 |
},
|
|
|
192 |
|
|
|
193 |
// add html for button-container
|
|
|
194 |
_addButtonList: function() {
|
|
|
195 |
var self = this;
|
|
|
196 |
|
|
|
197 |
var $socialshareElement = this.$socialshareElement();
|
|
|
198 |
|
|
|
199 |
var themeClass = 'theme-' + this.options.theme;
|
|
|
200 |
var orientationClass = 'orientation-' + this.options.orientation;
|
|
|
201 |
var serviceCountClass = 'col-' + this.options.services.length;
|
|
|
202 |
|
|
|
203 |
var $buttonList = $('<ul>').addClass(themeClass).addClass(orientationClass).addClass(serviceCountClass);
|
|
|
204 |
|
|
|
205 |
// add html for service-links
|
|
|
206 |
this.services.forEach(function(service) {
|
|
|
207 |
var $li = $('<li class="shariff-button">').addClass(service.name);
|
|
|
208 |
var $shareText = '<span class="share_text">' + self.getLocalized(service, 'shareText');
|
|
|
209 |
|
|
|
210 |
var $shareLink = $('<a>')
|
|
|
211 |
.attr('href', service.shareUrl)
|
|
|
212 |
.append($shareText);
|
|
|
213 |
|
|
|
214 |
if (typeof service.faName !== 'undefined') {
|
|
|
215 |
$shareLink.prepend('<span class="fa ' + service.faName + '">');
|
|
|
216 |
}
|
|
|
217 |
|
|
|
218 |
if (service.popup) {
|
|
|
219 |
$shareLink.attr('data-rel', 'popup');
|
|
|
220 |
} else if (service.blank) {
|
|
|
221 |
$shareLink.attr('target', '_blank');
|
|
|
222 |
}
|
|
|
223 |
$shareLink.attr('title', self.getLocalized(service, 'title'));
|
|
|
224 |
|
|
|
225 |
// add attributes for screen readers
|
|
|
226 |
$shareLink.attr('role', 'button');
|
|
|
227 |
$shareLink.attr('aria-label', self.getLocalized(service, 'title'));
|
|
|
228 |
|
|
|
229 |
$li.append($shareLink);
|
|
|
230 |
|
|
|
231 |
$buttonList.append($li);
|
|
|
232 |
});
|
|
|
233 |
|
|
|
234 |
// event delegation
|
|
|
235 |
$buttonList.on('click', '[data-rel="popup"]', function(e) {
|
|
|
236 |
e.preventDefault();
|
|
|
237 |
|
|
|
238 |
var url = $(this).attr('href');
|
|
|
239 |
var windowName = '_blank';
|
|
|
240 |
var windowSizeX = '600';
|
|
|
241 |
var windowSizeY = '460';
|
|
|
242 |
var windowSize = 'width=' + windowSizeX + ',height=' + windowSizeY;
|
|
|
243 |
|
|
|
244 |
global.window.open(url, windowName, windowSize);
|
|
|
245 |
|
|
|
246 |
});
|
|
|
247 |
|
|
|
248 |
$socialshareElement.append($buttonList);
|
|
|
249 |
}
|
|
|
250 |
};
|
|
|
251 |
|
|
|
252 |
module.exports = Shariff;
|
|
|
253 |
|
|
|
254 |
// export Shariff class to global (for non-Node users)
|
|
|
255 |
global.Shariff = Shariff;
|
|
|
256 |
|
|
|
257 |
// initialize .shariff elements
|
|
|
258 |
$('.shariff').each(function() {
|
|
|
259 |
if (!this.hasOwnProperty('shariff')) {
|
|
|
260 |
this.shariff = new Shariff(this);
|
|
|
261 |
}
|
|
|
262 |
});
|