PageSourceSearch

http://cmaf.ru/simai/asset/social-likes/social-likes-3.1.2/social-likes.min.js?171467709519330

js cmaf.ru collected 2026-09-27 20:55:41 UTC 19,330 bytes, 708 lines download raw bytes

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

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.