PageSourceSearch

https://vlany.org/wp-content/themes/flax_wp/public/js/assets/socia…?ver=f7035bf234e9905ef616e4222efa434f

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

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.