1/** 2 * Social Likes 3 * http://sapegin.github.com/social-likes 4 * 5 * Sharing buttons for Russian and worldwide social networks. 6 * 7 * @requires jQuery 8 * @author Artem Sapegin 9 * @copyright 2014 Artem Sapegin (sapegin.me) 10 * @license MIT 11 */ 12 13/* global define:false, socialLikesButtons:false */ 14 15function CopyLink() { 16 17 let copy_link = document.querySelector('#copy_link') 18 navigator.clipboard.writeText(copy_link.value) 19 .then(() => { 20 console.log('СÑÑлка ÑкопиÑована') 21 }) 22 .catch(error => { 23 console.error(`СÑÑлка не ÑкопиÑована ${error}`) 24 }) 25 26 return false; 27} 28 29 30(function(factory) { 31 // Try to register as an anonymous AMD module 32 if (typeof define === 'function' && define.amd) { 33 define(['jquery'], factory); 34 } else { 35 factory(jQuery); 36 } 37})(function($, undefined) { 38 'use strict'; 39 40 var prefix = 'social-likes'; 41 var classPrefix = prefix + '__'; 42 var openClass = prefix + '_opened'; 43 var protocol = location.protocol === 'https:' ? 'https:' : 'http:'; 44 45 /** 46 * Buttons 47 */ 48 var services = { 49 twitter: { 50 counters: false, 51 popupUrl: 'https://twitter.com/intent/tweet?url={url}&text={title}', 52 popupWidth: 600, 53 popupHeight: 250, 54 click: function() { 55 // Add colon to improve readability 56 if (!/[.?:\-ââ]\s*$/.test(this.options.title)) { 57 this.options.title += ':'; 58 } 59 return true; 60 }, 61 }, 62 mailru: { 63 counterUrl: protocol + '//connect.mail.ru/share_count?url_list={url}&callback=1&func=?', 64 convertNumber: function(data) { 65 for (var url in data) { 66 if (data.hasOwnProperty(url)) { 67 return data[url].shares; 68 } 69 } 70 }, 71 popupUrl: 'https://connect.mail.ru/share?share_url={url}&title={title}', 72 popupWidth: 492, 73 popupHeight: 500, 74 }, 75 vkontakte: { 76 counterUrl: 'https://vk.com/share.php?act=count&url={url}&index={index}', 77 counter: function(jsonUrl, deferred) { 78 var options = services.vkontakte; 79 if (!options._) { 80 options._ = []; 81 if (!window.VK) { 82 window.VK = {}; 83 } 84 window.VK.Share = { 85 count: function(idx, number) { 86 options._[idx].resolve(number); 87 }, 88 }; 89 } 90 91 var index = options._.length; 92 options._.push(deferred); 93 $.getScript(makeUrl(jsonUrl, { index: index })).fail(deferred.reject); 94 }, 95 popupUrl: 'https://vk.com/share.php?url={url}&title={title}', 96 popupWidth: 655, 97 popupHeight: 450, 98 }, 99 odnoklassniki: { 100 counterUrl: protocol + '//connect.ok.ru/dk?st.cmd=extLike&ref={url}&uid={index}', 101 counter: function(jsonUrl, deferred) { 102 var options = services.odnoklassniki; 103 if (!options._) { 104 options._ = []; 105 if (!window.ODKL) { 106 window.ODKL = {}; 107 } 108 window.ODKL.updateCount = function(idx, number) { 109 options._[idx].resolve(number); 110 }; 111 } 112 113 var index = options._.length; 114 options._.push(deferred); 115 $.getScript(makeUrl(jsonUrl, { index: index })).fail(deferred.reject); 116 }, 117 popupUrl: 118 'https://connect.ok.ru/dk?st.cmd=WidgetSharePreview&service=odnoklassniki&st.shareUrl={url}', 119 popupWidth: 580, 120 popupHeight: 336, 121 }, 122 plusone: { 123 counters: false, 124 popupUrl: 'https://plus.google.com/share?url={url}', 125 popupWidth: 500, 126 popupHeight: 550, 127 }, 128 pinterest: { 129 counterUrl: protocol + '//api.pinterest.com/v1/urls/count.json?url={url}&callback=?', 130 convertNumber: function(data) { 131 return data.count; 132 }, 133 popupUrl: 'https://pinterest.com/pin/create/button/?url={url}&description={title}', 134 popupWidth: 740, 135 popupHeight: 550, 136 }, 137 }; 138 139 /** 140 * Counters manager 141 */ 142 var counters = { 143 promises: {}, 144 fetch: function(service, url, extraOptions) { 145 if (!counters.promises[service]) { 146 counters.promises[service] = {}; 147 } 148 var servicePromises = counters.promises[service]; 149 150 if (!extraOptions.forceUpdate && servicePromises[url]) { 151 return servicePromises[url]; 152 } 153 154 var options = $.extend({}, services[service], extraOptions); 155 var deferred = $.Deferred(); 156 var jsonUrl = options.counterUrl && makeUrl(options.counterUrl, { url: url }); 157 158 if (jsonUrl && $.isFunction(options.counter)) { 159 options.counter(jsonUrl, deferred); 160 } else if (options.counterUrl) { 161 $.getJSON(jsonUrl) 162 .done(function(data) { 163 try { 164 var number = data; 165 if ($.isFunction(options.convertNumber)) { 166 number = options.convertNumber(data); 167 } 168 deferred.resolve(number); 169 } catch (e) { 170 deferred.reject(); 171 } 172 }) 173 .fail(deferred.reject); 174 } else { 175 deferred.reject(); 176 } 177 178 servicePromises[url] = deferred.promise(); 179 return servicePromises[url]; 180 }, 181 }; 182 183 // jQuery plugin 184 $.fn.socialLikes = function(options) { 185 return this.each(function() { 186 var elem = $(this); 187 var instance = elem.data(prefix); 188 if (instance) { 189 if ($.isPlainObject(options)) { 190 instance.update(options); 191 } 192 } else { 193 instance = new SocialLikes( 194 elem, 195 $.extend({}, $.fn.socialLikes.defaults, options, dataToOptions(elem)) 196 ); 197 elem.data(prefix, instance); 198 } 199 }); 200 }; 201 202 $.fn.socialLikes.defaults = { 203 url: window.location.href.replace(window.location.hash, ''), 204 title: document.title, 205 counters: true, 206 zeroes: false, 207 wait: 500, // Show buttons only after counters are ready or after this amount of time 208 timeout: 10000, // Show counters after this amount of time even if they arenât ready 209 popupCheckInterval: 500, 210 singleTitle: 'Share', 211 }; 212 213 function SocialLikes(container, options) { 214 this.container = container; 215 this.options = options; 216 this.init(); 217 } 218 219 SocialLikes.prototype = { 220 init: function() { 221 // Add class in case of manual initialization 222 this.container.addClass(prefix); 223 224 this.single = this.container.hasClass(prefix + '_single'); 225 226 this.initUserButtons(); 227 228 this.countersLeft = 0; 229 this.number = 0; 230 this.container.on('counter.' + prefix, $.proxy(this.updateCounter, this)); 231 232 var buttons = this.container.children(); 233 234 this.makeSingleButton(); 235 236 this.buttons = []; 237 buttons.each( 238 $.proxy(function(idx, elem) { 239 var button = new Button($(elem), this.options); 240 this.buttons.push(button); 241 if (button.options.counterUrl) { 242 this.countersLeft++; 243 } 244 }, this) 245 ); 246 247 if (this.options.counters) { 248 this.timer = setTimeout($.proxy(this.appear, this), this.options.wait); 249 this.timeout = setTimeout($.proxy(this.ready, this, true), this.options.timeout); 250 } else { 251 this.appear(); 252 } 253 }, 254 initUserButtons: function() { 255 if (!this.userButtonInited && window.socialLikesButtons) { 256 $.extend(true, services, socialLikesButtons); 257 } 258 this.userButtonInited = true; 259 }, 260 makeSingleButton: function() { 261 if (!this.single) { 262 return; 263 } 264 265 var container = this.container; 266 container.addClass(prefix + '_vertical'); 267 container.wrap($('<div>', { class: prefix + '_single-w' })); 268 container.wrapInner($('<div>', { class: prefix + '__single-container' })); 269 var wrapper = container.parent(); 270
271 // Widget 272 var widget = $('<div>', { 273 class: getElementClassNames('widget', 'single'), 274 }); 275 var button = $( 276 template( 277 '<div class="{buttonCls}">' + '<span class="{iconCls}"></span>' + '{title}' + '</div>', 278 { 279 buttonCls: getElementClassNames('button', 'single'), 280 iconCls: getElementClassNames('icon', 'single'), 281 title: this.options.singleTitle, 282 } 283 ) 284 ); 285 widget.append(button); 286 wrapper.append(widget); 287 288 widget.on('click', function() { 289 var activeClass = prefix + '__widget_active'; 290 widget.toggleClass(activeClass); 291 if (widget.hasClass(activeClass)) { 292 container.css({ 293 left: -(container.width() - widget.width()) / 2, 294 top: -container.height(), 295 }); 296 showInViewport(container); 297 closeOnClick(container, function() { 298 widget.removeClass(activeClass); 299 }); 300 } else { 301 container.removeClass(openClass); 302 } 303 return false; 304 }); 305 306 this.widget = widget; 307 }, 308 update: function(options) { 309 if (!options.forceUpdate && options.url === this.options.url) { 310 return; 311 } 312 313 // Reset counters 314 this.number = 0; 315 this.countersLeft = this.buttons.length; 316 if (this.widget) { 317 this.widget.find('.' + prefix + '__counter').remove(); 318 } 319 320 // Update options 321 $.extend(this.options, options); 322 for (var buttonIdx = 0; buttonIdx < this.buttons.length; buttonIdx++) { 323 this.buttons[buttonIdx].update(options); 324 } 325 }, 326 updateCounter: function(e, service, number) { 327 number = number || 0; 328 329 if (number || this.options.zeroes) { 330 this.number += number; 331 if (this.single) { 332 this.getCounterElem().text(this.number); 333 } 334 } 335 336 this.countersLeft--; 337 338 if (this.countersLeft === 0) { 339 this.appear(); 340 this.ready(); 341 } 342 }, 343 appear: function() { 344 this.container.addClass(prefix + '_visible'); 345 }, 346 ready: function(silent) { 347 if (this.timeout) { 348 clearTimeout(this.timeout); 349 } 350 this.container.addClass(prefix + '_ready'); 351 if (!silent) { 352 this.container.trigger('ready.' + prefix, this.number); 353 } 354 }, 355 getCounterElem: function() { 356 var counterElem = this.widget.find('.' + classPrefix + 'counter_single'); 357 if (!counterElem.length) { 358 counterElem = $('<span>', { 359 class: getElementClassNames('counter', 'single'), 360 }); 361 this.widget.append(counterElem); 362 } 363 return counterElem; 364 }, 365 }; 366 367 function Button(widget, options) { 368 this.widget = widget; 369 this.options = $.extend({}, options); 370 this.detectService(); 371 if (this.service) { 372 this.init(); 373 } 374 } 375 376 Button.prototype = { 377 init: function() { 378 this.detectParams(); 379 this.initHtml(); 380 setTimeout($.proxy(this.initCounter, this), 0); 381 }, 382 383 update: function(options) { 384 $.extend(this.options, { forceUpdate: false }, options); 385 this.widget.find('.' + prefix + '__counter').remove(); // Remove old counter 386 this.initCounter(); 387 }, 388 389 detectService: function() { 390 var service = this.widget.data('service'); 391 if (!service) { 392 // class="facebook" 393 var node = this.widget[0]; 394 var classes = node.classList || node.className.split(' '); 395 for (var classIdx = 0; classIdx < classes.length; classIdx++) { 396 var cls = classes[classIdx]; 397 if (services[cls]) { 398 service = cls; 399 break; 400 } 401 } 402 if (!service) { 403 return; 404 } 405 } 406 this.service = service; 407 $.extend(this.options, services[service]); 408 }, 409 410 detectParams: function() { 411 var data = this.widget.data(); 412 413 // Custom page counter URL or number 414 if (data.counter) { 415 var number = parseInt(data.counter, 10); 416 if (isNaN(number)) { 417 this.options.counterUrl = data.counter; 418 } else { 419 this.options.counterNumber = number; 420 } 421 } 422 423 // Custom page title 424 if (data.title) { 425 this.options.title = data.title; 426 } 427 428 // Custom page URL 429 if (data.url) { 430 this.options.url = data.url; 431 } 432 }, 433 434 initHtml: function() { 435 var options = this.options; 436 var widget = this.widget; 437 438 // Old initialization HTML 439 var a = widget.find('a'); 440 if (a.length) { 441 this.cloneDataAttrs(a, widget); 442 } 443 444 // Button 445 var button = $('<span>', { 446 class: this.getElementClassNames('button'), 447 html: widget.html(), 448 }); 449 if (options.clickUrl) { 450 var url = makeUrl(options.clickUrl, { 451 url: options.url, 452 title: options.title, 453 }); 454 var link = $('<a>', { 455 href: url, 456 }); 457 this.cloneDataAttrs(widget, link); 458 widget.replaceWith(link); 459 this.widget = link; 460 widget = link; 461 } else { 462 widget.on('click', $.proxy(this.click, this)); 463 } 464 465 widget.removeClass(this.service); 466 widget.addClass(this.getElementClassNames('widget')); 467 468 // Icon
469 button.prepend($('<span>', { class: this.getElementClassNames('icon') })); 470 471 widget.empty().append(button); 472 this.button = button; 473 }, 474 475 initCounter: function() { 476 if (this.options.counters) { 477 if (this.options.counterNumber) { 478 this.updateCounter(this.options.counterNumber); 479 } else { 480 var extraOptions = { 481 counterUrl: this.options.counterUrl, 482 forceUpdate: this.options.forceUpdate, 483 }; 484 counters 485 .fetch(this.service, this.options.url, extraOptions) 486 .always($.proxy(this.updateCounter, this)); 487 } 488 } 489 }, 490 491 cloneDataAttrs: function(source, destination) { 492 var data = source.data(); 493 for (var key in data) { 494 if (data.hasOwnProperty(key)) { 495 destination.data(key, data[key]); 496 } 497 } 498 }, 499 500 getElementClassNames: function(elem) { 501 return getElementClassNames(elem, this.service); 502 }, 503 504 updateCounter: function(number) { 505 number = parseInt(number, 10) || 0; 506 507 var params = { 508 class: this.getElementClassNames('counter'), 509 text: number, 510 }; 511 if (!number && !this.options.zeroes) { 512 params.class += ' ' + prefix + '__counter_empty'; 513 params.text = ''; 514 } 515 516 var counterElem = this.widget.find('.' + classPrefix + 'counter_' + this.service); 517 if (!counterElem.length) { 518 counterElem = $('<span>', params); 519 this.widget.append(counterElem); 520 } else { 521 var text = params.text + 0; 522 counterElem.html(text); 523 } 524 this.widget.trigger('counter.' + prefix, [this.service, number]); 525 }, 526 527 click: function(e) { 528 var options = this.options; 529 var process = true; 530 if ($.isFunction(options.click)) { 531 process = options.click.call(this, e); 532 } 533 if (process) { 534 var url = makeUrl(options.popupUrl, { 535 url: options.url, 536 title: options.title, 537 }); 538 url = this.addAdditionalParamsToUrl(url); 539 this.openPopup(url, { 540 width: options.popupWidth, 541 height: options.popupHeight, 542 }); 543 } 544 return false; 545 }, 546 547 addAdditionalParamsToUrl: function(url) { 548 var params = $.param($.extend(this.widget.data(), this.options.data)); 549 if ($.isEmptyObject(params)) { 550 return url; 551 } 552 var glue = url.indexOf('?') === -1 ? '?' : '&'; 553 return url + glue + params; 554 }, 555 556 openPopup: function(url, params) { 557 var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; 558 var dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; 559 var width = window.innerWidth 560 ? window.innerWidth 561 : document.documentElement.clientWidth 562 ? document.documentElement.clientWidth 563 : screen.width; 564 var height = window.innerHeight 565 ? window.innerHeight 566 : document.documentElement.clientHeight 567 ? document.documentElement.clientHeight 568 : screen.height; 569 570 var left = Math.round(width / 2 - params.width / 2) + dualScreenLeft; 571 var top = 0; 572 if (height > params.height) { 573 top = Math.round(height / 3 - params.height / 2) + dualScreenTop; 574 } 575 576 var win = window.open( 577 url, 578 'sl_' + this.service, 579 'left=' + 580 left + 581 ',top=' + 582 top + 583 ',' + 584 'width=' + 585 params.width + 586 ',height=' + 587 params.height + 588 ',personalbar=0,toolbar=0,scrollbars=1,resizable=1' 589 ); 590 if (win) { 591 win.focus(); 592 this.widget.trigger('popup_opened.' + prefix, [this.service, win]); 593 var timer = setInterval( 594 $.proxy(function() { 595 if (!win.closed) { 596 return; 597 } 598 clearInterval(timer); 599 this.widget.trigger('popup_closed.' + prefix, this.service); 600 }, this), 601 this.options.popupCheckInterval 602 ); 603 } else { 604 location.href = url; 605 } 606 }, 607 }; 608 609 /** 610 * Helpers 611 */ 612 613 // Camelize data-attributes 614 function dataToOptions(elem) { 615 function upper(m, l) { 616 return l.toUpper(); 617 } 618 var options = {}; 619 var data = elem.data(); 620 for (var key in data) { 621 var value = data[key]; 622 if (value === 'yes') { 623 value = true; 624 } else if (value === 'no') { 625 value = false;
626 } 627 options[key.replace(/-(\w)/g, upper)] = value; 628 } 629 return options; 630 } 631 632 function makeUrl(url, context) { 633 return template(url, context, encodeURIComponent); 634 } 635 636 function template(tmpl, context, filter) { 637 return tmpl.replace(/\{([^}]+)\}/g, function(m, key) { 638 // If key doesn't exists in the context we should keep template tag as is 639 return key in context ? (filter ? filter(context[key]) : context[key]) : m; 640 }); 641 } 642 643 function getElementClassNames(elem, mod) { 644 var cls = classPrefix + elem; 645 return cls + ' ' + cls + '_' + mod; 646 } 647 648 function closeOnClick(elem, callback) { 649 function handler(e) { 650 if ((e.type === 'keydown' && e.which !== 27) || $(e.target).closest(elem).length) { 651 return; 652 } 653 elem.removeClass(openClass); 654 doc.off(events, handler); 655 if ($.isFunction(callback)) { 656 callback(); 657 } 658 } 659 var doc = $(document); 660 var events = 'click touchstart keydown'; 661 doc.on(events, handler); 662 } 663 664 function showInViewport(elem) { 665 var offset = 10; 666 if (document.documentElement.getBoundingClientRect) { 667 var left = parseInt(elem.css('left'), 10); 668 var top = parseInt(elem.css('top'), 10); 669 670 var rect = elem[0].getBoundingClientRect(); 671 if (rect.left < offset) { 672 elem.css('left', offset - rect.left + left); 673 } else if (rect.right > window.innerWidth - offset) { 674 elem.css('left', window.innerWidth - rect.right - offset + left); 675 } 676 677 if (rect.top < offset) { 678 elem.css('top', offset - rect.top + top); 679 } else if (rect.bottom > window.innerHeight - offset) { 680 elem.css('top', window.innerHeight - rect.bottom - offset + top); 681 } 682 } 683 elem.addClass(openClass); 684 } 685 686 /** 687 * Auto initialization 688 */ 689 $(function() { 690 $('.' + prefix).socialLikes(); 691 }); 692}); 693$('.social-likes').socialLikes(); 694 695$( ".blog-detail-main__inner li" ).each(function( index ) { 696 //$( this ).html('<p>'+$( this ).text()+'</p>'); 697});
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.