PluginProbe
Float menu – awesome floating side menu / 6.1.2
Float menu – awesome floating side menu v6.1.2
7.2.5 trunk 2.1 2.2 3.0.1 3.1 3.2.2 3.3.1 3.5 3.5.1 3.5.2 3.5.3. 3.5.4 4.0 4.1 4.1.1 4.2 4.3 4.3.1 4.3.2 5.0 5.0.1 5.0.2 5.0.3 5.1 All 57 releases
float-menu / public / assets / js / floatMenu.js

floatMenu.js in Float menu – awesome floating side menu 6.1.2, at public/assets/js/floatMenu.js

1,424 lines 54.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*! ========= INFORMATION ============================
2 - document: Float Menu Pro
3 - brand: Wow-Company
4 - brand-url: https://wow-company.com/
5 - store-url: https://wow-estore.com/
6 - author: Dmytro Lobov
7 - url: https://wow-estore.com/item/float-menu-pro/
8 ==================================================== */
9
10 'use strict';
11
12 (function ($) {
13
14 var defaults = {
15 // Main
16 position: ['left', 'center'],
17 offset: [0, 0],
18 buttonShape: 'round',
19 buttonColor: 'custom',
20 buttonOverColor: 'custom',
21 iconColor: 'white',
22 iconOverColor: 'white',
23 labelColor: 'match',
24 labelTextColor: 'match',
25 labelEffect: 'slide-out-fade',
26 labelAnimate: 'default',
27 labelConnected: false,
28 labelsOn: true,
29 sideSpace: false,
30 buttonSpace: false,
31 labelSpace: false,
32 mobileEnable: false,
33 mobileScreen: 768,
34 // Subbar
35 subPosition: ['circular', 100, -90, 90],
36 subEffect: ['slide', 30],
37 subAnimate: [400, 'easeOutQuad'],
38 subSpace: false,
39 subOpen: 'mouseover',
40 subTop: 42,
41 // Window
42 windowPosition: ['center', 'center'],
43 windowOffset: [0, 0],
44 windowCorners: 'match',
45 windowColor: 'match',
46 windowShadow: true,
47 // Other
48 showAfterPosition: false,
49 hideAfterPosition: false,
50 barAnimate: [250, 'easeOutQuad'],
51 hideUnderWidth: false,
52 shareTarget: 'default',
53 };
54 var labelAnimateDefaults = {
55 'default': [400, 'easeOutQuad'],
56 'fade': [200, 'easeOutQuad'],
57 'slide-in-in': {
58 show: [400, 'easeOutQuad'],
59 hide: [400, 'swing'],
60 },
61 };
62
63 var methods = {
64 'build': build,
65 'destroy': destroy,
66 };
67
68 $.fn.floatingMenu = function (arg) {
69 if (typeof arg === 'object' || !arg) {
70 build.apply(this, arguments);
71 } else if (methods[arg]) {
72 methods[arg].apply(this, Array.prototype.slice.call(arguments, 1));
73 } else {
74 $.error('The method ' + arg + ' does not exist in Float Menu.');
75 }
76 };
77
78 function build(options) {
79 var settings = createSettings(options);
80
81 return this.each(function () {
82 var sidebar = $(this);
83
84 if (sidebar.data('fm-built')) destroy.apply(this);
85 sidebar.data('fm-built', true);
86
87 // VARS
88 var bar = sidebar.children('.fm-bar');
89 var barList = bar.children();
90 var sbwindow = sidebar.children('.fm-window');
91
92 var $window = $(window);
93 var $document = $(document);
94
95 var barVisible = true;
96 var right = false;
97 var csub = null;
98 var cwindow = null;
99 var nextMargins = [];
100
101 // INIT
102 if (settings.position[0] === 'right') {
103 right = true;
104 bar.addClass('fm-right');
105 }
106
107 if (settings.buttonShape !== 'square') bar.addClass('fm-' + settings.buttonShape);
108
109 if (settings.labelConnected) bar.addClass('fm-connected');
110
111 if (settings.buttonColor !== 'custom') bar.addClass('fm-' + settings.buttonColor + '-button');
112 if (settings.buttonOverColor !== 'custom') bar.addClass('fm-' + settings.buttonOverColor + '-button-over');
113
114 if (settings.iconColor !== 'custom') bar.addClass('fm-' + settings.iconColor + '-icon');
115 if (settings.iconOverColor !== 'custom') bar.addClass('fm-' + settings.iconOverColor + '-icon-over');
116
117 if (settings.labelColor !== 'custom') bar.addClass('fm-' + settings.labelColor + '-label');
118 if (settings.labelTextColor !== 'custom') bar.addClass('fm-' + settings.labelTextColor + '-label-text');
119
120 if (settings.sideSpace) bar.addClass('fm-side-space');
121 if (settings.buttonSpace) bar.addClass('fm-button-space');
122 if (settings.labelSpace) bar.addClass('fm-label-space');
123
124 if (settings.windowCorners === 'round') sbwindow.addClass('fm-round');
125 if (settings.windowColor !== 'custom') sbwindow.addClass('fm-' + settings.windowColor);
126 if (settings.windowShadow) sbwindow.addClass('fm-winshadow');
127
128 buildList(bar);
129
130 // Subbar animate fix.
131 barList.each(function (ind) {
132 nextMargins[ind] = getInt(barList.eq(ind).css('margin-top'));
133 });
134
135 sbwindow.children('.fm-shadow').on('click', closeWindow);
136
137 sbwindow.children('.fm-panel').each(buildPanel);
138
139 resize();
140
141 $window.on('resize.superSidebar', resize);
142
143 if (settings.showAfterPosition) {
144 if ($window.scrollTop() < settings.showAfterPosition) {
145 bar.css('opacity', 0).addClass('fm-hide');
146 barVisible = false;
147 }
148
149 $window.on('scroll.superSidebar', function () {
150 if ($window.scrollTop() < settings.showAfterPosition) {
151 if (barVisible) hideBar();
152 } else {
153 if (!barVisible) showBar();
154 }
155 });
156 }
157
158 if (settings.hideAfterPosition) {
159 if ($window.scrollTop() > settings.hideAfterPosition) {
160 bar.css('opacity', 0).addClass('fm-hide');
161 barVisible = false;
162 }
163
164 $window.on('scroll.superSidebar', function () {
165 if ($window.scrollTop() > settings.hideAfterPosition) {
166 if (barVisible) hideBar();
167 } else {
168 if (!barVisible) showBar();
169 }
170 });
171 }
172
173 bar.addClass('fm-css-anim');
174
175 sidebar.addClass('fm-ready');
176
177 // FUNCTIONS
178 function buildList(list) {
179 list.children().each(function (i) {
180 if ($(this).hasClass('fm-sub')) buildSub(this, i);
181 else buildButton(this);
182 });
183 }
184
185 function buildButton(btn) {
186 var button = $(btn);
187 var link = button.children('a, .fm-link');
188 var icon = link.children('.fm-icon');
189 var label = link.children('.fm-label');
190 var mask, hit = null;
191
192 var linkClick = 0;
193 var screen = $(window).width();
194
195 var maskHtml = '<div class="fm-mask"></div>';
196 var hitHtml = '<div class="fm-hit"></div>';
197
198 var iw, lw;
199 var side = right ? 'right' : 'left';
200 var dist = 40;
201 var maskOff = false;
202 var start = {}, show = {}, end = {};
203 var showLabel, hideLabel;
204
205 var showTime = settings.labelAnimate.show[0];
206 var showEase = settings.labelAnimate.show[1];
207 var hideTime = settings.labelAnimate.hide[0];
208 var hideEase = settings.labelAnimate.hide[1];
209
210 if (settings.labelsOn && label.length) {
211 iw = getInt(icon.css('width'));
212 lw = label.outerWidth(true);
213 if (settings.position[0] === 'left') {
214 label.css({'left': iw + 'px'});
215 } else {
216 label.css({'right': iw + 'px'});
217 }
218
219
220 if (settings.buttonShape === 'round' || settings.buttonShape === 'rounded') maskOff = true;
221
222 if (settings.labelConnected && settings.position[0] === 'left') {
223 label.css({'left': 0, 'padding-left': iw + 12 + 'px'});
224 } else if (settings.labelConnected && settings.position[0] === 'right') {
225 label.css({'right': 0, 'padding-right': iw + 12 + 'px'});
226 }
227
228 if (!settings.labelConnected &&
229 (settings.labelSpace || settings.buttonShape === 'round' || settings.buttonShape === 'rounded' ||
230 settings.buttonShape === 'rounded-out')) {
231 hit = $(hitHtml).appendTo(link);
232 }
233
234
235 switch (settings.labelEffect) {
236 case 'fade':
237 start = {'opacity': 0};
238 show = {'opacity': 1};
239
240 label.css(start);
241
242 showLabel = function () {
243 if (hit) hit.addClass('fm-show');
244 label.velocity('stop').addClass('fm-show').velocity(show, showTime, showEase);
245 };
246 hideLabel = function () {
247 label.velocity('stop').velocity(start, hideTime, hideEase, function () {
248 label.removeClass('fm-show');
249 if (hit) hit.removeClass('fm-show');
250 });
251 };
252 break;
253 case 'slide-out':
254 case 'slide-out-fade':
255 mask = link.wrap(maskHtml).parent();
256 mask.css('width', iw);
257 if (maskOff) mask.addClass('fm-off');
258
259 start[side] = -lw + iw;
260 if (settings.labelConnected) show[side] = 0;
261 else show[side] = iw;
262
263 if (settings.labelEffect === 'slide-out-fade') {
264 start['opacity'] = 0;
265 show['opacity'] = 1;
266 }
267
268 label.css(start);
269
270 showLabel = function () {
271 mask.css('width', iw + lw);
272 if (maskOff) mask.removeClass('fm-off');
273 if (hit) hit.addClass('fm-show');
274 label.velocity('stop').addClass('fm-show').velocity(show, showTime, showEase, function () {
275 mask.addClass('fm-off');
276 });
277 };
278 hideLabel = function () {
279 mask.removeClass('fm-off');
280 label.velocity('stop').velocity(start, hideTime, hideEase, function () {
281 label.removeClass('fm-show');
282 mask.css('width', iw);
283 if (maskOff) mask.addClass('fm-off');
284 if (hit) hit.removeClass('fm-show');
285 });
286 };
287 break;
288 case 'slide-in':
289 start = {'opacity': 0};
290 start[side] = iw + dist;
291 show = {'opacity': 1};
292 show[side] = iw;
293
294 label.css(start);
295
296 showLabel = function () {
297 if (hit) hit.addClass('fm-show');
298 label.velocity('stop').addClass('fm-show').velocity(show, showTime, showEase);
299 };
300 hideLabel = function () {
301 label.velocity('stop').velocity(start, hideTime, hideEase, function () {
302 label.removeClass('fm-show');
303 if (hit) hit.removeClass('fm-show');
304 });
305 };
306 break;
307 case 'slide-out-out':
308 case 'slide-in-in':
309 mask = link.wrap(maskHtml).parent();
310 mask.css('width', iw);
311 if (maskOff) mask.addClass('fm-off');
312
313 if (settings.labelEffect === 'slide-out-out') {
314 start[side] = -lw + iw;
315 show[side] = iw;
316 end[side] = iw + dist;
317 } else {
318 start[side] = iw + dist;
319 show[side] = iw;
320 end[side] = -lw + iw;
321 }
322 start['opacity'] = 0;
323 show['opacity'] = 1;
324 end['opacity'] = 0;
325
326 showLabel = function () {
327 mask.css('width', iw + lw + dist);
328 if (maskOff) mask.removeClass('fm-off');
329 if (hit) hit.addClass('fm-show');
330 label.velocity('stop').css(start).addClass('fm-show').velocity(show, showTime, showEase, function () {
331 mask.css('width', iw + lw);
332 mask.addClass('fm-off');
333 });
334 };
335 hideLabel = function () {
336 mask.removeClass('fm-off');
337 mask.css('width', iw + lw + dist);
338 label.velocity('stop').velocity(end, hideTime, hideEase, function () {
339 label.removeClass('fm-show');
340 mask.css('width', iw);
341 if (maskOff) mask.addClass('fm-off');
342 if (hit) hit.removeClass('fm-show');
343 });
344 };
345 break;
346 default:
347 showLabel = function () {
348 if (hit) hit.addClass('fm-show');
349 label.addClass('fm-show');
350 };
351 hideLabel = function () {
352 label.removeClass('fm-show');
353 if (hit) hit.removeClass('fm-show');
354 };
355 break;
356 }
357
358 if (settings.mobileEnable == true && settings.mobileScreen >= screen) {
359 link.on('touchend', function (e) {
360 if (!label.hasClass('fm-show')) {
361 e.preventDefault();
362 showLabel();
363 touchAnyWhere(link, label);
364 }
365 });
366
367 } else {
368 link.on('mouseenter', showLabel);
369 link.on('mouseleave', hideLabel);
370 }
371 }
372
373 function touchAnyWhere(link, label) {
374 $(document).on('touchstart', function (e) {
375 if (!$(e.target).closest(link).length) {
376 label.removeClass('fm-show');
377 }
378 });
379 }
380
381 var shareVal = link.data('share');
382 var shareData;
383 var shareUrl;
384 var shareTarget;
385 var href;
386 var labelShow;
387
388 if (shareVal) {
389 if (shareVal === 'pinterest') {
390 link.on('click', pinterestShare);
391 } else {
392 shareData = settings.shareServices[shareVal];
393
394 if (shareData) {
395 shareUrl = shareData.url.replace('{URL}', PAGE_URL).replace('{TITLE}', PAGE_TITLE);
396
397 link.attr('href', shareUrl);
398
399 if (shareData.target === 'app') {
400 link.attr('target', '_self');
401 } else {
402 if (settings.shareTarget === 'default') shareTarget = shareData.target;
403 else shareTarget = settings.shareTarget;
404
405 if (shareTarget === 'popup') {
406 link.on('click', {'url': shareUrl, 'params': shareData.popup}, sharePopup);
407 } else {
408 link.attr('target', '_blank');
409 }
410 }
411 } else {
412 warn('There is no share data for "' + shareVal + '".');
413 }
414 }
415 } else {
416 href = link.attr('href');
417
418 if (href && href.indexOf('fm-popup') > -1 && href !== '#') {
419 link.on('click', function () {
420 openWindow(href);
421 return false;
422 });
423 }
424 }
425
426 labelShow = link.attr('data-label');
427
428 if (labelShow === 'show') {
429 showLabel();
430 }
431
432 }
433
434 function buildSub(sub, ind) {
435 var sub = $(sub);
436 var icon = sub.children('.fm-icon');
437 var list = sub.children('ul');
438 var buttonList = list.children();
439 var hit = null;
440 var nextButton = null;
441
442 var hitHtml = '<div class="fm-subhit"></div>';
443
444 var position = settings.subPosition[0];
445 var effect = settings.subEffect[0];
446 var side = right ? 'right' : 'left';
447 var total = buttonList.length;
448 var iw = getInt(icon.css('width'));
449 var ih = getInt(icon.css('height'));
450 var positions = [];
451 var status = null;
452 var start = {}, show = {};
453 var interval;
454 var showList, hideList;
455 var i;
456 var nextOffset = 0;
457 var prevOffset = 0;
458 var nextMargin;
459 var buttonMargin;
460 var barMargin;
461 var subOpen = false;
462
463 var showTime = settings.subAnimate.show[0];
464 var showEase = settings.subAnimate.show[1];
465 var hideTime = settings.subAnimate.hide[0];
466 var hideEase = settings.subAnimate.hide[1];
467
468 buildList(list);
469
470 if (position === 'side') sub.addClass('fm-side');
471 if (settings.subSpace) sub.addClass('fm-sub-space');
472
473 if (effect === 'linear-slide' || position === 'circular')
474 sub.addClass('fm-posabs');
475
476 if ((position === 'under' && effect === 'linear-slide') ||
477 (position === 'circular' && effect === 'slide') ||
478 (position === 'circular' && effect === 'linear-slide')) {
479 buttonList.each(function (i) {
480 $(this).css('z-index', 100 - i);
481 });
482 }
483
484 if (barList[ind + 1]) {
485 nextButton = barList.eq(ind + 1);
486 //nextMargin = getInt(nextButton.css("margin-top"));
487 }
488
489 if (position === 'circular') {
490 sub.addClass('fm-circular');
491
492 var r = settings.subPosition[1];
493 var sa = settings.subPosition[2];
494 var ea = settings.subPosition[3];
495
496 var startRad = sa * Math.PI / 180;
497 var endRad = ea * Math.PI / 180;
498 var stepRad = (endRad - startRad) / (total - 1);
499 var a, s, t, p;
500
501 buttonList.each(function (i) {
502 a = i * stepRad + startRad;
503 s = Math.round(r * Math.cos(a));
504 t = Math.round(r * Math.sin(a));
505
506 p = {'top': t};
507 p[side] = s;
508 $(this).css(p);
509 positions[i] = [s, t];
510 });
511
512 hit = $(hitHtml).appendTo(sub);
513 hit.css({
514 'width': r + iw,
515 'height': 2 * r + iw,
516 'border-radius': right ? r + 'px 0 0 ' + r + 'px' : '0 ' + r + 'px ' + r + 'px 0',
517 'top': -r,
518 });
519
520 buttonMargin = getInt(barList.eq(0).css('margin-bottom'));
521
522 if (ind !== 0) {
523 prevOffset = r + buttonMargin;
524 barMargin = getInt(bar.css('margin-top'));
525 sub.css('margin-top', buttonMargin);
526 }
527
528 if (nextButton) {
529 nextOffset = r + buttonMargin;
530 }
531 } else {
532 if (effect === 'linear-slide') {
533 var c = 0;
534 buttonList.each(function (i) {
535 var btn = $(this);
536 btn.css('top', c);
537 positions[i] = c;
538 c += getInt(btn.css('height')) + getInt(btn.css('margin-bottom'));
539 });
540
541 list.css({'width': iw, 'height': c});
542 }
543
544 hit = $(hitHtml).appendTo(sub);
545 if (position === 'side')
546 hit.css({'width': iw + getInt(list.css('margin-' + side)), 'height': ih});
547 else
548 hit.css({'width': iw, 'height': ih + getInt(list.css('margin-top'))});
549
550 if (position === 'under' && nextButton) {
551 nextOffset = list.outerHeight(true) + getInt(nextButton.css('margin-top')) + getInt(list.css('margin-top'));
552 }
553 }
554
555 list.addClass('fm-hide');
556
557 switch (effect) {
558 case 'fade':
559 start = {'opacity': 0};
560 show = {'opacity': 1};
561
562 list.css(start);
563
564 showList = function () {
565 list.velocity('stop').removeClass('fm-hide').velocity(show, showTime, showEase);
566 };
567 hideList = function () {
568 list.velocity('stop').velocity(start, hideTime, hideEase, function () {
569 list.addClass('fm-hide');
570 });
571 };
572 break;
573 case 'slide':
574 if (position === 'circular') {
575 start = {'top': 0, 'opacity': 0};
576 start[side] = 0;
577 buttonList.css(start);
578
579 showList = function () {
580 list.removeClass('fm-hide');
581 buttonList.each(function (i) {
582 show = {'top': positions[i][1], 'opacity': 1};
583 show[side] = positions[i][0];
584 $(this).velocity('stop').velocity(show, showTime, showEase);
585 });
586 };
587 hideList = function () {
588 buttonList.each(function (i) {
589 $(this).velocity('stop').velocity(start, hideTime, hideEase, function () {
590 if (i === total - 1) list.addClass('fm-hide');
591 });
592 });
593 };
594 } else {
595 if (position === 'side') {
596 start[side] = 0;
597 show[side] = iw;
598 } else {
599 start = {'top': 0};
600 show = {'top': icon[0].clientHeight};
601 }
602 start['opacity'] = 0;
603 show['opacity'] = 1;
604
605 list.css(start);
606
607 showList = function () {
608 list.velocity('stop').removeClass('fm-hide').velocity(show, showTime, showEase);
609 };
610 hideList = function () {
611 list.velocity('stop').velocity(start, hideTime, hideEase, function () {
612 list.addClass('fm-hide');
613 });
614 };
615 }
616 break;
617 case 'linear-fade':
618 start = {'opacity': 0};
619 show = {'opacity': 1};
620
621 buttonList.css(start);
622
623 showList = function () {
624 status = 'show';
625 list.removeClass('fm-hide');
626 stopInterval();
627 i = 0;
628 interval = setInterval(function () {
629 buttonList.eq(i).velocity('stop').velocity(show, showTime, showEase);
630 if (i === total - 1) stopInterval();
631 else i++;
632 }, settings.subEffect[1]);
633 };
634 hideList = function () {
635 status = 'hide';
636 stopInterval();
637 i = total - 1;
638 interval = setInterval(function () {
639 var bi = i;
640 buttonList.eq(i).velocity('stop').velocity(start, showTime, showEase, function () {
641 if (status === 'hide' && bi === 0) list.addClass('fm-hide');
642 });
643 if (i === 0) stopInterval();
644 else i--;
645 }, settings.subEffect[1]);
646 };
647 break;
648 case 'linear-slide':
649 var first, last, step;
650
651 if (position === 'side') start[side] = -iw;
652 else if (position === 'circular') {
653 start = {'top': 0};
654 start[side] = 0;
655 } else start = {'top': -ih};
656 start['opacity'] = 0;
657
658 buttonList.css(start);
659
660 showList = function () {
661 status = 'show';
662 list.removeClass('fm-hide');
663 stopInterval();
664 i = 0;
665 interval = setInterval(function () {
666 if (position === 'side') show[side] = 0;
667 else if (position === 'circular') {
668 show = {'top': positions[i][1]};
669 show[side] = positions[i][0];
670 } else show = {'top': positions[i]};
671 show['opacity'] = 1;
672
673 buttonList.eq(i).velocity('stop').velocity(show, showTime, showEase);
674 if (i === total - 1) stopInterval();
675 else i++;
676 }, settings.subEffect[1]);
677 };
678 hideList = function () {
679 status = 'hide';
680
681 if (position === 'side' || position === 'circular') {
682 first = 0;
683 last = total - 1;
684 step = 1;
685 } else {
686 first = total - 1;
687 last = 0;
688 step = -1;
689 }
690
691 stopInterval();
692 i = first;
693 interval = setInterval(function () {
694 var bi = i;
695 buttonList.eq(i).velocity('stop').velocity(start, showTime, showEase, function () {
696 if (status === 'hide' && bi === last) list.addClass('fm-hide');
697 });
698 if (i === last) stopInterval();
699 else i += step;
700 }, settings.subEffect[1]);
701 };
702 break;
703 default:
704 showList = function () {
705 list.removeClass('fm-hide');
706 };
707 hideList = function () {
708 list.addClass('fm-hide');
709 };
710 break;
711 }
712
713 function stopInterval() {
714 clearInterval(interval);
715 }
716
717 function showSub() {
718 showList();
719 if (hit) hit.addClass('fm-show');
720
721 if (prevOffset) {
722 bar.velocity('stop').velocity({'margin-top': barMargin - prevOffset + buttonMargin}, showTime, showEase);
723 sub.velocity('stop').velocity({'margin-top': prevOffset}, showTime, showEase);
724 }
725
726 if (nextOffset) {
727 nextButton.velocity('stop').velocity({'margin-top': nextOffset}, showTime, showEase);
728 }
729
730 subOpen = true;
731 csub = sub;
732 }
733
734 function hideSub() {
735 hideList();
736 if (hit) hit.removeClass('fm-show');
737
738 if (prevOffset) {
739 bar.velocity('stop').velocity({'margin-top': barMargin}, showTime, showEase);
740 sub.velocity('stop').velocity({'margin-top': buttonMargin}, showTime, showEase);
741 }
742
743 if (nextOffset) {
744 nextButton.velocity('stop').velocity({'margin-top': nextMargins[ind + 1]}, showTime, showEase);
745 }
746
747 subOpen = false;
748 csub = null;
749 }
750
751 sub.show = showSub;
752 sub.hide = hideSub;
753
754 if (settings.subOpen === 'click') {
755 icon.on('click', function (event) {
756 if (subOpen) {
757 hideSub();
758 } else {
759 if (csub) {
760 csub.hide();
761 }
762 showSub();
763 }
764 event.stopPropagation();
765 });
766
767 $document.on('click', function (event) {
768 if (subOpen && !cwindow && !$(event.target).closest(sub).length) {
769 hideSub();
770 }
771 });
772 } else {
773 sub.on('mouseenter touchstart', showSub);
774 sub.on('mouseleave', hideSub);
775 }
776
777 function triggerClick() {
778 $document.on('click', function (event) {
779 if (subOpen && !cwindow && !$(event.target).closest(sub).length) {
780 hideSub();
781 }
782 });
783 }
784
785 window.addEventListener('scroll', function () {
786 if (subOpen) {
787 hideSub();
788 }
789 });
790 }
791
792 function buildPanel() {
793 var panel = $(this);
794 panel.find('.fm-close').on('click', function (event) {
795 closeWindow();
796 event.stopPropagation();
797 });
798
799 }
800
801 function openWindow(name) {
802 sbwindow.addClass('fm-show');
803 cwindow = $(name).addClass('fm-show');
804 posWindow(cwindow);
805 }
806
807 function closeWindow() {
808 sbwindow.removeClass('fm-show');
809 cwindow.removeClass('fm-show');
810 cwindow = null;
811 }
812
813 function position() {
814 posBar();
815 if (cwindow) posWindow(cwindow);
816 }
817
818 function resize() {
819 position();
820
821 if (settings.hideUnderWidth) {
822 if ($window.width() < settings.hideUnderWidth) {
823 sidebar.addClass('fm-vhide');
824 } else {
825 sidebar.removeClass('fm-vhide');
826 }
827 }
828 }
829
830 function posBar() {
831 posObject(bar, settings.position, settings.offset);
832 }
833
834 function posWindow(win) {
835 var pos, off;
836
837 if (win.data('position')) {
838 pos = win.data('position').split('-');
839 if (!pos[1]) pos[1] = defaults.windowPosition[1];
840 } else {
841 pos = settings.windowPosition;
842 }
843
844 if (win.data('offset')) {
845 off = splitOffset(win.data('offset'));
846 } else {
847 off = settings.windowOffset;
848 }
849
850 posObject(win, pos, off);
851 }
852
853 function posObject(tar, pos, off) {
854 if (pos) {
855 var ww = $window.width();
856 var wh = $window.height();
857 var tw = tar.outerWidth(true);
858 var th = tar.outerHeight(true);
859 var x, y;
860 var p;
861
862 if (typeof pos[0] === 'number') x = {'left': pos[0] + off[0]};
863 else if (typeof pos[0] === 'string') {
864 if (pos[0].indexOf('%') !== -1) {
865 p = getInt(pos[0].split('%')[0]);
866 x = {'left': p / 100 * ww + off[0]};
867 } else {
868 if (pos[0] === 'left') x = {'left': 0 + off[0]};
869 else if (pos[0] === 'center') x = {'left': (ww - tw) / 2 + off[0]};
870 else if (pos[0] === 'right') x = {'right': 0 + off[0]};
871
872 else x = {'left': getInt(pos[0]) + off[0]};
873 }
874 }
875
876 if (typeof pos[1] === 'number') y = {'top': pos[1] + off[1]};
877 else if (typeof pos[1] === 'string') {
878 if (pos[1].indexOf('%') !== -1) {
879 p = getInt(pos[1].split('%')[0]);
880 y = {'top': p / 100 * wh + off[1]};
881 } else {
882 if (pos[1] === 'top') y = {'top': 0 + off[1]};
883 else if (pos[1] === 'center') y = {'top': (wh - th) / 2 + off[1]};
884 else if (pos[1] === 'bottom') y = {'bottom': 0 + off[1]};
885
886 else y = {'top': getInt(pos[1]) + off[1]};
887 }
888 }
889
890 if (x.left) x.left = Math.round(x.left);
891 if (x.right) x.right = Math.round(x.right);
892
893 if (y.top) y.top = Math.round(y.top);
894 if (y.bottom) y.bottom = Math.round(y.bottom);
895
896 tar.css($.extend({}, x, y));
897 }
898 }
899
900 function pinterestShare(event) {
901 $('body').append('<script src="https://assets.pinterest.com/js/pinmarklet.js" type="text/javascript"></script>');
902 event.preventDefault();
903 }
904
905 function sharePopup(event) {
906 var url = event.data.url;
907 var params = event.data.params;
908 var winLeft;
909 var winParams;
910
911 if (params.left === 'center') {
912 winLeft = ($window.width() - params.width) / 2;
913 } else {
914 winLeft = params.left;
915 }
916
917 winParams = 'menubar=no,toolbar=no,location=no,scrollbars=no,status=no,resizable=yes,width=' + params.width +
918 ',height=' + params.height + ',top=' + params.top + ',left=' + winLeft;
919
920 window.open(url, 'sbShareWindow', winParams);
921
922 event.preventDefault();
923 }
924
925 function showBar() {
926 bar.removeClass('fm-hide');
927 bar.velocity('stop').velocity({'opacity': 1}, settings.barAnimate.show[0], settings.barAnimate.show[1]);
928 barVisible = true;
929 }
930
931 function hideBar() {
932 bar.velocity('stop').velocity({'opacity': 0}, settings.barAnimate.show[0], settings.barAnimate.show[1], function () {
933 bar.addClass('fm-hide');
934 });
935 barVisible = false;
936 }
937 });
938 }
939
940 function destroy() {
941 return $(this).each(function () {
942 var sidebar = $(this);
943 var bar, sbwindow;
944
945 if (sidebar.data('fm-built')) {
946 sidebar.data('fm-built', false);
947
948 bar = sidebar.children('.fm-bar');
949 sbwindow = sidebar.children('.fm-window');
950
951 bar.attr('class', 'fm-bar').removeAttr('style');
952 sbwindow.attr('class', 'fm-window');
953
954 destroyList(bar);
955
956 sbwindow.removeClass('fm-show');
957 sbwindow.children('.fm-shadow').off('click');
958 sbwindow.children('.fm-panel').removeClass('fm-show').removeAttr('style').each(destroyPanel);
959
960 $(window).off('resize.superSidebar scroll.superSidebar');
961
962 sidebar.removeClass('fm-ready');
963 }
964
965 function destroyList(list) {
966 list.children().each(function () {
967 if ($(this).hasClass('fm-sub')) destroySub(this);
968 else destroyButton(this);
969 });
970 }
971
972 function destroyButton(btn) {
973 var button = $(btn);
974 var link = button.find('a');
975 var label = link.children('.fm-label');
976
977 if (link.data('share')) link.removeAttr('href target');
978
979 link.children('.fm-hit').remove();
980
981 if (button.children('.fm-mask').length) link.unwrap();
982
983 label.removeAttr('style');
984
985 link.off('mouseenter mouseleave click');
986 }
987
988 function destroySub(sub) {
989 var sub = $(sub);
990 var list = sub.children('ul');
991
992 sub.removeClass('fm-side fm-circular fm-sub-space fm-posabs');
993
994 list.removeClass('fm-hide');
995 list.removeAttr('style');
996 list.children().removeAttr('style');
997
998 sub.children('.fm-subhit').remove();
999
1000 sub.off('mouseenter mouseleave');
1001 }
1002
1003 function destroyPanel() {
1004 var panel = $(this);
1005
1006 panel.find('.fm-close').off('click');
1007
1008 var form = panel.find('form');
1009 if (form.length) destroyForm(form);
1010 }
1011
1012 function destroyForm(form) {
1013 var fieldList = form.find('input, textarea');
1014
1015 form.find('.fm-submit').off('click');
1016 form.off('submit');
1017
1018 fieldList.removeClass('fm-formerror').off('focus');
1019 fieldList.each(function () {
1020 $(this).val('');
1021 });
1022
1023 form.find('.fm-status').attr('class', 'fm-status');
1024 }
1025 });
1026 }
1027
1028 function createSettings(options) {
1029 var settings = $.extend({}, defaults, options);
1030
1031 if (typeof settings.position === 'string') {
1032 settings.position = settings.position.split('-');
1033 }
1034 if (settings.position[0] === 'center') {
1035 settings.position[0] = defaults.position[0];
1036 warn('Bar horizontal position cannot be "center". Horizontal position reset to "left".');
1037 }
1038 if (!settings.position[1]) {
1039 settings.position[1] = defaults.position[1];
1040 }
1041
1042 if (settings.offset === 0 || settings.offset === false) {
1043 settings.offset = [0, 0];
1044 } else if (typeof settings.offset === 'string') {
1045 settings.offset = splitOffset(settings.offset);
1046 }
1047
1048 if (!options.buttonShape && options.shape) {
1049 settings.buttonShape = settings.shape;
1050 }
1051 if (settings.buttonShape !== 'square') {
1052 if (settings.buttonShape !== 'round' && settings.buttonShape !== 'rounded' && settings.buttonShape !==
1053 'rounded-out') {
1054 settings.buttonShape = 'square';
1055 }
1056 }
1057
1058 if (!options.buttonColor && options.color) {
1059 settings.buttonColor = settings.color;
1060 }
1061 if (settings.buttonColor === 'default') {
1062 settings.buttonColor = 'custom';
1063 }
1064
1065 if (!options.buttonOverColor && options.overColor) {
1066 settings.buttonOverColor = settings.overColor;
1067 }
1068 if (settings.buttonOverColor === 'default') {
1069 settings.buttonOverColor = 'custom';
1070 }
1071
1072 if (settings.labelColor === 'match') {
1073 settings.labelColor = settings.buttonOverColor;
1074 }
1075 if (settings.labelTextColor === 'match') {
1076 settings.labelTextColor = settings.iconOverColor;
1077 }
1078
1079 if (settings.labelEffect === 'slide') settings.labelEffect = 'slide-out';
1080 if (settings.labelEffect === 'slide-in-fade') settings.labelEffect = 'slide-in';
1081
1082 if (!options.labelAnimate && options.labelAnim) {
1083 settings.labelAnimate = settings.labelAnim;
1084 }
1085 if (settings.labelAnimate === 'default') {
1086 if (labelAnimateDefaults[settings.labelEffect]) {
1087 settings.labelAnimate = labelAnimateDefaults[settings.labelEffect];
1088 } else {
1089 settings.labelAnimate = labelAnimateDefaults[0];
1090 }
1091 }
1092 settings.labelAnimate = extendAnimateSetting(settings.labelAnimate);
1093
1094 if (settings.labelConnected) {
1095 if (settings.labelEffect === 'slide-in' || settings.labelEffect === 'slide-out-out' || settings.labelEffect ===
1096 'slide-in-in') {
1097 settings.labelConnected = false;
1098 warn('"labelConnected: true" incompatible with "labelEffect: ' + settings.labelEffect +
1099 '". "labelConnected" reset to false.');
1100 } else if (settings.labelSpace) {
1101 settings.labelSpace = false;
1102 warn('"labelSpace: true" incompatible with "labelConnected: true". "labelSpace" reset to false.');
1103 }
1104 }
1105
1106 if (typeof settings.subPosition === 'string') {
1107 settings.subPosition = [settings.subPosition];
1108 }
1109 if (settings.subPosition[0] === 'circular') {
1110 if (!settings.subPosition[1]) settings.subPosition[1] = defaults.subPosition[1];
1111 if (typeof settings.subPosition[2] === 'undefined') settings.subPosition[2] = defaults.subPosition[2];
1112 if (typeof settings.subPosition[3] === 'undefined') settings.subPosition[3] = defaults.subPosition[3];
1113
1114 if (settings.subSpace) settings.subSpace = false;
1115 }
1116
1117 if (!options.subAnimate && options.subAnim) {
1118 settings.subAnimate = settings.subAnim;
1119 }
1120 if (settings.subAnimate === 'default') settings.subAnimate = defaults.subAnimate;
1121
1122 if (typeof settings.subEffect === 'string') {
1123 settings.subEffect = [settings.subEffect];
1124 }
1125 if ((settings.subEffect[0] === 'linear-fade' || settings.subEffect[0] === 'linear-slide') &&
1126 !settings.subEffect[1]) {
1127 settings.subEffect[1] = defaults.subEffect[1];
1128 }
1129
1130 settings.subAnimate = extendAnimateSetting(settings.subAnimate);
1131
1132 if (typeof settings.windowPosition === 'string') {
1133 settings.windowPosition = settings.windowPosition.split('-');
1134 }
1135 if (!settings.windowPosition[1]) {
1136 settings.windowPosition[1] = defaults.windowPosition[1];
1137 }
1138
1139 if (settings.windowOffset === 0 || settings.windowOffset === false) {
1140 settings.windowOffset = [0, 0];
1141 } else if (typeof settings.windowOffset === 'string') {
1142 settings.windowOffset = splitOffset(settings.windowOffset);
1143 }
1144
1145 if (settings.windowCorners === 'match') {
1146 if (settings.buttonShape === 'round' || settings.buttonShape === 'rounded' || settings.buttonShape ===
1147 'rounded-out') {
1148 settings.windowCorners = 'round';
1149 }
1150 }
1151
1152 if (settings.windowColor === 'match') {
1153 settings.windowColor = settings.buttonColor;
1154 } else if (settings.windowColor === 'default') {
1155 settings.windowColor = 'custom';
1156 }
1157
1158 if (settings.barAnimate === 'default') {
1159 settings.barAnimate = defaults.barAnimate;
1160 }
1161
1162 settings.barAnimate = extendAnimateSetting(settings.barAnimate);
1163
1164 if (settings.hideUnder) {
1165 settings.hideUnderWidth = settings.hideUnder;
1166 }
1167
1168 return settings;
1169 }
1170
1171 function splitOffset(off) {
1172 off = off.split('-');
1173 off[0] = getInt(off[0]);
1174 if (off[1]) off[1] = getInt(off[1]);
1175 return off;
1176 }
1177
1178 function extendAnimateSetting(animate) {
1179 if (Object.prototype.toString.call(animate) === '[object Array]') {
1180 return {
1181 show: animate,
1182 hide: animate,
1183 };
1184 } else {
1185 return animate;
1186 }
1187 }
1188
1189 function warn(msg) {
1190 if (window.console) {
1191 console.log('(!) Float Menu: ' + msg);
1192 }
1193 }
1194
1195 function getInt(val) {
1196 return parseInt(val, 10);
1197 }
1198
1199 $('[data-btn-type]').on('click', function (event) {
1200 event.preventDefault();
1201
1202 let type = $(this).data('btn-type');
1203 switch (type) {
1204 case 'print':
1205 window.print();
1206 break;
1207 case 'scroll':
1208 let anchor = $(this).attr('href');
1209 $('html, body').animate({scrollTop: $(anchor).offset().top}, 777);
1210 break;
1211 case 'totop':
1212 $('body,html').animate({scrollTop: 0}, 777);
1213 break;
1214 case 'tobottom':
1215 $('html, body').animate({scrollTop: jQuery(document).height()}, 777);
1216 break;
1217 case 'goback':
1218 window.history.back();
1219 break;
1220 case 'goforward':
1221 window.history.forward();
1222 break;
1223 }
1224 });
1225
1226 $('[data-flm-track]').on('click', function (event) {
1227 const attr = $(this).data('flm-track');
1228 const lines = attr.split('|');
1229
1230 if (typeof window.gtag === 'function') {
1231 gtag('event', 'click', {
1232 'event_category': lines[0],
1233 'event_label': lines[1],
1234 'value': lines[2],
1235 });
1236 }
1237 });
1238
1239 $('[data-flm-share]').on('click', function (event) {
1240 event.preventDefault();
1241 let network = $(this).data('flm-share');
1242 let url = window.location.href;
1243 let title = encodeURIComponent(document.title);
1244 let shareUrl;
1245
1246 switch (network) {
1247 case 'facebook':
1248 shareUrl = 'https://www.facebook.com/sharer/sharer.php?u=' + url;
1249 break;
1250 case 'vk':
1251 shareUrl = 'http://vk.com/share.php?url=' + url;
1252 break;
1253 case 'twitter':
1254 shareUrl = 'https://twitter.com/share?url=' + url + '&text=' + title;
1255 break;
1256 case 'linkedin':
1257 shareUrl = 'https://www.linkedin.com/shareArticle?url=' + url + '&title=' + title;
1258 break;
1259 case 'odnoklassniki':
1260 shareUrl = 'http://ok.ru/dk?st.cmd=addShare&st._surl=' + url;
1261 break;
1262 case 'googleplus':
1263 shareUrl = 'https://plus.google.com/share?url=' + url;
1264 break;
1265 case 'pinterest':
1266 shareUrl = 'https://pinterest.com/pin/create/button/?url=' + url;
1267 break;
1268 case 'xing':
1269 shareUrl = 'https://www.xing.com/spi/shares/new?url=' + url;
1270 break;
1271 case 'myspace':
1272 shareUrl = 'https://myspace.com/post?u=' + url + '&t=' + title;
1273 break;
1274 case 'weibo':
1275 shareUrl = 'http://service.weibo.com/share/share.php?url=' + url + '&title=' + title;
1276 break;
1277 case 'buffer':
1278 shareUrl = 'https://buffer.com/add?text=' + title + '&url=' + url;
1279 break;
1280 case 'stumbleupon':
1281 shareUrl = 'http://www.stumbleupon.com/submit?url=' + url + '&title=' + title;
1282 break;
1283 case 'reddit':
1284 shareUrl = 'http://www.reddit.com/submit?url=' + url + '&title=' + title;
1285 break;
1286 case 'tumblr':
1287 shareUrl = 'https://www.tumblr.com/widgets/share/tool?canonicalUrl=' + url + '&title=' + title;
1288 break;
1289 case 'blogger':
1290 shareUrl = 'https://www.blogger.com/blog-this.g?u=' + url + '&n=' + title;
1291 break;
1292 case 'livejournal':
1293 shareUrl = 'http://www.livejournal.com/update.bml?subject=' + title + '&event=' + url;
1294 break;
1295 case 'pocket':
1296 shareUrl = 'https://getpocket.com/save?url=' + url;
1297 break;
1298 case 'telegram':
1299 shareUrl = 'https://telegram.me/share/url?url=' + url + '&text=' + title;
1300 break;
1301 case 'skype':
1302 shareUrl = 'https://web.skype.com/share?url=' + url;
1303 break;
1304 case 'email':
1305 shareUrl = 'mailto:?subject=' + title + '&body=' + url;
1306 break;
1307 case 'draugiem':
1308 shareUrl = 'https://www.draugiem.lv/say/ext/add.php?title=' + title + '&url=' + url;
1309 break;
1310 case 'whatsappsend':
1311 shareUrl = 'whatsapp://send?text=' + title + '%20%0A' + url;
1312 break;
1313 case 'whatsapp':
1314 shareUrl = 'https://api.whatsapp.com/send?text=' + title + '%20%0A' + url;
1315 break;
1316 case 'diaspora':
1317 shareUrl = 'https://share.diasporafoundation.org/?title=' + title + '&url=' + url;
1318 break;
1319 case 'digg':
1320 shareUrl = 'http://digg.com/submit?url=' + url;
1321 break;
1322 case 'douban':
1323 shareUrl = 'http://www.douban.com/recommend/?url=' + url + '&title=' + title;
1324 break;
1325 case 'evernote':
1326 shareUrl = 'http://www.evernote.com/clip.action?url=' + url + '&title=' + title;
1327 break;
1328 case 'flipboard':
1329 shareUrl = 'https://share.flipboard.com/bookmarklet/popout?v=2&title=' + title + '&url=' + url;
1330 break;
1331 case 'google-bookmarks':
1332 shareUrl = 'https://www.google.com/bookmarks/mark?op=edit&bkmk=' + url + '&title=' + title;
1333 break;
1334 case 'hacker-news':
1335 shareUrl = 'https://news.ycombinator.com/submitlink?u=' + url + '&t=' + title;
1336 break;
1337 case 'instapaper':
1338 shareUrl = 'http://www.instapaper.com/edit?url=' + url + '&title=' + title;
1339 break;
1340 case 'line':
1341 shareUrl = 'https://lineit.line.me/share/ui?url=' + url;
1342 break;
1343 case 'qzone':
1344 shareUrl = 'http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=' + url;
1345 break;
1346 case 'renren':
1347 shareUrl = 'http://widget.renren.com/dialog/share?resourceUrl=' + url + '&srcUrl=' + url + '&title=' + title;
1348 break;
1349 default:
1350 shareUrl = '';
1351 }
1352
1353 let popupWidth = 550;
1354 let popupHeight = 450;
1355 let topPosition = (screen.height - popupHeight) / 2;
1356 let leftPosition = (screen.width - popupWidth) / 2;
1357 let popup = 'width=' + popupWidth + ', height=' + popupHeight + ', top=' + topPosition + ', left=' + leftPosition +
1358 ', scrollbars=0, resizable=1, menubar=0, toolbar=0, status=0';
1359
1360 window.open(shareUrl, null, popup);
1361
1362 return true;
1363
1364 });
1365
1366
1367 }(jQuery));
1368
1369
1370 const flTranslate = document.querySelectorAll('[data-google-lang]');
1371 const flDefaultLang = document.documentElement.lang.substr(0, 2);
1372
1373 function flTranslateInit() {
1374
1375 let code = flTranslateGetCode();
1376
1377 if (code == flDefaultLang) {
1378 flTranslateClearCookie();
1379 }
1380
1381 new google.translate.TranslateElement({
1382 pageLanguage: flDefaultLang,
1383 });
1384
1385 flTranslate.forEach((el) => {
1386 el.addEventListener('click', (e) => {
1387 e.preventDefault();
1388 let lang = el.getAttribute('data-google-lang');
1389 flTranslateSetCookie(lang);
1390 window.location.reload();
1391 });
1392 });
1393
1394 }
1395
1396 function flTranslateGetCode() {
1397 let keyValue = document['cookie'].match('(^|;) ?googtrans=([^;]*)(;|$)');
1398 let cookieLang = keyValue ? keyValue[2].split('/')[2] : null;
1399 let lang = (cookieLang != undefined && cookieLang != 'null') ? cookieLang : flDefaultLang;
1400 return lang;
1401
1402 }
1403
1404 function flTranslateClearCookie() {
1405 document.cookie = 'googtrans=null';
1406 document.cookie = 'googtrans=null; domain=' + document.domain;
1407 }
1408
1409 function flTranslateSetCookie(code) {
1410 document.cookie = 'googtrans=/auto/' + code;
1411 document.cookie = 'googtrans=/auto/' + code + '; domain=' + document.domain;
1412 }
1413
1414
1415 document.addEventListener('DOMContentLoaded', function () {
1416 for (let key in window) {
1417 if (key.indexOf('FloatMenu_') >= 0) {
1418 const val = window[key];
1419 jQuery(val.selector).floatingMenu(val);
1420 }
1421 }
1422 });
1423
1424