1
|
/*! jssocials - v1.5.0 - 2017-04-30
|
2
|
* http://js-socials.com
|
3
|
* Copyright (c) 2017 Artem Tabalin; Licensed MIT */
|
4
|
(function(window, $, undefined) {
|
5
|
|
6
|
var JSSOCIALS = "JSSocials",
|
7
|
JSSOCIALS_DATA_KEY = JSSOCIALS;
|
8
|
|
9
|
var getOrApply = function(value, context) {
|
10
|
if($.isFunction(value)) {
|
11
|
return value.apply(context, $.makeArray(arguments).slice(2));
|
12
|
}
|
13
|
return value;
|
14
|
};
|
15
|
|
16
|
var IMG_SRC_REGEX = /(\.(jpeg|png|gif|bmp|svg)$|^data:image\/(jpeg|png|gif|bmp|svg\+xml);base64)/i;
|
17
|
var URL_PARAMS_REGEX = /(&?[a-zA-Z0-9]+=)?\{([a-zA-Z0-9]+)\}/g;
|
18
|
|
19
|
var MEASURES = {
|
20
|
"G": 1000000000,
|
21
|
"M": 1000000,
|
22
|
"K": 1000
|
23
|
};
|
24
|
|
25
|
var shares = {};
|
26
|
|
27
|
function Socials(element, config) {
|
28
|
var $element = $(element);
|
29
|
|
30
|
$element.data(JSSOCIALS_DATA_KEY, this);
|
31
|
|
32
|
this._$element = $element;
|
33
|
|
34
|
this.shares = [];
|
35
|
|
36
|
this._init(config);
|
37
|
this._render();
|
38
|
}
|
39
|
|
40
|
Socials.prototype = {
|
41
|
url: "",
|
42
|
text: "",
|
43
|
shareIn: "blank",
|
44
|
|
45
|
showLabel: function(screenWidth) {
|
46
|
return (this.showCount === false) ?
|
47
|
(screenWidth > this.smallScreenWidth) :
|
48
|
(screenWidth >= this.largeScreenWidth);
|
49
|
},
|
50
|
|
51
|
showCount: function(screenWidth) {
|
52
|
return (screenWidth <= this.smallScreenWidth) ? "inside" : true;
|
53
|
},
|
54
|
|
55
|
smallScreenWidth: 640,
|
56
|
largeScreenWidth: 1024,
|
57
|
|
58
|
resizeTimeout: 200,
|
59
|
|
60
|
elementClass: "jssocials",
|
61
|
sharesClass: "jssocials-shares",
|
62
|
shareClass: "jssocials-share",
|
63
|
shareButtonClass: "jssocials-share-button",
|
64
|
shareLinkClass: "jssocials-share-link",
|
65
|
shareLogoClass: "jssocials-share-logo",
|
66
|
shareLabelClass: "jssocials-share-label",
|
67
|
shareLinkCountClass: "jssocials-share-link-count",
|
68
|
shareCountBoxClass: "jssocials-share-count-box",
|
69
|
shareCountClass: "jssocials-share-count",
|
70
|
shareZeroCountClass: "jssocials-share-no-count",
|
71
|
|
72
|
_init: function(config) {
|
73
|
this._initDefaults();
|
74
|
$.extend(this, config);
|
75
|
this._initShares();
|
76
|
this._attachWindowResizeCallback();
|
77
|
},
|
78
|
|
79
|
_initDefaults: function() {
|
80
|
this.url = window.location.href;
|
81
|
this.text = $.trim($("meta[name=description]").attr("content") || $("title").text());
|
82
|
},
|
83
|
|
84
|
_initShares: function() {
|
85
|
this.shares = $.map(this.shares, $.proxy(function(shareConfig) {
|
86
|
if(typeof shareConfig === "string") {
|
87
|
shareConfig = { share: shareConfig };
|
88
|
}
|
89
|
|
90
|
var share = (shareConfig.share && shares[shareConfig.share]);
|
91
|
|
92
|
if(!share && !shareConfig.renderer) {
|
93
|
throw Error("Share '" + shareConfig.share + "' is not found");
|
94
|
}
|
95
|
|
96
|
return $.extend({ url: this.url, text: this.text }, share, shareConfig);
|
97
|
}, this));
|
98
|
},
|
99
|
|
100
|
_attachWindowResizeCallback: function() {
|
101
|
$(window).on("resize", $.proxy(this._windowResizeHandler, this));
|
102
|
},
|
103
|
|
104
|
_detachWindowResizeCallback: function() {
|
105
|
$(window).off("resize", this._windowResizeHandler);
|
106
|
},
|
107
|
|
108
|
_windowResizeHandler: function() {
|
109
|
if($.isFunction(this.showLabel) || $.isFunction(this.showCount)) {
|
110
|
window.clearTimeout(this._resizeTimer);
|
111
|
this._resizeTimer = setTimeout($.proxy(this.refresh, this), this.resizeTimeout);
|
112
|
}
|
113
|
},
|
114
|
|
115
|
_render: function() {
|
116
|
this._clear();
|
117
|
|
118
|
this._defineOptionsByScreen();
|
119
|
|
120
|
this._$element.addClass(this.elementClass);
|
121
|
|
122
|
this._$shares = $("<div>").addClass(this.sharesClass)
|
123
|
.appendTo(this._$element);
|
124
|
|
125
|
this._renderShares();
|
126
|
},
|
127
|
|
128
|
_defineOptionsByScreen: function() {
|
129
|
this._screenWidth = $(window).width();
|
130
|
this._showLabel = getOrApply(this.showLabel, this, this._screenWidth);
|
131
|
this._showCount = getOrApply(this.showCount, this, this._screenWidth);
|
132
|
},
|
133
|
|
134
|
_renderShares: function() {
|
135
|
$.each(this.shares, $.proxy(function(_, share) {
|
136
|
this._renderShare(share);
|
137
|
}, this));
|
138
|
},
|
139
|
|
140
|
_renderShare: function(share) {
|
141
|
var $share;
|
142
|
|
143
|
if($.isFunction(share.renderer)) {
|
144
|
$share = $(share.renderer());
|
145
|
} else {
|
146
|
$share = this._createShare(share);
|
147
|
}
|
148
|
|
149
|
$share.addClass(this.shareClass)
|
150
|
.addClass(share.share ? "jssocials-share-" + share.share : "")
|
151
|
.addClass(share.css)
|
152
|
.appendTo(this._$shares);
|
153
|
},
|
154
|
|
155
|
_createShare: function(share) {
|
156
|
var $result = $("<div>");
|
157
|
var $shareLink = this._createShareLink(share).appendTo($result);
|
158
|
|
159
|
if(this._showCount) {
|
160
|
var isInsideCount = (this._showCount === "inside");
|
161
|
var $countContainer = isInsideCount ? $shareLink : $("<div>").addClass(this.shareCountBoxClass).appendTo($result);
|
162
|
$countContainer.addClass(isInsideCount ? this.shareLinkCountClass : this.shareCountBoxClass);
|
163
|
this._renderShareCount(share, $countContainer);
|
164
|
}
|
165
|
|
166
|
return $result;
|
167
|
},
|
168
|
|
169
|
_createShareLink: function(share) {
|
170
|
var shareStrategy = this._getShareStrategy(share);
|
171
|
|
172
|
var $result = shareStrategy.call(share, {
|
173
|
shareUrl: this._getShareUrl(share)
|
174
|
});
|
175
|
|
176
|
$result.addClass(this.shareLinkClass)
|
177
|
.append(this._createShareLogo(share));
|
178
|
|
179
|
if(this._showLabel) {
|
180
|
$result.append(this._createShareLabel(share));
|
181
|
}
|
182
|
|
183
|
$.each(this.on || {}, function(event, handler) {
|
184
|
if($.isFunction(handler)) {
|
185
|
$result.on(event, $.proxy(handler, share));
|
186
|
}
|
187
|
});
|
188
|
|
189
|
return $result;
|
190
|
},
|
191
|
|
192
|
_getShareStrategy: function(share) {
|
193
|
var result = shareStrategies[share.shareIn || this.shareIn];
|
194
|
|
195
|
if(!result)
|
196
|
throw Error("Share strategy '" + this.shareIn + "' not found");
|
197
|
|
198
|
return result;
|
199
|
},
|
200
|
|
201
|
_getShareUrl: function(share) {
|
202
|
var shareUrl = getOrApply(share.shareUrl, share);
|
203
|
return this._formatShareUrl(shareUrl, share);
|
204
|
},
|
205
|
|
206
|
_createShareLogo: function(share) {
|
207
|
var logo = share.logo;
|
208
|
|
209
|
var $result = IMG_SRC_REGEX.test(logo) ?
|
210
|
$("<img>").attr("src", share.logo) :
|
211
|
$("<i>").addClass(logo);
|
212
|
|
213
|
$result.addClass(this.shareLogoClass);
|
214
|
|
215
|
return $result;
|
216
|
},
|
217
|
|
218
|
_createShareLabel: function(share) {
|
219
|
return $("<span>").addClass(this.shareLabelClass)
|
220
|
.text(share.label);
|
221
|
},
|
222
|
|
223
|
_renderShareCount: function(share, $container) {
|
224
|
var $count = $("<span>").addClass(this.shareCountClass);
|
225
|
|
226
|
$container.addClass(this.shareZeroCountClass)
|
227
|
.append($count);
|
228
|
|
229
|
this._loadCount(share).done($.proxy(function(count) {
|
230
|
if(count) {
|
231
|
$container.removeClass(this.shareZeroCountClass);
|
232
|
$count.text(count);
|
233
|
}
|
234
|
}, this));
|
235
|
},
|
236
|
|
237
|
_loadCount: function(share) {
|
238
|
var deferred = $.Deferred();
|
239
|
var countUrl = this._getCountUrl(share);
|
240
|
|
241
|
if(!countUrl) {
|
242
|
return deferred.resolve(0).promise();
|
243
|
}
|
244
|
|
245
|
var handleSuccess = $.proxy(function(response) {
|
246
|
deferred.resolve(this._getCountValue(response, share));
|
247
|
}, this);
|
248
|
|
249
|
$.getJSON(countUrl).done(handleSuccess)
|
250
|
.fail(function() {
|
251
|
$.get(countUrl).done(handleSuccess)
|
252
|
.fail(function() {
|
253
|
deferred.resolve(0);
|
254
|
});
|
255
|
});
|
256
|
|
257
|
return deferred.promise();
|
258
|
},
|
259
|
|
260
|
_getCountUrl: function(share) {
|
261
|
var countUrl = getOrApply(share.countUrl, share);
|
262
|
return this._formatShareUrl(countUrl, share);
|
263
|
},
|
264
|
|
265
|
_getCountValue: function(response, share) {
|
266
|
var count = ($.isFunction(share.getCount) ? share.getCount(response) : response) || 0;
|
267
|
return (typeof count === "string") ? count : this._formatNumber(count);
|
268
|
},
|
269
|
|
270
|
_formatNumber: function(number) {
|
271
|
$.each(MEASURES, function(letter, value) {
|
272
|
if(number >= value) {
|
273
|
number = parseFloat((number / value).toFixed(2)) + letter;
|
274
|
return false;
|
275
|
}
|
276
|
});
|
277
|
|
278
|
return number;
|
279
|
},
|
280
|
|
281
|
_formatShareUrl: function(url, share) {
|
282
|
return url.replace(URL_PARAMS_REGEX, function(match, key, field) {
|
283
|
var value = share[field] || "";
|
284
|
return value ? (key || "") + window.encodeURIComponent(value) : "";
|
285
|
});
|
286
|
},
|
287
|
|
288
|
_clear: function() {
|
289
|
window.clearTimeout(this._resizeTimer);
|
290
|
this._$element.empty();
|
291
|
},
|
292
|
|
293
|
_passOptionToShares: function(key, value) {
|
294
|
var shares = this.shares;
|
295
|
|
296
|
$.each(["url", "text"], function(_, optionName) {
|
297
|
if(optionName !== key)
|
298
|
return;
|
299
|
|
300
|
$.each(shares, function(_, share) {
|
301
|
share[key] = value;
|
302
|
});
|
303
|
});
|
304
|
},
|
305
|
|
306
|
_normalizeShare: function(share) {
|
307
|
if($.isNumeric(share)) {
|
308
|
return this.shares[share];
|
309
|
}
|
310
|
|
311
|
if(typeof share === "string") {
|
312
|
return $.grep(this.shares, function(s) {
|
313
|
return s.share === share;
|
314
|
})[0];
|
315
|
}
|
316
|
|
317
|
return share;
|
318
|
},
|
319
|
|
320
|
refresh: function() {
|
321
|
this._render();
|
322
|
},
|
323
|
|
324
|
destroy: function() {
|
325
|
this._clear();
|
326
|
this._detachWindowResizeCallback();
|
327
|
|
328
|
this._$element
|
329
|
.removeClass(this.elementClass)
|
330
|
.removeData(JSSOCIALS_DATA_KEY);
|
331
|
},
|
332
|
|
333
|
option: function(key, value) {
|
334
|
if(arguments.length === 1) {
|
335
|
return this[key];
|
336
|
}
|
337
|
|
338
|
this[key] = value;
|
339
|
|
340
|
this._passOptionToShares(key, value);
|
341
|
|
342
|
this.refresh();
|
343
|
},
|
344
|
|
345
|
shareOption: function(share, key, value) {
|
346
|
share = this._normalizeShare(share);
|
347
|
|
348
|
if(arguments.length === 2) {
|
349
|
return share[key];
|
350
|
}
|
351
|
|
352
|
share[key] = value;
|
353
|
this.refresh();
|
354
|
}
|
355
|
};
|
356
|
|
357
|
|
358
|
$.fn.jsSocials = function(config) {
|
359
|
var args = $.makeArray(arguments),
|
360
|
methodArgs = args.slice(1),
|
361
|
result = this;
|
362
|
|
363
|
this.each(function() {
|
364
|
var $element = $(this),
|
365
|
instance = $element.data(JSSOCIALS_DATA_KEY),
|
366
|
methodResult;
|
367
|
|
368
|
if(instance) {
|
369
|
if(typeof config === "string") {
|
370
|
methodResult = instance[config].apply(instance, methodArgs);
|
371
|
if(methodResult !== undefined && methodResult !== instance) {
|
372
|
result = methodResult;
|
373
|
return false;
|
374
|
}
|
375
|
} else {
|
376
|
instance._detachWindowResizeCallback();
|
377
|
instance._init(config);
|
378
|
instance._render();
|
379
|
}
|
380
|
} else {
|
381
|
new Socials($element, config);
|
382
|
}
|
383
|
});
|
384
|
|
385
|
return result;
|
386
|
};
|
387
|
|
388
|
var setDefaults = function(config) {
|
389
|
var component;
|
390
|
|
391
|
if($.isPlainObject(config)) {
|
392
|
component = Socials.prototype;
|
393
|
} else {
|
394
|
component = shares[config];
|
395
|
config = arguments[1] || {};
|
396
|
}
|
397
|
|
398
|
$.extend(component, config);
|
399
|
};
|
400
|
|
401
|
var shareStrategies = {
|
402
|
popup: function(args) {
|
403
|
return $("<a>").attr("href", "#")
|
404
|
.on("click", function() {
|
405
|
window.open(args.shareUrl, null, "width=600, height=400, location=0, menubar=0, resizeable=0, scrollbars=0, status=0, titlebar=0, toolbar=0");
|
406
|
return false;
|
407
|
});
|
408
|
},
|
409
|
|
410
|
blank: function(args) {
|
411
|
return $("<a>").attr({ target: "_blank", href: args.shareUrl });
|
412
|
},
|
413
|
|
414
|
self: function(args) {
|
415
|
return $("<a>").attr({ target: "_self", href: args.shareUrl });
|
416
|
}
|
417
|
};
|
418
|
|
419
|
window.jsSocials = {
|
420
|
Socials: Socials,
|
421
|
shares: shares,
|
422
|
shareStrategies: shareStrategies,
|
423
|
setDefaults: setDefaults
|
424
|
};
|
425
|
|
426
|
}(window, jQuery));
|
427
|
|
428
|
|
429
|
(function(window, $, jsSocials, undefined) {
|
430
|
|
431
|
$.extend(jsSocials.shares, {
|
432
|
|
433
|
email: {
|
434
|
label: "E-mail",
|
435
|
logo: "fa fa-at",
|
436
|
shareUrl: "mailto:{to}?subject={text}&body={url}",
|
437
|
countUrl: "",
|
438
|
shareIn: "self"
|
439
|
},
|
440
|
|
441
|
twitter: {
|
442
|
label: "Tweet",
|
443
|
logo: "fa fa-twitter",
|
444
|
shareUrl: "https://twitter.com/share?url={url}&text={text}&via={via}&hashtags={hashtags}",
|
445
|
countUrl: ""
|
446
|
},
|
447
|
|
448
|
facebook: {
|
449
|
label: "Like",
|
450
|
logo: "fa fa-facebook",
|
451
|
shareUrl: "https://facebook.com/sharer/sharer.php?u={url}",
|
452
|
countUrl: "https://graph.facebook.com/?id={url}",
|
453
|
getCount: function(data) {
|
454
|
return data.share && data.share.share_count || 0;
|
455
|
}
|
456
|
},
|
457
|
|
458
|
vkontakte: {
|
459
|
label: "Like",
|
460
|
logo: "fa fa-vk",
|
461
|
shareUrl: "https://vk.com/share.php?url={url}&title={title}&description={text}",
|
462
|
countUrl: "https://vk.com/share.php?act=count&index=1&url={url}",
|
463
|
getCount: function(data) {
|
464
|
return parseInt(data.slice(15, -2).split(', ')[1]);
|
465
|
}
|
466
|
},
|
467
|
|
468
|
googleplus: {
|
469
|
label: "+1",
|
470
|
logo: "fa fa-google",
|
471
|
shareUrl: "https://plus.google.com/share?url={url}",
|
472
|
countUrl: ""
|
473
|
},
|
474
|
|
475
|
linkedin: {
|
476
|
label: "Share",
|
477
|
logo: "fa fa-linkedin",
|
478
|
shareUrl: "https://www.linkedin.com/shareArticle?mini=true&url={url}",
|
479
|
countUrl: "https://www.linkedin.com/countserv/count/share?format=jsonp&url={url}&callback=?",
|
480
|
getCount: function(data) {
|
481
|
return data.count;
|
482
|
}
|
483
|
},
|
484
|
|
485
|
pinterest: {
|
486
|
label: "Pin it",
|
487
|
logo: "fa fa-pinterest",
|
488
|
shareUrl: "https://pinterest.com/pin/create/bookmarklet/?media={media}&url={url}&description={text}",
|
489
|
countUrl: "https://api.pinterest.com/v1/urls/count.json?&url={url}&callback=?",
|
490
|
getCount: function(data) {
|
491
|
return data.count;
|
492
|
}
|
493
|
},
|
494
|
|
495
|
stumbleupon: {
|
496
|
label: "Share",
|
497
|
logo: "fa fa-stumbleupon",
|
498
|
shareUrl: "http://www.stumbleupon.com/submit?url={url}&title={title}",
|
499
|
countUrl: "https://cors-anywhere.herokuapp.com/https://www.stumbleupon.com/services/1.01/badge.getinfo?url={url}",
|
500
|
getCount: function(data) {
|
501
|
return data.result && data.result.views;
|
502
|
}
|
503
|
},
|
504
|
|
505
|
telegram: {
|
506
|
label: "Telegram",
|
507
|
logo: "fa fa-telegram",
|
508
|
shareUrl: "tg://msg?text={url} {text}",
|
509
|
countUrl: "",
|
510
|
shareIn: "self"
|
511
|
},
|
512
|
|
513
|
whatsapp: {
|
514
|
label: "WhatsApp",
|
515
|
logo: "fa fa-whatsapp",
|
516
|
shareUrl: "whatsapp://send?text={url} {text}",
|
517
|
countUrl: "",
|
518
|
shareIn: "self"
|
519
|
},
|
520
|
|
521
|
line: {
|
522
|
label: "LINE",
|
523
|
logo: "fa fa-comment",
|
524
|
shareUrl: "http://line.me/R/msg/text/?{text} {url}",
|
525
|
countUrl: ""
|
526
|
},
|
527
|
|
528
|
viber: {
|
529
|
label: "Viber",
|
530
|
logo: "fa fa-volume-control-phone",
|
531
|
shareUrl: "viber://forward?text={url} {text}",
|
532
|
countUrl: "",
|
533
|
shareIn: "self"
|
534
|
},
|
535
|
|
536
|
pocket: {
|
537
|
label: "Pocket",
|
538
|
logo: "fa fa-get-pocket",
|
539
|
shareUrl: "https://getpocket.com/save?url={url}&title={title}",
|
540
|
countUrl: ""
|
541
|
},
|
542
|
|
543
|
messenger: {
|
544
|
label: "Share",
|
545
|
logo: "fa fa-commenting",
|
546
|
shareUrl: "fb-messenger://share?link={url}",
|
547
|
countUrl: "",
|
548
|
shareIn: "self"
|
549
|
},
|
550
|
rss: {
|
551
|
label: "RSS",
|
552
|
logo: "fa fa-rss",
|
553
|
shareUrl: "/feeds/",
|
554
|
countUrl: "",
|
555
|
shareIn: "blank"
|
556
|
}
|
557
|
|
558
|
});
|
559
|
|
560
|
}(window, jQuery, window.jsSocials));
|
561
|
|