1(function (Drupal) { 2 3 /** 4 * Command to attach data using jQuery's data API. 5 * 6 * @param {Drupal.Ajax} [ajax] 7 * {@link Drupal.Ajax} object created by {@link Drupal.ajax}. 8 * @param {object} response 9 * The response from the Ajax request. 10 * @param {string} response.event_name 11 * The event name 12 * @param {object} response.data 13 * The value of the event. 14 */ 15 Drupal.AjaxCommands.prototype.gtagEvent = function (ajax, response) { 16 gtag('event', response.event_name, response.data) 17 } 18})(Drupal); 19; 20function ctSetCookie(cookies) 21{ 22 23 let useCookies, useAltCookies 24 25 if ('undefined' !== typeof ct_use_cookies) { 26 useCookies = ct_use_cookies; 27 } else { 28 useCookies = false; 29 } 30 31 if ('undefined' !== typeof ct_use_alt_cookies) { 32 useAltCookies = ct_use_alt_cookies; 33 } else { 34 useAltCookies = false 35 } 36 37 if (useCookies) { 38 if (useAltCookies && useAltCookies === 1) { 39 let xhr = new XMLHttpRequest(); 40 41 let json = JSON.stringify(cookies); 42 43 xhr.open("POST", '/admin/config/cleantalk/set_alt_cookies') 44 xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8'); 45 46 xhr.send(json); 47 } else { 48 cookies.forEach( 49 function (e) { 50 let ctSecure = location.protocol === "https:" ? "; secure" : ""; 51 document.cookie = e.name + "=" + encodeURIComponent(e.value) + "; path=/; expires=0; samesite=lax" + ctSecure; 52 } 53 ) 54 } 55 } 56} 57; 58var d = new Date(), 59 ctTimeMs = new Date().getTime(), 60 ctMouseEventTimerFlag = true, //Reading interval flag 61 ctMouseData = "[", 62 ctMouseDataCounter = 0, 63 ctScrollCollected = false; 64 65ctSetCookie( 66 [ 67 { 68 'name' : 'ct_check_js', 69 'value' : ct_check_js_val 70 }, 71 { 72 'name' : 'ct_ps_timestamp', 73 'value' : Math.floor(new Date().getTime()/1000) 74 }, 75 { 76 'name' : 'ct_fkp_timestamp', 77 'value' : '0' 78 }, 79 { 80 'name' : 'ct_pointer_data', 81 'value' : '0' 82 }, 83 { 84 'name' : 'ct_timezone', 85 'value' : d.getTimezoneOffset()/60*(-1) 86 }, 87 { 88 'name' : 'apbct_antibot', 89 'value' : drupal_ac_antibot_cookie_value 90 }, 91 { 92 'name' : 'ct_has_scrolled', 93 'value' : false 94 } 95 ] 96); 97 98//Reading interval 99 100var ctMouseReadInterval = setInterval( 101 function () { 102 ctMouseEventTimerFlag = true; 103 }, 150 104); 105 106//Writting interval 107 108var ctMouseWriteDataInterval = setInterval( 109 function () { 110 if(typeof ct_use_alt_cookies !== "undefined" && ct_use_alt_cookies === 1) { 111 return; 112 } 113 var ctMouseDataToSend = ctMouseData.slice(0,-1).concat("]"); 114 ctSetCookie( 115 [ 116 { 117 'name' : 'ct_pointer_data', 118 'value' : ctMouseDataToSend 119 } 120 ] 121 ); 122 }, 1200 123); 124 125//Stop observing function 126 127function ctMouseStopData() 128{ 129 if(typeof window.addEventListener == "function") { 130 window.removeEventListener("mousemove", ctFunctionMouseMove); 131 } else { 132 window.detachEvent("onmousemove", ctFunctionMouseMove); 133 } 134 clearInterval(ctMouseReadInterval); 135 clearInterval(ctMouseWriteDataInterval); 136} 137 138//Logging mouse position each 300 ms 139 140var ctFunctionMouseMove = function output(event) 141{ 142 if (ctMouseEventTimerFlag == true) { 143 var mouseDate = new Date(); 144 ctMouseData += "[" + Math.round(event.pageY) + "," + Math.round(event.pageX) + "," + Math.round(mouseDate.getTime() - ctTimeMs) + "],"; 145 ctMouseDataCounter++; 146 ctMouseEventTimerFlag = false; 147 if(ctMouseDataCounter >= 100) { 148 ctMouseStopData(); 149 } 150 } 151}; 152 153/** 154 * Set scrolling cookie 155 */ 156function ctSetHasScrolled() 157{ 158 if(! ctScrollCollected ) { 159 ctSetCookie( 160 [ 161 { 162 'name' : 'ct_has_scrolled', 163 'value' : true 164 } 165 ] 166 ); 167 ctScrollCollected = true; 168 } 169} 170 171//Stop key listening function 172 173function ctKeyStopStopListening() 174{ 175 if (typeof window.addEventListener == "function") { 176 window.removeEventListener("mousedown", ctFunctionFirstKey); 177 window.removeEventListener("keydown", ctFunctionFirstKey); 178 } 179 else { 180 window.detachEvent("mousedown", ctFunctionFirstKey); 181 window.detachEvent("keydown", ctFunctionFirstKey); 182 } 183} 184 185//Writing first key press timestamp 186 187var ctFunctionFirstKey = function output(event) 188{ 189 var KeyTimestamp = Math.floor(new Date().getTime()/1000);
190 ctSetCookie( 191 [ 192 { 193 'name' : 'ct_fkp_timestamp', 194 'value' : KeyTimestamp 195 } 196 ] 197 ); 198 ctKeyStopStopListening(); 199}; 200 201if (typeof window.addEventListener == "function") { 202 window.addEventListener("mousemove", ctFunctionMouseMove); 203 window.addEventListener("mousedown", ctFunctionFirstKey); 204 window.addEventListener("keydown", ctFunctionFirstKey); 205 window.addEventListener("scroll", ctSetHasScrolled); 206} 207else { 208 window.attachEvent("onmousemove", ctFunctionMouseMove); 209 window.attachEvent("mousedown", ctFunctionFirstKey); 210 window.attachEvent("keydown", ctFunctionFirstKey); 211 window.attachEvent("scroll", ctSetHasScrolled); 212} 213 214function apbct_collect_visible_fields( form ) 215{ 216 217 // Get only fields 218 var inputs = [], 219 inputs_visible = '', 220 inputs_visible_count = 0, 221 inputs_invisible = '', 222 inputs_invisible_count = 0, 223 inputs_with_duplicate_names = []; 224 225 for(var key in form.elements){ 226 if(!isNaN(+key)) { 227 inputs[key] = form.elements[key]; 228 } 229 } 230 231 // Filter fields 232 inputs = inputs.filter( 233 function (elem) { 234 235 // Filter already added fields 236 if(inputs_with_duplicate_names.indexOf(elem.getAttribute('name')) !== -1 ) { 237 return false; 238 } 239 // Filter inputs with same names for type == radio 240 if(-1 !== ['radio', 'checkbox'].indexOf(elem.getAttribute("type"))) { 241 inputs_with_duplicate_names.push(elem.getAttribute('name')); 242 return false; 243 } 244 return true; 245 } 246 ); 247 248 // Visible fields 249 inputs.forEach( 250 function (elem, i, elements) { 251 // Unnecessary fields 252 if(elem.getAttribute("type") === "submit" // type == submit 253 || elem.getAttribute('name') === null 254 || elem.getAttribute('name') === 'ct_checkjs' 255 ) { 256 return; 257 } 258 // Invisible fields 259 if(getComputedStyle(elem).display === "none" // hidden 260 || getComputedStyle(elem).visibility === "hidden" // hidden 261 || getComputedStyle(elem).opacity === "0" // hidden 262 || elem.getAttribute("type") === "hidden" // type == hidden 263 ) { 264 if(elem.classList.contains("wp-editor-area") ) { 265 inputs_visible += " " + elem.getAttribute("name"); 266 inputs_visible_count++; 267 } else { 268 inputs_invisible += " " + elem.getAttribute("name"); 269 inputs_invisible_count++; 270 } 271 } 272 // Visible fields 273 else { 274 inputs_visible += " " + elem.getAttribute("name"); 275 inputs_visible_count++; 276 } 277 278 } 279 ); 280 281 inputs_invisible = inputs_invisible.trim(); 282 inputs_visible = inputs_visible.trim(); 283 284 return { 285 visible_fields : inputs_visible, 286 visible_fields_count : inputs_visible_count, 287 invisible_fields : inputs_invisible, 288 invisible_fields_count : inputs_invisible_count, 289 } 290 291} 292 293function apbct_visible_fields_set_cookie( visible_fields_collection ) 294{ 295 296 var collection = typeof visible_fields_collection === 'object' && visible_fields_collection !== null ? visible_fields_collection : {}; 297 298 ctSetCookie( 299 [ 300 { 301 'name' : 'apbct_visible_fields', 302 'value' : JSON.stringify(collection) 303 } 304 ] 305 ) 306} 307; 308/** 309 * @file 310 * Bootstrap Popovers. 311 */ 312 313var Drupal = Drupal || {}; 314 315(function ($, Drupal, Bootstrap) { 316 "use strict"; 317 318 var $document = $(document); 319 320 /** 321 * Extend the Bootstrap Popover plugin constructor class. 322 */ 323 Bootstrap.extendPlugin('popover', function (settings) { 324 return { 325 DEFAULTS: { 326 animation: !!settings.popover_animation, 327 autoClose: !!settings.popover_auto_close, 328 enabled: settings.popover_enabled, 329 html: !!settings.popover_html, 330 placement: settings.popover_placement, 331 selector: settings.popover_selector, 332 trigger: settings.popover_trigger, 333 title: settings.popover_title, 334 content: settings.popover_content, 335 delay: parseInt(settings.popover_delay, 10), 336 container: settings.popover_container 337 } 338 }; 339 }); 340 341 /** 342 * Bootstrap Popovers. 343 * 344 * @todo This should really be properly delegated if selector option is set. 345 */ 346 Drupal.behaviors.bootstrapPopovers = { 347 $activePopover: null, 348 attach: function (context) { 349 // Immediately return if popovers are not available. 350 if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) { 351 return; 352 } 353 354 var _this = this; 355 356 $document 357 .on('show.bs.popover', '[data-toggle=popover]', function () { 358 var $trigger = $(this); 359 var popover = $trigger.data('bs.popover'); 360 361 // Only keep track of clicked triggers that we're manually handling. 362 if (popover.options.originalTrigger === 'click') { 363 if (_this.$activePopover && _this.getOption('autoClose') && !_this.$activePopover.is($trigger)) { 364 _this.$activePopover.popover('hide'); 365 } 366 _this.$activePopover = $trigger; 367 } 368 }) 369 // Unfortunately, :focusable is only made available when using jQuery 370 // UI. While this would be the most semantic pseudo selector to use 371 // here, jQuery UI may not always be loaded. Instead, just use :visible 372 // here as this just needs some sort of selector here. This activates 373 // delegate binding to elements in jQuery so it can work it's bubbling 374 // focus magic since elements don't really propagate their focus events. 375 // @see https://www.drupal.org/project/bootstrap/issues/3013236 376 .on('focus.bs.popover', ':visible', function (e) { 377 var $target = $(e.target); 378 if (_this.$activePopover && _this.getOption('autoClose') && !_this.$activePopover.is($target) && !$target.closest('.popover.in')[0]) { 379 _this.$activePopover.popover('hide'); 380 _this.$activePopover = null; 381 } 382 }) 383 .on('click.bs.popover', function (e) { 384 var $target = $(e.target); 385 if (_this.$activePopover && _this.getOption('autoClose') && !$target.is('[data-toggle=popover]') && !$target.closest('.popover.in')[0]) { 386 _this.$activePopover.popover('hide'); 387 _this.$activePopover = null; 388 } 389 }) 390 .on('keyup.bs.popover', function (e) { 391 if (_this.$activePopover && _this.getOption('autoClose') && e.which === 27) { 392 _this.$activePopover.popover('hide'); 393 _this.$activePopover = null; 394 } 395 }) 396 ; 397 398 var elements = $(context).find('[data-toggle=popover]').toArray(); 399 for (var i = 0; i < elements.length; i++) { 400 var $element = $(elements[i]); 401 var options = $.extend({}, $.fn.popover.Constructor.DEFAULTS, $element.data()); 402 403 // Store the original trigger. 404 options.originalTrigger = options.trigger; 405 406 // If the trigger is "click", then we'll handle it manually here. 407 if (options.trigger === 'click') { 408 options.trigger = 'manual'; 409 } 410 411 // Retrieve content from a target element. 412 var target = options.target || $element.is('a[href^="#"]') && $element.attr('href'); 413 var $target = $document.find(target).clone(); 414 if (!options.content && $target[0]) { 415 $target.removeClass('visually-hidden hidden').removeAttr('aria-hidden'); 416 options.content = $target.wrap('<div/>').parent()[options.html ? 'html' : 'text']() || ''; 417 } 418 419 // Initialize the popover. 420 $element.popover(options); 421 422 // Handle clicks manually. 423 if (options.originalTrigger === 'click') { 424 // To ensure the element is bound multiple times, remove any 425 // previously set event handler before adding another one. 426 $element 427 .off('click.drupal.bootstrap.popover') 428 .on('click.drupal.bootstrap.popover', function (e) { 429 $(this).popover('toggle'); 430 e.preventDefault(); 431 e.stopPropagation(); 432 }) 433 ; 434 } 435 } 436 }, 437 detach: function (context) { 438 // Immediately return if popovers are not available. 439 if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) { 440 return; 441 } 442 443 // Destroy all popovers. 444 $(context).find('[data-toggle="popover"]') 445 .off('click.drupal.bootstrap.popover') 446 .popover('destroy') 447 ; 448 }, 449 getOption: function(name, defaultValue, element) { 450 var $element = element ? $(element) : this.$activePopover; 451 var options = $.extend(true, {}, $.fn.popover.Constructor.DEFAULTS, ($element && $element.data('bs.popover') || {}).options); 452 if (options[name] !== void 0) { 453 return options[name]; 454 } 455 return defaultValue !== void 0 ? defaultValue : void 0; 456 } 457 }; 458 459})(window.jQuery, window.Drupal, window.Drupal.bootstrap); 460; 461/** 462 * @file 463 * Bootstrap Tooltips. 464 */ 465 466var Drupal = Drupal || {}; 467 468(function ($, Drupal, Bootstrap) { 469 "use strict"; 470 471 /** 472 * Extend the Bootstrap Tooltip plugin constructor class. 473 */ 474 Bootstrap.extendPlugin('tooltip', function (settings) { 475 return { 476 DEFAULTS: { 477 animation: !!settings.tooltip_animation, 478 enabled: settings.tooltip_enabled, 479 html: !!settings.tooltip_html, 480 placement: settings.tooltip_placement, 481 selector: settings.tooltip_selector, 482 trigger: settings.tooltip_trigger, 483 delay: parseInt(settings.tooltip_delay, 10), 484 container: settings.tooltip_container 485 } 486 }; 487 }); 488 489 /** 490 * Bootstrap Tooltips. 491 * 492 * @todo This should really be properly delegated if selector option is set. 493 */ 494 Drupal.behaviors.bootstrapTooltips = { 495 attach: function (context) { 496 // Immediately return if tooltips are not available. 497 if (!$.fn.tooltip || !$.fn.tooltip.Constructor.DEFAULTS.enabled) { 498 return; 499 } 500 501 var elements = $(context).find('[data-toggle="tooltip"]').toArray(); 502 for (var i = 0; i < elements.length; i++) { 503 var $element = $(elements[i]); 504 var options = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, $element.data()); 505 $element.tooltip(options); 506 } 507 }, 508 detach: function (context) { 509 // Immediately return if tooltips are not available. 510 if (!$.fn.tooltip || !$.fn.tooltip.Constructor.DEFAULTS.enabled) { 511 return; 512 } 513 514 // Destroy all tooltips. 515 $(context).find('[data-toggle="tooltip"]').tooltip('destroy'); 516 } 517 }; 518 519})(window.jQuery, window.Drupal, window.Drupal.bootstrap); 520; 521(function ($, undefined) { 522 523 'use strict'; 524 525 /** 526 Â Â * Provides enhanced functionality for Pay Portal Paragraphs admin. 527 Â Â * 528 Â Â * @type {Drupal~behavior} 529 Â Â * 530 Â Â * @prop {Drupal~behaviorAttach} attach 531 Â Â *Â Â Adds administrative effects and enhancements for the various 532 * Paragraphs components that act as the base for this module. 533 Â Â */ 534 Drupal.behaviors.payportal_admin = { 535 attach: function (context, settings) { 536 537 var 538 $settings = settings.payportal_admin, 539 $keys = Object.keys($settings) 540 ; 541 542 // The top level object literal is keyed by the deltas for 543 // each Pay Portal paragraph instance. 544 for (var i = 0, c = $keys.length; i < c; i++) { 545 var $delta = $keys[i]; 546 547 // If an Add More set of elements is present for this delta... 548 if ($settings[$delta]['payprovider_add_more'] !== undefined) { 549 550 // Update Add More button text based on the value 551 // selected in the Add More select. 552 $($settings[$delta]['payprovider_add_more']['select']).each(function () { 553 var $this = this; 554 555 // Add event handler only once per element per behaviors attachment. 556 $($this).once('payportal_admin_' + $delta).each(function () { 557 558 // Update button text when pay provider select option changes. 559 $($this).on('change', function () { 560 var $pattern = $settings[$delta]['payprovider_add_more']['pattern']; 561 var $text = Drupal.t($pattern, {'@pp': this[this.selectedIndex].innerHTML}); 562 $($settings[$delta]['payprovider_add_more']['button'], context) 563 .prop('value', $text) 564 .text($text); 565 }); 566 }); 567 }); 568 } 569 } 570 } 571 }; 572})(jQuery);; 573/** 574 * @file 575 * Defines Javascript behaviors for MegaMenu frontend. 576 */ 577 578(function ($, Drupal, drupalSettings) { 579 "use strict"; 580 581 Drupal.TBMegaMenu = Drupal.TBMegaMenu || {}; 582 583 Drupal.TBMegaMenu.oldWindowWidth = 0; 584 Drupal.TBMegaMenu.displayedMenuMobile = false;
585 Drupal.TBMegaMenu.supportedScreens = [980]; 586 Drupal.TBMegaMenu.focusableElements = 'a:not([disabled]), button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), details:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])'; 587 Drupal.TBMegaMenu.menuResponsive = function () { 588 var windowWidth = window.innerWidth ? window.innerWidth : $(window).width(); 589 var navCollapse = $('.tb-megamenu').children('.nav-collapse'); 590 if (windowWidth < Drupal.TBMegaMenu.supportedScreens[0]) { 591 navCollapse.addClass('collapse'); 592 if (Drupal.TBMegaMenu.displayedMenuMobile) { 593 navCollapse.css({height: 'auto', overflow: 'visible'}); 594 } 595 else { 596 navCollapse.css({height: 0, overflow: 'hidden'}); 597 } 598 } 599 else { 600 // If width of window is greater than 980 (supported screen). 601 navCollapse.removeClass('collapse'); 602 if (navCollapse.height() <= 0) { 603 navCollapse.css({height: 'auto', overflow: 'visible'}); 604 } 605 } 606 }; 607 608 Drupal.TBMegaMenu.focusNextPrevElement = function (direction) { 609 // Add all the elements we want to include in our selection 610 var $current = $(document.activeElement); 611 612 if ($current.length) { 613 var $focusable = $(Drupal.TBMegaMenu.focusableElements).filter(function () { 614 var $this = $(this); 615 return $this.closest('.tb-megamenu-subnav').length === 0 && $this.is(':visible'); 616 }) 617 618 var index = $focusable.index($current); 619 if (index > -1) { 620 if (direction === 'next') { 621 var nextElement = $focusable[index + 1] || $focusable[0]; 622 } 623 else { 624 var nextElement = $focusable[index - 1] || $focusable[0]; 625 } 626 627 nextElement.focus(); 628 } 629 } 630 } 631 632 633 Drupal.behaviors.tbMegaMenuAction = { 634 attach: function (context, settings) { 635 636 $('.tb-megamenu', context).once('tb-megamenu').each(function () { 637 638 /* Keyboard Control Setup */ 639 // Semi-Global Variables 640 var navParent = document.querySelector('.tb-megamenu'), 641 linkArray = new Array(), 642 curPos = new Array(-1,-1,-1); 643 644 // Each Top-Level Link 645 $(this).find('.level-1').children('a, span').not('.mobile-only').each(function (i, toplink) { 646 linkArray[i] = new Array(); 647 648 // Add Link to Array 649 linkArray[i][-1] = toplink; 650 651 // Determine Coordinates 652 $(toplink).data({ coordinate: [i, -1] }); 653 654 // Each Column 655 $(toplink).next().children().children().children('.mega-col-nav').each(function (j, column) { 656 // Only add to the linkArray if menu items exist. 657 // TODO - this does not allow for tabbing to links in blocks, only menu item links. 658 if ($(column).find(Drupal.TBMegaMenu.focusableElements).length > 0) { 659 660 linkArray[i][j] = new Array(); 661 662 // Each Link 663 $(column).find(Drupal.TBMegaMenu.focusableElements).each(function (k, sublink) { 664 665 // Add Link to Array 666 linkArray[i][j][k] = sublink; 667 668 // Determine Coordinates 669 $(sublink).data({ coordinate: [i, j, k] }); 670 }); // each link 671 } 672 673 }); // each column 674 675 }); // each top-level link 676 677 // Update Position on Focus 678 $(this).find(Drupal.TBMegaMenu.focusableElements).focus(function () { 679 curPos = $(this).data('coordinate'); 680 }); 681 682 // Key Pressed 683 function keydownEvent(k) { 684 // Determine Key 685 switch(k.keyCode) { 686 687 // TAB 688 case 9: 689 k.preventDefault(); 690 nav_tab(k); 691 break; 692 693 // RETURN 694 case 13: 695 nav_open_link(); 696 break; 697 698 // ESC 699 case 27: 700 nav_esc(); 701 break; 702 703 // LEFT 704 case 37: 705 k.preventDefault(); 706 nav_left(); 707 break; 708 709 // UP 710 case 38: 711 k.preventDefault(); 712 nav_up(); 713 break; 714 715 // RIGHT 716 case 39: 717 k.preventDefault(); 718 nav_right(); 719 break; 720 721 // DOWN 722 case 40: 723 k.preventDefault(); 724 nav_down(); 725 break; 726 727 // HOME 728 case 36: 729 nav_home(); 730 break; 731 732 // END 733 case 35: 734 nav_end(); 735 break; 736 737 // Else 738 default:
739 // Do nothing 740 741 } // determine key 742 } // keydownEvent 743 744 /* Keypress Functions */ 745 // Tab 746 function nav_tab(k) { 747 if (nav_is_toplink()) { 748 if (k.shiftKey) { 749 nav_prev_toplink(); 750 } 751 else { 752 nav_next_toplink(); 753 } 754 } 755 else { 756 if (k.shiftKey) { 757 nav_up(); 758 } 759 else { 760 nav_down(); 761 } 762 } 763 } 764 765 // Open Link 766 function nav_open_link() { 767 linkArray[curPos[0]][curPos[1]][curPos[2]].click(); 768 } 769 770 // Escape 771 function nav_esc() { 772 nav_close_megamenu(); 773 } 774 775 // Left 776 function nav_left() { 777 if (nav_is_toplink()) { 778 nav_prev_toplink(); 779 } 780 else { 781 nav_prev_column(); 782 } 783 } 784 785 // Right 786 function nav_right() { 787 if (nav_is_toplink()) { 788 nav_next_toplink(); 789 } 790 else { 791 nav_next_column(); 792 } 793 } 794 795 // Up 796 function nav_up() { 797 if (nav_is_toplink()) { 798 nav_prev_toplink(); 799 } 800 else { 801 if (linkArray[curPos[0]][curPos[1]][curPos[2] - 1]) { 802 // If the previous link in the array is hidden (ie, it's in a 803 // submenu that is not currently expanded), then skip to the next 804 // item in the array until we find one that's visible. 805 if ($(linkArray[curPos[0]][curPos[1]][curPos[2] - 1]).is(':visible')) { 806 linkArray[curPos[0]][curPos[1]][curPos[2] - 1].focus(); 807 } 808 else { 809 curPos = [curPos[0], curPos[1], curPos[2] - 1]; 810 nav_up(); 811 } 812 } 813 else { 814 nav_prev_column(); 815 } 816 } 817 } 818 819 // Down 820 function nav_down() { 821 if (nav_is_toplink()) { 822 nav_next_column(); 823 } 824 else { 825 if (linkArray[curPos[0]][curPos[1]][curPos[2] + 1]) { 826 linkArray[curPos[0]][curPos[1]][curPos[2] + 1].focus(); 827 } 828 else { 829 nav_next_column(); 830 } 831 } 832 } 833 834 // Home Button 835 function nav_home() { 836 if (nav_is_toplink()) { 837 linkArray[0][-1].focus(); 838 } 839 else { 840 linkArray[curPos[0]][0][0].focus(); 841 } 842 } 843 844 // End Button 845 function nav_end() { 846 if (nav_is_toplink()) { 847 linkArray.slice(-1)[0][-1].focus(); 848 } 849 else { 850 linkArray[curPos[0]].slice(-1)[0].slice(-1)[0].focus(); 851 } 852 } 853 854 /* Helper Functions */ 855 // Determine Link Level 856 function nav_is_toplink() { 857 return (curPos[1] < 0); 858 } 859 860 // Close Mega Menu 861 function nav_close_megamenu() { 862 $('.tb-megamenu .open').removeClass('open'); 863 ariaCheck(); 864 } 865 866 // Next Toplink 867 function nav_next_toplink() { 868 if (linkArray[curPos[0] + 1]) { 869 linkArray[curPos[0] + 1][-1].focus(); 870 } 871 else { 872 nav_close_megamenu(); 873 874 // Focus on the next element. 875 Drupal.TBMegaMenu.focusNextPrevElement('next'); 876 } 877 } 878 879 // Previous Toplink 880 function nav_prev_toplink() { 881 if (linkArray[curPos[0] - 1]) { 882 linkArray[curPos[0] - 1][-1].focus(); 883 } 884 else { 885 // Focus on the previous element. 886 Drupal.TBMegaMenu.focusNextPrevElement('prev'); 887 } 888 } 889 890 // Previous Column 891 function nav_prev_column() { 892 if (linkArray[curPos[0]][curPos[1] - 1][0]) { 893 linkArray[curPos[0]][curPos[1] - 1][0].focus(); 894 } 895 else { 896 nav_parent_toplink(); 897 } 898 } 899 900 // Next Column 901 function nav_next_column() { 902 if (linkArray[curPos[0]][curPos[1] + 1]) { 903 linkArray[curPos[0]][curPos[1] + 1][0].focus(); 904 } 905 else { 906 nav_parent_toplink(); 907 } 908 } 909 910 // Go to Parent Toplink 911 function nav_parent_toplink() { 912 linkArray[curPos[0]][-1].focus(); 913 } 914 915 var ariaCheck = function () { 916 $("li.tb-megamenu-item", this).each(function () { 917 if ($(this).is('.mega-group')) { 918 // Mega menu item has mega class (it's a true mega menu) 919 if (!$(this).parents().is('.open')) { 920 // Mega menu item has mega class and its ancestor is closed, so apply appropriate ARIA attributes 921 $(this).children().attr('aria-expanded', 'false'); 922 } 923 else if ($(this).parents().is('.open')) { 924 // Mega menu item has mega class and its ancestor is o
924pen, so apply appropriate ARIA attributes 925 $(this).children().attr('aria-expanded', 'true'); 926 } 927 } 928 else if ($(this).is('.dropdown') || $(this).is('.dropdown-submenu')) { 929 // Mega menu item has dropdown (it's a flyout menu) 930 if (!$(this).is('.open')) { 931 // Mega menu item has dropdown class and is closed, so apply appropriate ARIA attributes 932 $(this).children().attr('aria-expanded', 'false'); 933 } 934 else if ($(this).is('.open')) { 935 // Mega menu item has dropdown class and is open, so apply appropriate ARIA attributes 936 $(this).children().attr('aria-expanded', 'true'); 937 } 938 } 939 else { 940 // Mega menu item is neither a mega or dropdown class, so remove ARIA attributes (it doesn't have children) 941 $(this).children().removeAttr('aria-expanded'); 942 } 943 }); 944 }; 945 946 var showMenu = function ($subMenu, mm_timeout) { 947 if ($subMenu.hasClass('mega')) { 948 $subMenu.addClass('animating'); 949 clearTimeout($subMenu.data('animatingTimeout')); 950 $subMenu.data('animatingTimeout', setTimeout(function () { 951 $subMenu.removeClass('animating') 952 }, mm_timeout)); 953 clearTimeout($subMenu.data('hoverTimeout')); 954 $subMenu.data('hoverTimeout', setTimeout(function () { 955 $subMenu.addClass('open'); 956 ariaCheck(); 957 }, 100)); 958 } 959 else { 960 clearTimeout($subMenu.data('hoverTimeout')); 961 $subMenu.data('hoverTimeout', 962 setTimeout(function () { 963 $subMenu.addClass('open'); 964 ariaCheck(); 965 }, 100)); 966 } 967 }; 968 969 var hideMenu = function ($subMenu, mm_timeout) { 970 $subMenu.children('.dropdown-toggle').attr('aria-expanded', 'false'); 971 if ($subMenu.hasClass('mega')) { 972 $subMenu.addClass('animating'); 973 clearTimeout($subMenu.data('animatingTimeout')); 974 $subMenu.data('animatingTimeout', setTimeout(function () { 975 $subMenu.removeClass('animating') 976 }, mm_timeout)); 977 clearTimeout($subMenu.data('hoverTimeout')); 978 $subMenu.data('hoverTimeout', setTimeout(function () { 979 $subMenu.removeClass('open'); 980 ariaCheck(); 981 }, 100)); 982 } 983 else { 984 clearTimeout($subMenu.data('hoverTimeout')); 985 $subMenu.data('hoverTimeout', setTimeout(function () { 986 $subMenu.removeClass('open'); 987 ariaCheck(); 988 }, 100)); 989 } 990 }; 991 992 $('.tb-megamenu-button', this).click(function () { 993 if (parseInt($(this).parent().children('.nav-collapse').height())) { 994 $(this).parent().children('.nav-collapse').css({height: 0, overflow: 'hidden'}); 995 Drupal.TBMegaMenu.displayedMenuMobile = false; 996 } 997 else { 998 $(this).parent().children('.nav-collapse').css({height: 'auto', overflow: 'visible'}); 999 Drupal.TBMegaMenu.displayedMenuMobile = true; 1000 } 1001 }); 1002 1003 var isTouch = window.matchMedia('(pointer: coarse)').matches; 1004 1005 if (!isTouch) { 1006 var mm_duration = 0; 1007 1008 $('.tb-megamenu', context).each(function () { 1009 if ($(this).data('duration')) { 1010 mm_duration = $(this).data('duration'); 1011 } 1012 }); 1013 1014 var mm_timeout = mm_duration ? 100 + mm_duration : 500; 1015 $('.nav > li, li.mega', context).bind('mouseenter', function (event) { 1016 showMenu($(this), mm_timeout); 1017 }); 1018 1019 $('.nav > li > .dropdown-toggle, li.mega > .dropdown-toggle', context).bind('focus', function (event) { 1020 var $this = $(this); 1021 var $subMenu = $this.closest('li'); 1022 showMenu($subMenu, mm_timeout); 1023 // If the focus moves outside of the subMenu, close it. 1024 $(document).bind('focusin', function (event) { 1025 if ($subMenu.has(event.target).length) { 1026 return; 1027 } 1028 $(document).unbind(event); 1029 hideMenu($subMenu, mm_timeout); 1030 }); 1031 }); 1032 1033 $('.nav > li, li.mega', context).bind('mouseleave', function (event) { 1034 hideMenu($(this), mm_timeout); 1035 }); 1036 1037 /** 1038 * Allow tabbing by appending the open class. 1039 * Works in tandem with CSS changes that utilize opacity rather than 1040 * display none 1041 */ 1042 // If the selected anchor is not in the TB Megamenu, remove all "open" 1043 // class occurrences 1044 $('a, span').focus(function (event) { 1045 if (!$(this).parent().hasClass('tb-megamenu-item') && !$(this).parents('.tb-megamenu-block').length) {
1046 nav_close_megamenu(); 1047 } 1048 }); 1049 1050 $('.nav > li > a, li.mega > a').focus(function (event) { 1051 // Remove all occurrences of "open" from other menu trees 1052 var siblings = $(this).parents('.tb-megamenu-item').siblings(); 1053 // var siblings = $(this).closest('.tb-megamenu-item.level-1').siblings(); 1054 $.each(siblings, function (i, v) { 1055 var cousins = $(v).find('.open'); 1056 $.each(cousins, function (index, value) { 1057 $(value).removeClass('open'); 1058 ariaCheck($(this)); 1059 }); 1060 $(v).removeClass('open'); 1061 ariaCheck(); 1062 }); 1063 // Open the submenu if the selected item has one 1064 if ($(this).next(".tb-megamenu-submenu").length > 0) { 1065 if (!$(this).parent().hasClass("open")) { 1066 $(this).parent().addClass("open"); 1067 } 1068 } 1069 // If the anchor's top-level parent is not open, open it 1070 if (!$(this).closest('.tb-megamenu-item.dropdown').hasClass('open') && $(this).closest('.tb-megamenu-item.dropdown').find('.tb-megamenu-submenu').length > 0) { 1071 $(this).closest('.tb-megamenu-item.dropdown').addClass('open'); 1072 ariaCheck(); 1073 } 1074 // If anchor's parent submenus are not open, open them 1075 var parents = $(this).parents('.tb-megamenu-item.dropdown-submenu'); 1076 $.each(parents, function (i, v) { 1077 if (!$(v).hasClass('open')) { 1078 $(v).addClass('open'); 1079 ariaCheck(); 1080 } 1081 }); 1082 }); 1083 } 1084 1085 // Define actions for touch devices. 1086 var createTouchMenu = function (items) { 1087 items.children("a, span").each(function () { 1088 var $item = $(this); 1089 var tbitem = $(this).parent(); 1090 1091 $item.click(function (event) { 1092 // If the menu link has already been clicked once... 1093 if ($item.hasClass("tb-megamenu-clicked")) { 1094 var $uri = $item.attr("href"); 1095 1096 // If the menu link has a URI, go to the link. 1097 // <nolink> menu items will not have a URI. 1098 if ($uri) { 1099 window.location.href = $uri; 1100 } 1101 else { 1102 $item.removeClass("tb-megamenu-clicked"); 1103 hideMenu(tbitem, mm_timeout); 1104 } 1105 } 1106 else { 1107 event.preventDefault(); 1108 1109 // Hide any already open menus. 1110 nav_close_megamenu(); 1111 $(".tb-megamenu").find(".tb-megamenu-clicked").removeClass("tb-megamenu-clicked"); 1112 1113 // Open the submenu. 1114 $item.addClass("tb-megamenu-clicked"); 1115 showMenu(tbitem, mm_timeout); 1116 } 1117 }); 1118 }); 1119 1120 // Anytime there's a click outside the menu, close the menu. 1121 $(document).on('click', function (event) { 1122 if ($(event.target).closest('.tb-megamenu-nav').length === 0) { 1123 nav_close_megamenu(); 1124 $(".tb-megamenu").find(".tb-megamenu-clicked").removeClass("tb-megamenu-clicked"); 1125 }; 1126 }) 1127 }; 1128 1129 if (isTouch) { 1130 createTouchMenu($(".tb-megamenu ul.nav li.mega", context).has(".dropdown-menu")); 1131 }; 1132 1133 $(window).on('load resize', function () { 1134 var windowWidth = window.innerWidth ? window.innerWidth : $(window).width(); 1135 if (windowWidth != Drupal.TBMegaMenu.oldWindowWidth) { 1136 Drupal.TBMegaMenu.oldWindowWidth = windowWidth; 1137 Drupal.TBMegaMenu.menuResponsive(); 1138 1139 if (windowWidth >= Drupal.TBMegaMenu.supportedScreens[0]) { 1140 navParent.addEventListener('keydown',keydownEvent); 1141 } 1142 else { 1143 navParent.removeEventListener('keydown',keydownEvent); 1144 } 1145 } 1146 }); 1147 1148 }); 1149 1150 } 1151 } 1152})(jQuery, Drupal, drupalSettings); 1153; 1154/*! vTicker 1.21 http://richhollis.github.com/vticker/ | http://richhollis.github.com/vticker/license/ | based on Jubgits vTicker http://www.jugbit.com/jquery-vticker-vertical-news-ticker/ */ 1155(function(d){var g,c,f;g={speed:700,pause:4E3,showItems:1,mousePause:!0,height:0,animate:!0,margin:0,padding:0,startPaused:!1,autoAppend:!0};
1155c={moveUp:function(a,b){return c.showNextItem(a,b,"up")},moveDown:function(a,b){return c.showNextItem(a,b,"down")},nextItemState:function(a,b){var e,c;c=a.element.children("ul");e=a.itemHeight;0<a.options.height&&(e=c.children("li:first").height());e+=a.options.margin+2*a.options.padding;return{height:e,options:a.options,el:a.element,obj:c,selector:"up"===b? 1156"li:first":"li:last",dir:b}},showNextItem:function(a,b,e){var d;d=c.nextItemState(a,e);d.el.trigger("vticker.beforeTick");e=d.obj.children(d.selector).clone(!0);"down"===d.dir&&d.obj.css("top","-"+d.height+"px").prepend(e);b&&b.animate?a.animating||c.animateNextItem(d,a):c.nonAnimatedNextItem(d);"up"===d.dir&&a.options.autoAppend&&e.appendTo(d.obj);return d.el.trigger("vticker.afterTick")},animateNextItem:function(a,b){b.animating=!0;return a.obj.animate("up"===a.dir?{top:"-="+a.height+"px"}:{top:0}, 1157b.options.speed,function(){d(a.obj).children(a.selector).remove();d(a.obj).css("top","0px");return b.animating=!1})},nonAnimatedNextItem:function(a){a.obj.children(a.selector).remove();return a.obj.css("top","0px")},nextUsePause:function(){var a,b;b=d(this).data("state");a=b.options;if(!b.isPaused&&!c.hasSingleItem(b))return f.next.call(this,{animate:a.animate})},startInterval:function(){var a,b;b=d(this).data("state");a=b.options;return b.intervalId=setInterval(function(a){return function(){return c.nextUsePause.call(a)}}(this), 1158a.pause)},stopInterval:function(){var a;if(a=d(this).data("state"))return a.intervalId&&clearInterval(a.intervalId),a.intervalId=void 0},restartInterval:function(){c.stopInterval.call(this);return c.startInterval.call(this)},getState:function(a,b){var c;if(!(c=d(b).data("state")))throw Error("vTicker: No state available from "+a);return c},isAnimatingOrSingleItem:function(a){return a.animating||this.hasSingleItem(a)},hasMultipleItems:function(a){return 1<a.itemCount},hasSingleItem:function(a){return!c.hasMultipleItems(a)}, 1159bindMousePausing:function(a){return function(a,e){return a.bind("mouseenter",function(){if(!e.isPaused)return e.pausedByCode=!0,c.stopInterval.call(this),f.pause.call(this,!0)}).bind("mouseleave",function(){if(!e.isPaused||e.pausedByCode)return e.pausedByCode=!1,f.pause.call(this,!1),c.startInterval.call(this)})}}(this),setItemLayout:function(a,b,c){var f;a.css({overflow:"hidden",position:"relative"}).children("ul").css({position:"absolute",margin:0,padding:0}).children("li").css({margin:c.margin, 1160padding:c.padding});return isNaN(c.height)||0===c.height?(a.children("ul").children("li").each(function(){if(d(this).height()>b.itemHeight)return b.itemHeight=d(this).height()}),a.children("ul").children("li").each(function(){return d(this).height(b.itemHeight)}),f=c.margin+2*c.padding,a.height((b.itemHeight+f)*c.showItems+c.margin)):a.height(c.height)},defaultStateAttribs:function(a,b){return{itemCount:a.children("ul").children("li").length,itemHeight:0,itemMargin:0,element:a,animating:!1,options:b, 1161isPaused:b.startPaused,pausedByCode:!1}}};f={init:function(a){var b,e;d(this).data("state")&&f.stop.call(this);b=jQuery.extend({},g);a=d.extend(b,a);b=d(this);e=c.defaultStateAttribs(b,a);d(this).data("state",e);c.setItemLayout(b,e,a);a.startPaused||c.startInterval.call(this);if(a.mousePause)return c.bindMousePausing(b,e)},pause:function(a){var b;b=c.getState("pause",this);if(!c.hasMultipleItems(b))return!1;b.isPaused=a;b=b.element;if(a)return d(this).addClass("paused"),b.trigger("vticker.pause"); 1162d(this).removeClass("paused");return b.trigger("vticker.resume")},next:function(a){var b;b=c.getState("next",this);if(c.isAnimatingOrSingleItem(b))return!1;c.restartInterval.call(this);return c.moveUp(b,a)},prev:function(a){var b;b=c.getState("prev",this);if(c.isAnimatingOrSingleItem(b))return!1;c.restartInterval.call(this);return c.moveDown(b,a)},stop:function(){c.getState("stop",this);return c.stopInterval.call(this)},remove:function(){var a;a=c.getState("remove",this);c.stopInterval.call(this); 1163a=a.element;a.unbind();return a.remove()}};return d.fn.vTicker=function(a){return f[a]?f[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!==typeof a&&a?d.error("Method "+a+" does not exist on jQuery.vTicker"):f.init.apply(this,arguments)}})(jQuery); 1164; 1165/*! 1166 * jQuery.ellipsis 1167 * http://github.com/jjenzz/jquery.ellipsis 1168 * -------------------------------------------------------------------------- 1169 * Copyright (c) 2013 J. Smith (@jjenzz) 1170 * Dual licensed under the MIT and GPL licenses: 1171 * http://www.opensource.org/licenses/mit-license.php 1172 * http://www.gnu.org/licenses/gpl.html 1173 * 1174 * adds a class to the last 'allowed' line of text so you can apply 1175 * text-overflow: ellipsis; 1176 */ 1177(function(factory) { 1178 'use strict'; 1179 1180 if (typeof define === 'function' && define.amd) { 1181 // AMD. register as an anonymous module 1182 define(['jquery'], factory); 1183 } else { 1184 // browser globals 1185 factory(jQuery); 1186 } 1187}(function($) { 1188 'use strict'; 1189 1190 var namespace = 'ellipsis', 1191 span = '<span style="white-space: nowrap;">', 1192 defaults = { 1193 lines: 'auto', 1194 ellipClass: 'ellip', 1195 responsive: false 1196 }; 1197 1198 /** 1199 * Ellipsis() 1200 * -------------------------------------------------------------------------- 1201 * @param {Node} el 1202 * @param {Object} opts 1203 */ 1204 function Ellipsis(el, opts) { 1205 var base = this, 1206 currLine = 0, 1207 lines = [], 1208 setStartEllipAt, 1209 startEllipAt, 1210 resizeTimer, 1211 currOffset, 1212 lineHeight, 1213 contHeight, 1214 words, 1215 htmlEntities; 1216 1217 // List of HTML entities for escaping. 1218 htmlEntities = { 1219 '&': '&', 1220 '<': '<', 1221 '>': '>', 1222 '"': '"', 1223 "'": ''', 1224 '`': '`' 1225 }; 1226 1227 base.$cont = $(el); 1228 base.opts = $.extend({}, defaults, opts); 1229 1230 /** 1231 * create() happens once when 1232 * instance is created 1233 */ 1234 function create() { 1235 base.text = base.$cont.text(); 1236 base.opts.ellipLineClass = base.opts.ellipClass + '-line'; 1237 1238 base.$el = $('<span class="' + base.opts.ellipClass + '" />'); 1239 base.$el.text(base.text); 1240 1241 base.$cont.empty().append(base.$el); 1242 1243 init(); 1244 } 1245 1246 /**
1247 * init() 1248 */ 1249 function init() { 1250 1251 // if they only want one line just add 1252 // the class and do nothing else 1253 if (typeof base.opts.lines === 'number' && base.opts.lines < 2) { 1254 base.$el.addClass(base.opts.ellipLineClass); 1255 return; 1256 } 1257 1258 contHeight = base.$cont.height(); 1259 1260 // if they only want to ellipsis the overflow 1261 // then do nothing if there is no overflow 1262 if (base.opts.lines === 'auto' && base.$el.prop('scrollHeight') <= contHeight) { 1263 return; 1264 } 1265 1266 if (!setStartEllipAt) { 1267 return; 1268 } 1269 1270 // create an array of words from our string 1271 words = $.trim(escapeText(base.text)).split(/\s+/); 1272 1273 // wrap each word in a span and temporarily append to the DOM 1274 base.$el.html(span + words.join('</span> ' + span) + '</span>'); 1275 1276 // loop through words to determine which word the 1277 // ellipsis container should start from (need to 1278 // re-query spans from DOM so we can get their offset) 1279 base.$el.find('span').each(setStartEllipAt); 1280 1281 // startEllipAt could be 0 so make sure we're 1282 // checking undefined instead of falsey 1283 if (startEllipAt != null) { 1284 updateText(startEllipAt); 1285 } 1286 } 1287 1288 /** 1289 * updateText() updates the text in the DOM 1290 * with a span around the line that needs 1291 * to be truncated 1292 * 1293 * @param {Number} i 1294 */ 1295 function updateText(nth) { 1296 // add a span that wraps from nth 1297 // word to the end of the string 1298 words[nth] = '<span class="' + base.opts.ellipLineClass + '">' + words[nth]; 1299 words.push('</span>'); 1300 1301 // update the DOM with 1302 // our new string/markup 1303 base.$el.html(words.join(' ')); 1304 } 1305 1306 function escapeText(text){ 1307 return String(text).replace(/[&<>"'\/]/g, function (s) { 1308 return htmlEntities[s]; 1309 }); 1310 } 1311 1312 // only define the method if it's required 1313 if (base.opts.lines === 'auto') { 1314 1315 /** 1316 * setStartEllipByHeight() sets the start 1317 * position to the first word in the last 1318 * line of the element that doesn't overflow 1319 * 1320 * @param {Number} i 1321 * @param {Node} word 1322 */ 1323 var setStartEllipByHeight = function(i, word) { 1324 var $word = $(word), 1325 top = $word.position().top; 1326 1327 lineHeight = lineHeight || $word.height(); 1328 1329 if (top === currOffset) { 1330 // if it's top matches currOffset 1331 // then it's on the same line 1332 // as the previous word 1333 lines[currLine].push($word); 1334 } else { 1335 // otherwise we're 1336 // on a new line 1337 currOffset = top; 1338 currLine += 1; 1339 lines[currLine] = [$word]; 1340 } 1341 1342 // if the bottom of the word is outside 1343 // the element (overflowing) then 1344 // stop looping and set startEllipAt to 1345 // the first word in the previous line 1346 if (top + lineHeight > contHeight) { 1347 startEllipAt = i - lines[currLine - 1].length; 1348 return false; 1349 } 1350 }; 1351 1352 setStartEllipAt = setStartEllipByHeight; 1353 } 1354 1355 // only define the method if it's required 1356 if (typeof base.opts.lines === 'number' && base.opts.lines > 1) { 1357 1358 /** 1359 * setStartEllipByLine() sets the start 1360 * position to the first word in the line 1361 * that was passed to opts. This forces 1362 * the ellipsis on a specific line 1363 * regardless of overflow 1364 * 1365 * @param {Number} i 1366 * @param {Node} word 1367 */ 1368 var setStartEllipByLine = function(i, word) { 1369 var $word = $(word), 1370 top = $word.position().top; 1371 1372 // if top isn't currOfset 1373 // then we're on a new line 1374 if (top !== currOffset) { 1375 currOffset = top; 1376 currLine += 1; 1377 } 1378 1379 // if the word's currLine is equal 1380 // to the line limit passed via options 1381 // then start ellip from this 1382 // word and stop looping 1383 if (currLine === base.opts.lines) { 1384 startEllipAt = i; 1385 return false;
1386 } 1387 }; 1388 1389 setStartEllipAt = setStartEllipByLine; 1390 } 1391 1392 // only bind to window resize if required 1393 if (base.opts.responsive) { 1394 1395 /** 1396 * resize() resets necessary vars 1397 * and content and then re-initialises 1398 * the Ellipsis script 1399 */ 1400 var resize = function() { 1401 lines = []; 1402 currLine = 0; 1403 currOffset = null; 1404 startEllipAt = null; 1405 base.$el.html(escapeText(base.text)); 1406 1407 clearTimeout(resizeTimer); 1408 resizeTimer = setTimeout(init, 100); 1409 }; 1410 1411 $(window).on('resize.' + namespace, resize); 1412 } 1413 1414 // start 'er up 1415 create(); 1416 } 1417 1418 $.fn[namespace] = function(opts) { 1419 return this.each(function() { 1420 try { 1421 $(this).data(namespace, (new Ellipsis(this, opts))); 1422 } catch (err) { 1423 if (window.console) { 1424 console.error(namespace + ': ' + err); 1425 } 1426 } 1427 }); 1428 }; 1429 1430})); 1431; 1432/** 1433 * @file cwb_alerts.block.ticker.js 1434 * 1435 * Initializes and manages jQuery libraries providing Ticker style functionality. 1436 * 1437 * @see cwb_alerts.module cwb_alerts_block_view_alter() 1438 */ 1439 1440(function ($, undefined) { 1441 Drupal.behaviors.cwb_alerts_ticker = { 1442 attach: function (context, settings) { 1443 1444 // Cache local vars. 1445 var 1446 blockAnimate = settings.cwb_alerts_ticker.tickerAnimate, 1447 blockInterval = settings.cwb_alerts_ticker.tickerInterval, 1448 blockMargin = settings.cwb_alerts_ticker.tickerMargin, 1449 1450 ticker = settings.cwb_alerts_ticker.tickerTarget, 1451 tickerCnt = settings.cwb_alerts_ticker.tickerCounter, 1452 prev = settings.cwb_alerts_ticker.buttonPrev, 1453 next = settings.cwb_alerts_ticker.buttonNext, 1454 1455 cnt = 1, 1456 len = $('.ticker-row', ticker).length 1457 ; 1458 1459 // Kick off ticker functionality. 1460 // @see http://richhollis.github.io/vticker/ 1461 $(ticker) 1462 .vTicker('init', { 1463 speed: blockAnimate, 1464 pause: blockInterval, 1465 margin: blockMargin 1466 // padding: 1 1467 }) 1468 .on('vticker.beforeTick', function () { 1469 len = $('.ticker-row', ticker).length; 1470 cnt = $('.ticker-row:nth-child(2) .alert-message', this).attr('data-index'); 1471 $(tickerCnt).text(cnt+' of '+len); 1472 }); 1473 1474 // Set previous button. 1475 $(prev).on('click', function () { 1476 $(ticker).vTicker('prev', {animate: true}); 1477 }); 1478 1479 // Set next button. 1480 $(next).on('click', function () { 1481 $(ticker).vTicker('next', {animate: true}); 1482 }); 1483 } 1484 }; 1485})(jQuery);;
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.