1/*! 2 * Social Share Kit v1.0.14 (http://socialsharekit.com) 3 * Copyright 2015 Social Share Kit / Kaspars Sprogis. 4 * @Licensed under Creative Commons Attribution-NonCommercial 3.0 license: 5 * https://github.com/darklow/social-share-kit/blob/master/LICENSE 6 * --- 7 */ 8var SocialShareKit = (function () { 9 var supportsShare = /(twitter|facebook|google-plus|pinterest|tumblr|vk|linkedin|whatsapp|buffer|email)/, 10 sep = '*|*', wrap, _wrap; 11 12 // Wrapper to support multiple instances per page by selector 13 _wrap = function (opts) { 14 var options = opts || {}, 15 selector = options.selector || '.ssk'; 16 this.nodes = $(selector); 17 this.options = options; 18 }; 19 20 // Instance related functions 21 _wrap.prototype = { 22 share: function () { 23 var els = this.nodes, 24 options = this.options, 25 urlsToCount = {}; 26 27 var _init = function () { 28 if (!els.length) 29 return; 30 31 each(els, function (el) { 32 var network = elSupportsShare(el), uniqueKey; 33 if (!network) { 34 return; 35 } 36 37 if (el.getAttribute('data-ssk-ready')) 38 return; 39 40 el.setAttribute('data-ssk-ready', true); 41 addEventListener(el, 'click', onClick); 42 43 // Gather icons with share counts 44 if (el.parentNode.className.indexOf('ssk-count') !== -1) { 45 network = network[0]; 46 uniqueKey = network + sep + getShareUrl(options, network, el); 47 if (!(uniqueKey in urlsToCount)) { 48 urlsToCount[uniqueKey] = []; 49 } 50 urlsToCount[uniqueKey].push(el); 51 } 52 }); 53 54 processShareCount(); 55 }; 56 57 if (options.forceInit === true) 58 _init(); 59 else 60 ready(_init); 61 62 63 function onClick(e) { 64 var target = preventDefault(e), 65 match = elSupportsShare(target), 66 network = match[0], 67 url; 68 69 if (!match) 70 return; 71 72 url = getUrl(options, network, target); 73 if (!url) 74 return; 75 76 // To use Twitter intent events, replace URL and use Twitter native share JS 77 if (window.twttr && target.getAttribute('href').indexOf('twitter.com/intent/') !== -1) { 78 target.setAttribute('href', url); 79 return; 80 } 81 82 if (network !== 'email') { 83 var width, height; 84 if (network === 'buffer') { 85 width = 800; 86 height = 680; 87 } else { 88 width = 575; 89 height = 400; 90 } 91 var win = winOpen(url, width, height); 92 93 if (options.onOpen) { 94 options.onOpen(target, network, url, win); 95 } 96 97 if (options.onClose) { 98 var closeInt = window.setInterval(function () { 99 if (win.closed !== false) { 100 window.clearInterval(closeInt); 101 options.onClose(target, network, url, win); 102 } 103 }, 250); 104 } 105 106 } else { 107 document.location = url; 108 } 109 } 110 111 function processShareCount() { 112 var a, ref; 113 for (a in urlsToCount) { 114 ref = a.split(sep); 115 (function (els) { 116 getCount(ref[0], ref[1], options, function (cnt) { 117 for (var c in els) 118 addCount(els[c], cnt); 119 }); 120 })(urlsToCount[a]); 121 } 122 } 123 124 return this.nodes; 125 } 126 }; 127 128 wrap = function (selector) { 129 return new _wrap(selector); 130 }; 131 132 function init(opts) { 133 return wrap(opts).share(); 134 } 135 136 function ready(fn) { 137 if (document.readyState != 'loading') { 138 fn(); 139 } else if (document.addEventListener) { 140 document.addEventListener('DOMContentLoaded', fn); 141 } else { 142 document.attachEvent('onreadystatechange', function () { 143 if (document.readyState != 'loading') 144 fn(); 145 }); 146 } 147 } 148 149 function $(selector) { 150 return document.querySelectorAll(selector); 151 } 152 153 function each(elements, fn) { 154 for (var i = 0; i < elements.length; i++) 155 fn(elements[i], i); 156 } 157 158 function addEventListener(el, eventName, handler) { 159 if (el.addEventListener) { 160 el.addEventListener(eventName, handler); 161 } else { 162 el.attachEvent('on' + eventName, function () { 163 handler.call(el); 164 }); 165 } 166 } 167 168 function elSupportsShare(el) { 169 return el.className.match(supportsShare); 170 } 171 172 173 function preventDefault(e) { 174 var evt = e || window.event; // IE8 compatibility 175 if (evt.preventDefault) { 176 evt.preventDefault(); 177 } else { 178 evt.returnValue = false;
179 evt.cancelBubble = true; 180 } 181 return evt.currentTarget || evt.srcElement; 182 } 183 184 function winOpen(url, width, height) { 185 var win, left, top, opts; 186 if (width && height) { 187 left = (document.documentElement.clientWidth / 2 - width / 2); 188 top = (document.documentElement.clientHeight - height) / 2; 189 opts = 'status=1,resizable=yes' + 190 ',width=' + width + ',height=' + height + 191 ',top=' + top + ',left=' + left; 192 win = window.open(url, '', opts); 193 } else { 194 win = window.open(url); 195 } 196 win.focus(); 197 return win; 198 } 199 200 function getUrl(options, network, el) { 201 var url, dataOpts = getDataOpts(options, network, el), 202 shareUrl = getShareUrl(options, network, el, dataOpts), 203 title = typeof dataOpts['title'] !== 'undefined' ? dataOpts['title'] : getTitle(network), 204 text = typeof dataOpts['text'] !== 'undefined' ? dataOpts['text'] : getText(network), 205 image = dataOpts['image'] ? dataOpts['image'] : getMetaContent('og:image'), 206 via = typeof dataOpts['via'] !== 'undefined' ? dataOpts['via'] : getMetaContent('twitter:site'), 207 paramsObj = { 208 shareUrl: shareUrl, 209 title: title, 210 text: text, 211 image: image, 212 via: via, 213 options: options, 214 shareUrlEncoded: function () { 215 return encodeURIComponent(this.shareUrl); 216 } 217 }; 218 switch (network) { 219 case 'whatsapp': 220 url = 'https://api.whatsapp.com/send?text=' + encodeURIComponent(title + '\n' + shareUrl + '\n\n' + text + '\n'); 221 break; 222 case 'facebook': 223 url = 'https://www.facebook.com/share.php?u=' + paramsObj.shareUrlEncoded(); 224 break; 225 case 'twitter': 226 url = 'https://twitter.com/intent/tweet?url=' + paramsObj.shareUrlEncoded() + 227 '&text=' + encodeURIComponent(title + (text && title ? ' - ' : '') + text); 228 if (via) 229 url += '&via=' + via.replace('@', ''); 230 break; 231 case 'google-plus': 232 url = 'https://plus.google.com/share?url=' + paramsObj.shareUrlEncoded(); 233 break; 234 case 'pinterest': 235 url = 'https://pinterest.com/pin/create/button/?url=' + paramsObj.shareUrlEncoded() + 236 '&description=' + encodeURIComponent(text); 237 if (image) 238 url += '&media=' + encodeURIComponent(image); 239 break; 240 case 'tumblr': 241 url = 'https://www.tumblr.com/share/link?url=' + paramsObj.shareUrlEncoded() + 242 '&name=' + encodeURIComponent(title) + 243 '&description=' + encodeURIComponent(text); 244 break; 245 case 'linkedin': 246 url = 'https://www.linkedin.com/shareArticle?mini=true&url=' + paramsObj.shareUrlEncoded() + 247 '&title=' + encodeURIComponent(title) + 248 '&summary=' + encodeURIComponent(text); 249 break; 250 case 'vk': 251 url = 'https://vkontakte.ru/share.php?url=' + paramsObj.shareUrlEncoded(); 252 break; 253 case 'buffer': 254 url = 'https://buffer.com/add?source=button&url=' + paramsObj.shareUrlEncoded() + 255 '&text=' + encodeURIComponent(text); 256 break; 257 case 'email': 258 url = 'mailto:?subject=' + encodeURIComponent(title) + 259 '&body=' + encodeURIComponent(title + '\n' + shareUrl + '\n\n' + text + '\n'); 260 break; 261 } 262 263 paramsObj.networkUrl = url; 264 265 if (options.onBeforeOpen) { 266 options.onBeforeOpen(el, network, paramsObj) 267 } 268 269 return paramsObj.networkUrl; 270 } 271 272 function getShareUrl(options, network, el, dataOpts) { 273 dataOpts = dataOpts || getDataOpts(options, network, el); 274 return dataOpts['url'] || window.location.href; 275 } 276 277 function getTitle(network) { 278 var title; 279 if (network == 'twitter') 280 title = getMetaContent('twitter:title'); 281 return title || document.title; 282 } 283 284 function getText(network) { 285 var text; 286 if (network == 'twitter') 287 text = getMetaContent('twitter:description'); 288 return text || getMetaContent('description'); 289 } 290 291 function getMetaContent(tagName, attr) { 292 var text, 293 tag = $('meta[' + (attr ? attr : tagName.indexOf('og:') === 0 ? 'property' : 'name') + '="' + tagName + '"]'); 294 if (tag.length) { 295 text = tag[0].getAttribute('content') || ''; 296 } 297 return text || '' 298 } 299 300 function getDataOpts(options, network, el) {
301 var validOpts = ['url', 'title', 'text', 'image'], 302 opts = {}, optValue, optKey, dataKey, a, parent = el.parentNode; 303 network == 'twitter' && validOpts.push('via'); 304 for (a in validOpts) { 305 optKey = validOpts[a]; 306 dataKey = 'data-' + optKey; 307 optValue = el.getAttribute(dataKey) || parent.getAttribute(dataKey) || 308 (options[network] && typeof options[network][optKey] != 'undefined' ? options[network][optKey] : options[optKey]); 309 if (typeof optValue != 'undefined') { 310 opts[optKey] = optValue; 311 } 312 } 313 return opts; 314 } 315 316 317 function addCount(el, cnt) { 318 var newEl = document.createElement('div'); 319 newEl.innerHTML = cnt; 320 newEl.className = 'ssk-num'; 321 el.appendChild(newEl); 322 } 323 324 function getCount(network, shareUrl, options, onReady) { 325 var url, parseFunc, body, 326 shareUrlEnc = encodeURIComponent(shareUrl); 327 switch (network) { 328 case 'facebook': 329 url = 'https://graph.facebook.com/?id=' + shareUrlEnc; 330 parseFunc = function (r) { 331 return onReady(r.share ? r.share.share_count : 0); 332 }; 333 break; 334 case 'twitter': 335 if (options && options.twitter && options.twitter.countCallback) { 336 options.twitter.countCallback(shareUrl, onReady); 337 } 338 break; 339 case 'google-plus': 340 url = 'https://clients6.google.com/rpc?key=AIzaSyCKSbrvQasunBoV16zDH9R33D88CeLr9gQ'; 341 body = "[{\"method\":\"pos.plusones.get\",\"id\":\"p\"," + 342 "\"params\":{\"id\":\"" + shareUrl + "\",\"userId\":\"@viewer\",\"groupId\":\"@self\",\"nolog\":true}," + 343 "\"jsonrpc\":\"2.0\",\"key\":\"p\",\"apiVersion\":\"v1\"}]"; 344 parseFunc = function (r) { 345 r = JSON.parse(r); 346 if (r.length) { 347 return onReady(r[0].result.metadata.globalCounts.count); 348 } 349 }; 350 ajax(url, parseFunc, body); 351 return; 352 case 'linkedin': 353 url = 'https://www.linkedin.com/countserv/count/share?url=' + shareUrlEnc; 354 parseFunc = function (r) { 355 return onReady(r.count); 356 }; 357 break; 358 case 'pinterest': 359 url = 'https://api.pinterest.com/v1/urls/count.json?url=' + shareUrlEnc; 360 parseFunc = function (r) { 361 return onReady(r.count); 362 }; 363 break; 364 case 'vk': 365 url = 'https://vk.com/share.php?act=count&url=' + shareUrlEnc; 366 parseFunc = function (r) { 367 return onReady(r); 368 }; 369 break; 370 case 'buffer': 371 url = 'https://api.bufferapp.com/1/links/shares.json?url=' + shareUrlEnc; 372 parseFunc = function (r) { 373 return onReady(r.shares); 374 }; 375 break; 376 } 377 url && parseFunc && JSONPRequest(network, url, parseFunc, body); 378 } 379 380 function ajax(url, callback, body) { 381 var request = new XMLHttpRequest(); 382 request.onreadystatechange = function () { 383 if (this.readyState === 4) { 384 if (this.status >= 200 && this.status < 400) { 385 callback(this.responseText); 386 } 387 } 388 }; 389 request.open('POST', url, true); 390 request.setRequestHeader('Content-Type', 'application/json'); 391 request.send(body); 392 } 393 394 function JSONPRequest(network, url, callback) { 395 var callbackName = 'cb_' + network + '_' + Math.round(100000 * Math.random()), 396 script = document.createElement('script'); 397 window[callbackName] = function (data) { 398 try { // IE8 399 delete window[callbackName]; 400 } catch (e) { 401 } 402 document.body.removeChild(script); 403 callback(data); 404 }; 405 if (network == 'vk') { 406 window['VK'] = { 407 Share: { 408 count: function (a, b) { 409 window[callbackName](b); 410 } 411 } 412 }; 413 } else if (network == 'google-plus') { 414 window['services'] = { 415 gplus: { 416 cb: window[callbackName] 417 } 418 }; 419 } 420 script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName; 421 document.body.appendChild(script); 422 return true; 423 } 424 425 return { 426 init: init 427 }; 428})(); 429 430window.SocialShareKit = SocialShareKit;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.