1/* @license GPL-2.0-or-later https://www.drupal.org/licensing/faq */ 2"use strict"; 3 4// JavaScript should be made compatible with libraries other than jQuery by 5// wrapping it with an "anonymous closure". See: 6// - https://drupal.org/node/1446420 7// - http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth 8(function (Drupal, $) { 9 'use strict'; 10 11 Drupal.behaviors.uhSticky = { 12 attach: function attach(context, settings) { 13 once('processed', '.stick-to-top', context).forEach(function (el) { 14 var stickyElm = $(el); 15 if ($(window).width() > 768) { 16 stickyElm.sticky({ 17 topSpacing: 0, 18 responsiveWidth: true 19 }); 20 } 21 $(window).resize(function () { 22 if ($(window).width() > 768) { 23 stickyElm.sticky({ 24 topSpacing: 0, 25 responsiveWidth: true 26 }); 27 } else { 28 stickyElm.unstick(); 29 } 30 }); 31 }); 32 once('processed', '.progress-container', context).forEach(function (el) { 33 var stickyContainer = $(el); 34 if ($(window).width() < 768) { 35 stickyContainer.sticky({ 36 topSpacing: 0, 37 responsiveWidth: true 38 }); 39 } 40 $(window).resize(function () { 41 if ($(window).width() < 768) { 42 stickyContainer.sticky({ 43 topSpacing: 0, 44 responsiveWidth: true 45 }); 46 } else { 47 stickyContainer.unstick(); 48 } 49 }); 50 }); 51 } 52 }; 53 54 // We pass the parameters of this anonymous function are the global variables 55 // that this script depend on. For example, if the above script requires 56 // jQuery, you should change (Drupal) to (Drupal, jQuery) in the line below 57 // and, in this file's first line of JS, change function (Drupal) to 58 // (Drupal, $) 59})(Drupal, jQuery);; 60'use strict'; 61 62/** 63 * Copyright Marc J. Schmidt. See the LICENSE file at the top-level 64 * directory of this distribution and at 65 * https://github.com/marcj/css-element-queries/blob/master/LICENSE. 66 */ 67function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 68(function (root, factory) { 69 if (typeof define === "function" && define.amd) { 70 define(factory); 71 } else if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object") { 72 module.exports = factory(); 73 } else { 74 root.ResizeSensor = factory(); 75 } 76})(typeof window !== 'undefined' ? window : void 0, function () { 77 // Make sure it does not throw in a SSR (Server Side Rendering) situation 78 if (typeof window === "undefined") { 79 return null; 80 } 81 // https://github.com/Semantic-Org/Semantic-UI/issues/3855 82 // https://github.com/marcj/css-element-queries/issues/257 83 var globalWindow = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); 84 // Only used for the dirty checking, so the event callback count is limited to max 1 call per fps per sensor. 85 // In combination with the event based resize sensor this saves cpu time, because the sensor is too fast and 86 // would generate too many unnecessary events. 87 var requestAnimationFrame = globalWindow.requestAnimationFrame || globalWindow.mozRequestAnimationFrame || globalWindow.webkitRequestAnimationFrame || function (fn) { 88 return globalWindow.setTimeout(fn, 20); 89 }; 90 var cancelAnimationFrame = globalWindow.cancelAnimationFrame || globalWindow.mozCancelAnimationFrame || globalWindow.webkitCancelAnimationFrame || function (timer) { 91 globalWindow.clearTimeout(timer); 92 }; 93 94 /** 95 * Iterate over each of the provided element(s). 96 * 97 * @param {HTMLElement|HTMLElement[]} elements 98 * @param {Function} callback 99 */ 100 function forEachElement(elements, callback) { 101 var elementsType = Object.prototype.toString.call(elements); 102 var isCollectionTyped = '[object Array]' === elementsType || '[object NodeList]' === elementsType || '[object HTMLCollection]' === elementsType || '[object Object]' === elementsType || 'undefined' !== typeof jQuery && elements instanceof jQuery //jquery 103 || 'undefined' !== typeof Elements && elements instanceof Elements //mootools 104 ; 105 var i = 0, 106 j = elements.length; 107 if (isCollectionTyped) { 108 for (; i < j; i++) { 109 callback(elements[i]); 110 } 111 } else { 112 callback(elements); 113 } 114 } 115 116 /** 117 * Get element size 118 * @param {HTMLElement} element 119 * @returns {Object} {width, height} 120 */ 121 function getElementSize(element) { 122 if (!element.getBoundingClientRect) { 123 return { 124 width: element.offsetWidth, 125 height: element.offsetHeight 126 }; 127 } 128 var rect = element.getBoundingClientRect(); 129 return { 130 width: Math.round(rect.width), 131 height: Math.round(rect.height) 132 }; 133 } 134 135 /** 136 * Apply CSS styles to element. 137 * 138 * @param {HTMLElement} element 139 * @param {Object} style 140 */ 141 function setStyle(element, style) { 142 Object.keys(style).forEach(function (key) { 143 element.style[key] = style[key]; 144 }); 145 } 146 147 /** 148 * Class for dimension change detection. 149 * 150 * @param {Element|Element[]|Elements|jQuery} element 151 * @param {Function} callback 152 * 153 * @constructor 154 */ 155 var _ResizeSensor = function ResizeSensor(element, callback) { 156 //Is used when checking in reset() only for invisible elements 157 var lastAnimationFrameForInvisibleCheck = 0; 158 159 /** 160 * 161 * @constructor 162 */ 163 function EventQueue() { 164 var q = []; 165 this.add = function (ev) { 166 q.push(ev); 167 }; 168 var i, j; 169 this.call = function (sizeInfo) { 170 for (i = 0, j = q.length; i < j; i++) { 171 q[i].call(this, sizeInfo); 172 } 173 }; 174 this.remove = function (ev) { 175 var newQueue = []; 176 for (i = 0, j = q.length; i < j; i++) { 177 if (q[i] !== ev) newQueue.push(q[i]); 178 } 179 q = newQueue; 180 }; 181 this.length = function () { 182 return q.length; 183 }; 184 } 185 186 /** 187 * 188 * @param {HTMLElement} element 189 * @param {Function} resized 190 */ 191 function attachResizeEvent(element, resized) { 192 if (!element) return; 193 if (element.resizedAttached) { 194 element.resizedAttached.add(resized); 195 return; 196 } 197 element.resizedAttached = new EventQueue(); 198 element.resizedAttached.add(resized); 199 element.resizeSensor = document.createElement('div'); 200 element.resizeSensor.dir = 'ltr'; 201 element.resizeSensor.className = 'resize-sensor'; 202 var style = { 203 pointerEvents: 'none', 204 position: 'absolute', 205 left: '0px', 206 top: '0px', 207 right: '0px', 208 bottom: '0px', 209 overflow: 'hidden', 210 zIndex: '-1', 211 visibility: 'hidden', 212 maxWidth: '100%' 213 }; 214 var styleChild = { 215 position: 'absolute', 216 left: '0px', 217 top: '0px', 218 transition: '0s' 219 }; 220 setStyle(element.resizeSensor, style); 221 var expand = document.createElement('div'); 222 expand.className = 'resize-sensor-expand'; 223 setStyle(expand, style); 224 var expandChild = document.createElement('div'); 225 setStyle(expandChild, styleChild); 226 expand.appendChild(expandChild); 227 var shrink = document.createElement('div'); 228 shrink.className = 'resize-sensor-shrink'; 229 setStyle(shrink, style); 230 var shrinkChild = document.createElement('div'); 231 setStyle(shrinkChild, styleChild); 232 setStyle(shrinkChild, { 233 width: '200%', 234 height: '200%' 235 }); 236 shrink.appendChild(shrinkChild); 237 element.resizeSensor.appendChild(expand); 238 element.resizeSensor.appendChild(shrink); 239 element.appendChild(element.resizeSensor); 240 var computedStyle = window.getComputedStyle(element); 241 var position = computedStyle ? computedStyle.getPropertyValue('position') : null; 242 if ('absolute' !== position && 'relative' !== position && 'fixed' !== position && 'sticky' !== position) { 243 element.style.position = 'relative'; 244 } 245 var dirty = false;
246 247 //last request animation frame id used in onscroll event 248 var rafId = 0; 249 var size = getElementSize(element); 250 var lastWidth = 0; 251 var lastHeight = 0; 252 var initialHiddenCheck = true; 253 lastAnimationFrameForInvisibleCheck = 0; 254 var resetExpandShrink = function resetExpandShrink() { 255 var width = element.offsetWidth; 256 var height = element.offsetHeight; 257 expandChild.style.width = width + 10 + 'px'; 258 expandChild.style.height = height + 10 + 'px'; 259 expand.scrollLeft = width + 10; 260 expand.scrollTop = height + 10; 261 shrink.scrollLeft = width + 10; 262 shrink.scrollTop = height + 10; 263 }; 264 var _reset = function reset() { 265 // Check if element is hidden 266 if (initialHiddenCheck) { 267 var invisible = element.offsetWidth === 0 && element.offsetHeight === 0; 268 if (invisible) { 269 // Check in next frame 270 if (!lastAnimationFrameForInvisibleCheck) { 271 lastAnimationFrameForInvisibleCheck = requestAnimationFrame(function () { 272 lastAnimationFrameForInvisibleCheck = 0; 273 _reset(); 274 }); 275 } 276 return; 277 } else { 278 // Stop checking 279 initialHiddenCheck = false; 280 } 281 } 282 resetExpandShrink(); 283 }; 284 element.resizeSensor.resetSensor = _reset; 285 var onResized = function onResized() { 286 rafId = 0; 287 if (!dirty) return; 288 lastWidth = size.width; 289 lastHeight = size.height; 290 if (element.resizedAttached) { 291 element.resizedAttached.call(size); 292 } 293 }; 294 var onScroll = function onScroll() { 295 size = getElementSize(element); 296 dirty = size.width !== lastWidth || size.height !== lastHeight; 297 if (dirty && !rafId) { 298 rafId = requestAnimationFrame(onResized); 299 } 300 _reset(); 301 }; 302 var addEvent = function addEvent(el, name, cb) { 303 if (el.attachEvent) { 304 el.attachEvent('on' + name, cb); 305 } else { 306 el.addEventListener(name, cb); 307 } 308 }; 309 addEvent(expand, 'scroll', onScroll); 310 addEvent(shrink, 'scroll', onScroll); 311 312 // Fix for custom Elements and invisible elements 313 lastAnimationFrameForInvisibleCheck = requestAnimationFrame(function () { 314 lastAnimationFrameForInvisibleCheck = 0; 315 _reset(); 316 }); 317 } 318 forEachElement(element, function (elem) { 319 attachResizeEvent(elem, callback); 320 }); 321 this.detach = function (ev) { 322 // clean up the unfinished animation frame to prevent a potential endless requestAnimationFrame of reset 323 if (lastAnimationFrameForInvisibleCheck) { 324 cancelAnimationFrame(lastAnimationFrameForInvisibleCheck); 325 lastAnimationFrameForInvisibleCheck = 0; 326 } 327 _ResizeSensor.detach(element, ev); 328 }; 329 this.reset = function () { 330 //To prevent invoking element.resizeSensor.resetSensor if it's undefined 331 if (element.resizeSensor.resetSensor) { 332 element.resizeSensor.resetSensor(); 333 } 334 }; 335 }; 336 _ResizeSensor.reset = function (element) { 337 forEachElement(element, function (elem) { 338 //To prevent invoking element.resizeSensor.resetSensor if it's undefined 339 if (element.resizeSensor.resetSensor) { 340 elem.resizeSensor.resetSensor(); 341 } 342 }); 343 }; 344 _ResizeSensor.detach = function (element, ev) { 345 forEachElement(element, function (elem) { 346 if (!elem) return; 347 if (elem.resizedAttached && typeof ev === "function") { 348 elem.resizedAttached.remove(ev); 349 if (elem.resizedAttached.length()) return; 350 } 351 if (elem.resizeSensor) { 352 if (elem.contains(elem.resizeSensor)) { 353 elem.removeChild(elem.resizeSensor); 354 } 355 delete elem.resizeSensor; 356 delete elem.resizedAttached; 357 } 358 }); 359 }; 360 if (typeof MutationObserver !== "undefined") { 361 var observer = new MutationObserver(function (mutations) { 362 for (var i in mutations) { 363 if (mutations.hasOwnProperty(i)) { 364 var items = mutations[i].addedNodes; 365 for (var j = 0; j < items.length; j++) { 366 if (items[j].resizeSensor) { 367 _ResizeSensor.reset(items[j]); 368 } 369 } 370 } 371 } 372 }); 373 document.addEventListener("DOMContentLoaded", function (event) { 374 observer.observe(document.body, { 375 childList: true, 376 subtree: true 377 }); 378 }); 379 } 380 return _ResizeSensor; 381});; 382"use strict"; 383 384function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 385(function (global, factory) { 386 (typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : factory(); 387})(void 0, function () { 388 'use strict'; 389 390 var _createClass = function () { 391 function defineProperties(target, props) { 392 for (var i = 0; i < props.length; i++) { 393 var descriptor = props[i]; 394 descriptor.enumerable = descriptor.enumerable || false; 395 descriptor.configurable = true; 396 if ("value" in descriptor) descriptor.writable = true; 397 Object.defineProperty(target, descriptor.key, descriptor); 398 } 399 } 400 return function (Constructor, protoProps, staticProps) { 401 if (protoProps) defineProperties(Constructor.prototype, protoProps); 402 if (staticProps) defineProperties(Constructor, staticProps); 403 return Constructor; 404 }; 405 }(); 406 function _classCallCheck(instance, Constructor) { 407 if (!(instance instanceof Constructor)) { 408 throw new TypeError("Cannot call a class as a function"); 409 } 410 } 411 412 /** 413 * Sticky Sidebar JavaScript Plugin. 414 * @version 3.3.1 415 * @author Ahmed Bouhuolia <[email protected]> 416 * @license The MIT License (MIT) 417 */ 418 var StickySidebar = function () { 419 // ---------------------------------
vendor: 3,355 bytes, lines 420-527
420 // # Define Constants 421 // --------------------------------- 422 // 423 var EVENT_KEY = '.stickySidebar'; 424 var DEFAULTS = { 425 /** 426 * Additional top spacing of the element when it becomes sticky. 427 * @type {Numeric|Function} 428 */ 429 topSpacing: 0, 430 /** 431 * Additional bottom spacing of the element when it becomes sticky. 432 * @type {Numeric|Function} 433 */ 434 bottomSpacing: 0, 435 /** 436 * Container sidebar selector to know what the beginning and end of sticky element. 437 * @type {String|False} 438 */ 439 containerSelector: false, 440 /** 441 * Inner wrapper selector. 442 * @type {String} 443 */ 444 innerWrapperSelector: '.inner-wrapper-sticky', 445 /** 446 * The name of CSS class to apply to elements when they have become stuck. 447 * @type {String|False} 448 */ 449 stickyClass: 'is-affixed', 450 /** 451 * Detect when sidebar and its container change height so re-calculate their dimensions. 452 * @type {Boolean} 453 */ 454 resizeSensor: true, 455 /** 456 * The sidebar returns to its normal position if its width below this value. 457 * @type {Numeric} 458 */ 459 minWidth: false 460 }; 461 462 // --------------------------------- 463 // # Class Definition 464 // --------------------------------- 465 // 466 /** 467 * Sticky Sidebar Class. 468 * @public 469 */ 470 471 var StickySidebar = function () { 472 /** 473 * Sticky Sidebar Constructor. 474 * @constructor 475 * @param {HTMLElement|String} sidebar - The sidebar element or sidebar selector. 476 * @param {Object} options - The options of sticky sidebar. 477 */ 478 function StickySidebar(sidebar) { 479 var _this = this; 480 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 481 _classCallCheck(this, StickySidebar); 482 this.options = StickySidebar.extend(DEFAULTS, options); 483 484 // Sidebar element query if there's no one, throw error. 485 this.sidebar = 'string' === typeof sidebar ? document.querySelector(sidebar) : sidebar; 486 if ('undefined' === typeof this.sidebar) throw new Error("There is no specific sidebar element."); 487 this.sidebarInner = false; 488 this.container = this.sidebar.parentElement; 489 490 // Current Affix Type of sidebar element. 491 this.affixedType = 'STATIC'; 492 this.direction = 'down'; 493 this.support = { 494 transform: false, 495 transform3d: false 496 }; 497 this._initialized = false; 498 this._reStyle = false; 499 this._breakpoint = false; 500 this._resizeListeners = []; 501 502 // Dimensions of sidebar, container and screen viewport. 503 this.dimensions = { 504 translateY: 0, 505 topSpacing: 0, 506 lastTopSpacing: 0, 507 bottomSpacing: 0, 508 lastBottomSpacing: 0, 509 sidebarHeight: 0, 510 sidebarWidth: 0, 511 containerTop: 0, 512 containerHeight: 0, 513 viewportHeight: 0, 514 viewportTop: 0, 515 lastViewportTop: 0 516 }; 517 518 // Bind event handlers for referencability. 519 ['handleEvent'].forEach(function (method) { 520 _this[method] = _this[method].bind(_this); 521 }); 522 523 // Initialize sticky sidebar for first time. 524 this.initialize(); 525 } 526 527 /**
528 * Initializes the sticky sidebar by adding inner wrapper, define its container, 529 * min-width breakpoint, calculating dimensions, adding helper classes and inline style. 530 * @private 531 */ 532 533 _createClass(StickySidebar, [{ 534 key: 'initialize', 535 value: function initialize() { 536 var _this2 = this; 537 this._setSupportFeatures(); 538 539 // Get sticky sidebar inner wrapper, if not found, will create one. 540 if (this.options.innerWrapperSelector) { 541 this.sidebarInner = this.sidebar.querySelector(this.options.innerWrapperSelector); 542 if (null === this.sidebarInner) this.sidebarInner = false; 543 } 544 if (!this.sidebarInner) { 545 var wrapper = document.createElement('div'); 546 wrapper.setAttribute('class', 'inner-wrapper-sticky'); 547 this.sidebar.appendChild(wrapper); 548 while (this.sidebar.firstChild != wrapper) { 549 wrapper.appendChild(this.sidebar.firstChild); 550 } 551 this.sidebarInner = this.sidebar.querySelector('.inner-wrapper-sticky'); 552 } 553 554 // Container wrapper of the sidebar. 555 if (this.options.containerSelector) { 556 var containers = document.querySelectorAll(this.options.containerSelector);
557 containers = Array.prototype.slice.call(containers); 558 containers.forEach(function (container, item) { 559 if (!container.contains(_this2.sidebar)) return; 560 _this2.container = container; 561 }); 562 if (!containers.length) throw new Error("The container does not contains on the sidebar."); 563 } 564 565 // If top/bottom spacing is not function parse value to integer. 566 if ('function' !== typeof this.options.topSpacing) this.options.topSpacing = parseInt(this.options.topSpacing) || 0; 567 if ('function' !== typeof this.options.bottomSpacing) this.options.bottomSpacing = parseInt(this.options.bottomSpacing) || 0; 568 569 // Breakdown sticky sidebar if screen width below `options.minWidth`. 570 this._widthBreakpoint(); 571 572 // Calculate dimensions of sidebar, container and viewport. 573 this.calcDimensions(); 574 575 // Affix sidebar in proper position. 576 this.stickyPosition(); 577 578 // Bind all events. 579 this.bindEvents(); 580
vendor: 21,176 bytes, lines 581-1142
581 // Inform other properties the sticky sidebar is initialized. 582 this._initialized = true; 583 } 584 585 /** 586 * Bind all events of sticky sidebar plugin. 587 * @protected 588 */ 589 }, { 590 key: 'bindEvents', 591 value: function bindEvents() { 592 window.addEventListener('resize', this, { 593 passive: true, 594 capture: false 595 }); 596 window.addEventListener('scroll', this, { 597 passive: true, 598 capture: false 599 }); 600 this.sidebar.addEventListener('update' + EVENT_KEY, this); 601 if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) { 602 new ResizeSensor(this.sidebarInner, this.handleEvent); 603 new ResizeSensor(this.container, this.handleEvent); 604 } 605 } 606 607 /** 608 * Handles all events of the plugin. 609 * @param {Object} event - Event object passed from listener. 610 */ 611 }, { 612 key: 'handleEvent', 613 value: function handleEvent(event) { 614 this.updateSticky(event); 615 } 616 617 /** 618 * Calculates dimensions of sidebar, container and screen viewpoint 619 * @public 620 */ 621 }, { 622 key: 'calcDimensions', 623 value: function calcDimensions() { 624 if (this._breakpoint) return; 625 var dims = this.dimensions; 626 627 // Container of sticky sidebar dimensions. 628 dims.containerTop = StickySidebar.offsetRelative(this.container).top; 629 dims.containerHeight = this.container.clientHeight; 630 dims.containerBottom = dims.containerTop + dims.containerHeight; 631 632 // Sidebar dimensions. 633 dims.sidebarHeight = this.sidebarInner.offsetHeight; 634 dims.sidebarWidth = this.sidebar.offsetWidth; 635 636 // Screen viewport dimensions. 637 dims.viewportHeight = window.innerHeight; 638 this._calcDimensionsWithScroll(); 639 } 640 641 /** 642 * Some dimensions values need to be up-to-date when scrolling the page. 643 * @private 644 */ 645 }, { 646 key: '_calcDimensionsWithScroll', 647 value: function _calcDimensionsWithScroll() { 648 var dims = this.dimensions; 649 dims.sidebarLeft = StickySidebar.offsetRelative(this.sidebar).left; 650 dims.viewportTop = document.documentElement.scrollTop || document.body.scrollTop; 651 dims.viewportBottom = dims.viewportTop + dims.viewportHeight; 652 dims.viewportLeft = document.documentElement.scrollLeft || document.body.scrollLeft; 653 dims.topSpacing = this.options.topSpacing; 654 dims.bottomSpacing = this.options.bottomSpacing; 655 if ('function' === typeof dims.topSpacing) dims.topSpacing = parseInt(dims.topSpacing(this.sidebar)) || 0; 656 if ('function' === typeof dims.bottomSpacing) dims.bottomSpacing = parseInt(dims.bottomSpacing(this.sidebar)) || 0; 657 if ('VIEWPORT-TOP' === this.affixedType) { 658 // Adjust translate Y in the case decrease top spacing value. 659 if (dims.topSpacing < dims.lastTopSpacing) { 660 dims.translateY += dims.lastTopSpacing - dims.topSpacing; 661 this._reStyle = true; 662 } 663 } else if ('VIEWPORT-BOTTOM' === this.affixedType) { 664 // Adjust translate Y in the case decrease bottom spacing value. 665 if (dims.bottomSpacing < dims.lastBottomSpacing) { 666 dims.translateY += dims.lastBottomSpacing - dims.bottomSpacing; 667 this._reStyle = true; 668 } 669 } 670 dims.lastTopSpacing = dims.topSpacing; 671 dims.lastBottomSpacing = dims.bottomSpacing; 672 } 673 674 /** 675 * Determine whether the sidebar is bigger than viewport. 676 * @public 677 * @return {Boolean} 678 */ 679 }, { 680 key: 'isSidebarFitsViewport', 681 value: function isSidebarFitsViewport() { 682 return this.dimensions.sidebarHeight < this.dimensions.viewportHeight; 683 } 684 685 /** 686 * Observe browser scrolling direction top and down. 687 */ 688 }, { 689 key: 'observeScrollDir', 690 value: function observeScrollDir() { 691 var dims = this.dimensions; 692 if (dims.lastViewportTop === dims.viewportTop) return; 693 var furthest = 'down' === this.direction ? Math.min : Math.max; 694 695 // If the browser is scrolling not in the same direction. 696 if (dims.viewportTop === furthest(dims.viewportTop, dims.lastViewportTop)) this.direction = 'down' === this.direction ? 'up' : 'down'; 697 } 698 699 /** 700 * Gets affix type of sidebar according to current scrollTop and scrollLeft. 701 * Holds all logical affix of the sidebar when scrolling up and down and when sidebar 702 * is bigger than viewport and vice versa. 703 * @public 704 * @return {String|False} - Proper affix type. 705 */ 706 }, { 707 key: 'getAffixType', 708 value: function getAffixType() { 709 var dims = this.dimensions, 710 affixType = false; 711 this._calcDimensionsWithScroll(); 712 var sidebarBottom = dims.sidebarHeight + dims.containerTop; 713 var colliderTop = dims.viewportTop + dims.topSpacing; 714 var colliderBottom = dims.viewportBottom - dims.bottomSpacing; 715 716 // When browser is scrolling top. 717 if ('up' === this.direction) { 718 if (colliderTop <= dims.containerTop) { 719 dims.translateY = 0; 720 affixType = 'STATIC'; 721 } else if (colliderTop <= dims.translateY + dims.containerTop) { 722 dims.translateY = colliderTop - dims.containerTop; 723 affixType = 'VIEWPORT-TOP'; 724 } else if (!this.isSidebarFitsViewport() && dims.containerTop <= colliderTop) { 725 affixType = 'VIEWPORT-UNBOTTOM'; 726 } 727 // When browser is scrolling up. 728 } else { 729 // When sidebar element is not bigger than screen viewport. 730 if (this.isSidebarFitsViewport()) { 731 if (dims.sidebarHeight + colliderTop >= dims.containerBottom) { 732 dims.translateY = dims.containerBottom - sidebarBottom; 733 affixType = 'CONTAINER-BOTTOM'; 734 } else if (colliderTop >= dims.containerTop) { 735 dims.translateY = colliderTop - dims.containerTop; 736 affixType = 'VIEWPORT-TOP'; 737 } 738 // When sidebar element is bigger than screen viewport. 739 } else { 740 if (dims.containerBottom <= colliderBottom) { 741 dims.translateY = dims.containerBottom - sidebarBottom; 742 affixType = 'CONTAINER-BOTTOM'; 743 } else if (sidebarBottom + dims.translateY <= colliderBottom) { 744 dims.translateY = colliderBottom - sidebarBottom; 745 affixType = 'VIEWPORT-BOTTOM'; 746 } else if (dims.containerTop + dims.translateY <= colliderTop) { 747 affixType = 'VIEWPORT-UNBOTTOM'; 748 } 749 } 750 } 751 752 // Make sure the translate Y is not bigger than container height. 753 dims.translateY = Math.max(0, dims.translateY); 754 dims.translateY = Math.min(dims.containerHeight, dims.translateY); 755 dims.lastViewportTop = dims.viewportTop; 756 return affixType; 757 } 758 759 /** 760 * Gets inline style of sticky sidebar wrapper and inner wrapper according 761 * to its affix type. 762 * @private 763 * @param {String} affixType - Affix type of sticky sidebar. 764 * @return {Object} 765 */ 766 }, { 767 key: '_getStyle', 768 value: function _getStyle(affixType) { 769 if ('undefined' === typeof affixType) return; 770 var style = { 771 inner: {}, 772 outer: {} 773 }; 774 var dims = this.dimensions; 775 switch (affixType) { 776 case 'VIEWPORT-TOP': 777 style.inner = { 778 position: 'fixed', 779 top: dims.topSpacing, 780 left: dims.sidebarLeft - dims.viewportLeft, 781 width: dims.sidebarWidth 782 }; 783 break; 784 case 'VIEWPORT-BOTTOM': 785 style.inner = { 786 position: 'fixed', 787 top: 'auto', 788 left: dims.sidebarLeft, 789 bottom: dims.bottomSpacing, 790 width: dims.sidebarWidth 791 }; 792 break; 793 case 'CONTAINER-BOTTOM': 794 case 'VIEWPORT-UNBOTTOM': 795 var translate = this._getTranslate(0, dims.translateY + 'px'); 796 if (translate) style.inner = { 797 transform: translate 798 };else style.inner = { 799 position: 'absolute', 800 top: dims.translateY, 801 width: dims.sidebarWidth 802 }; 803 break; 804 } 805 switch (affixType) { 806 case 'VIEWPORT-TOP': 807 case 'VIEWPORT-BOTTOM': 808 case 'VIEWPORT-UNBOTTOM': 809 case 'CONTAINER-BOTTOM': 810 style.outer = { 811 height: dims.sidebarHeight, 812 position: 'relative' 813 }; 814 break; 815 } 816 style.outer = StickySidebar.extend({ 817 height: '', 818 position: '' 819 }, style.outer); 820 style.inner = StickySidebar.extend({ 821 position: 'relative', 822 top: '', 823 left: '', 824 bottom: '', 825 width: '', 826 transform: this._getTranslate() 827 }, style.inner); 828 return style; 829 } 830 831 /** 832 * Cause the sidebar to be sticky according to affix type by adding inline 833 * style, adding helper class and trigger events. 834 * @function 835 * @protected 836 * @param {string} force - Update sticky sidebar position by force. 837 */ 838 }, { 839 key: 'stickyPosition', 840 value: function stickyPosition(force) { 841 if (this._breakpoint) return; 842 force = this._reStyle || force || false; 843 var affixType = this.getAffixType(); 844 var style = this._getStyle(affixType); 845 if ((this.affixedType != affixType || force) && affixType) { 846 var affixEvent = 'affix.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY; 847 StickySidebar.eventTrigger(this.sidebar, affixEvent); 848 if ('STATIC' === affixType) StickySidebar.removeClass(this.sidebar, this.options.stickyClass);else StickySidebar.addClass(this.sidebar, this.options.stickyClass); 849 for (var key in style.outer) { 850 this.sidebar.style[key] = style.outer[key]; 851 } 852 for (var _key in style.inner) { 853 var _unit2 = 'number' === typeof style.inner[_key] ? 'px' : ''; 854 this.sidebarInner.style[_key] = style.inner[_key] + _unit2; 855 } 856 var affixedEvent = 'affixed.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY; 857 StickySidebar.eventTrigger(this.sidebar, affixedEvent); 858 } else { 859 if (this._initialized) this.sidebarInner.style.left = style.inner.left; 860 } 861 this.affixedType = affixType; 862 } 863 864 /** 865 * Breakdown sticky sidebar when window width is below `options.minWidth` value. 866 * @protected 867 */ 868 }, { 869 key: '_widthBreakpoint', 870 value: function _widthBreakpoint() { 871 if (window.innerWidth <= this.options.minWidth) { 872 this._breakpoint = true; 873 this.affixedType = 'STATIC'; 874 this.sidebar.removeAttribute('style'); 875 StickySidebar.removeClass(this.sidebar, this.options.stickyClass); 876 this.sidebarInner.removeAttribute('style'); 877 } else { 878 this._breakpoint = false; 879 } 880 } 881 882 /** 883 * Switches between functions stack for each event type, if there's no 884 * event, it will re-initialize sticky sidebar. 885 * @public 886 */ 887 }, { 888 key: 'updateSticky', 889 value: function updateSticky() { 890 var _this3 = this; 891 var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 892 if (this._running) return; 893 this._running = true; 894 (function (eventType) { 895 requestAnimationFrame(function () { 896 switch (eventType) { 897 // When browser is scrolling and re-calculate just dimensions 898 // within scroll. 899 case 'scroll': 900 _this3._calcDimensionsWithScroll(); 901 _this3.observeScrollDir(); 902 _this3.stickyPosition(); 903 break; 904 905 // When browser is resizing or there's no event, observe width 906 // breakpoint and re-calculate dimensions. 907 case 'resize': 908 default: 909 _this3._widthBreakpoint(); 910 _this3.calcDimensions(); 911 _this3.stickyPosition(true); 912 break; 913 } 914 _this3._running = false; 915 }); 916 })(event.type); 917 } 918 919 /** 920 * Set browser support features to the public property. 921 * @private 922 */ 923 }, { 924 key: '_setSupportFeatures', 925 value: function _setSupportFeatures() { 926 var support = this.support; 927 support.transform = StickySidebar.supportTransform(); 928 support.transform3d = StickySidebar.supportTransform(true); 929 } 930 931 /** 932 * Get translate value, if the browser supports transfrom3d, it will adopt it. 933 * and the same with translate. if browser doesn't support both return false. 934 * @param {Number} y - Value of Y-axis. 935 * @param {Number} x - Value of X-axis. 936 * @param {Number} z - Value of Z-axis. 937 * @return {String|False} 938 */ 939 }, { 940 key: '_getTranslate', 941 value: function _getTranslate() { 942 var y = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 943 var x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; 944 var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; 945 if (this.support.transform3d) return 'translate3d(' + y + ', ' + x + ', ' + z + ')';else if (this.support.translate) return 'translate(' + y + ', ' + x + ')';else return false; 946 } 947 948 /** 949 * Destroy sticky sidebar plugin. 950 * @public 951 */ 952 }, { 953 key: 'destroy', 954 value: function destroy() { 955 window.removeEventListener('resize', this, { 956 caption: false 957 }); 958 window.removeEventListener('scroll', this, { 959 caption: false 960 }); 961 this.sidebar.classList.remove(this.options.stickyClass); 962 this.sidebar.style.minHeight = ''; 963 this.sidebar.removeEventListener('update' + EVENT_KEY, this); 964 var styleReset = { 965 inner: {}, 966 outer: {} 967 }; 968 styleReset.inner = { 969 position: '', 970 top: '', 971 left: '', 972 bottom: '', 973 width: '', 974 transform: '' 975 }; 976 styleReset.outer = { 977 height: '', 978 position: '' 979 }; 980 for (var key in styleReset.outer) { 981 this.sidebar.style[key] = styleReset.outer[key]; 982 } 983 for (var _key2 in styleReset.inner) { 984 this.sidebarInner.style[_key2] = styleReset.inner[_key2]; 985 } 986 if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) { 987 ResizeSensor.detach(this.sidebarInner, this.handleEvent); 988 ResizeSensor.detach(this.container, this.handleEvent); 989 } 990 } 991 992 /** 993 * Determine if the browser supports CSS transform feature. 994 * @function 995 * @static 996 * @param {Boolean} transform3d - Detect transform with translate3d. 997 * @return {String} 998 */ 999 }], [{ 1000 key: 'supportTransform', 1001 value: function supportTransform(transform3d) { 1002 var result = false, 1003 property = transform3d ? 'perspective' : 'transform', 1004 upper = property.charAt(0).toUpperCase() + property.slice(1), 1005 prefixes = ['Webkit', 'Moz', 'O', 'ms'], 1006 support = document.createElement('support'), 1007 style = support.style; 1008 (property + ' ' + prefixes.join(upper + ' ') + upper).split(' ').forEach(function (property, i) { 1009 if (style[property] !== undefined) { 1010 result = property; 1011 return false; 1012 } 1013 }); 1014 return result; 1015 } 1016 1017 /** 1018 * Trigger custom event. 1019 * @static 1020 * @param {DOMObject} element - Target element on the DOM. 1021 * @param {String} eventName - Event name. 1022 * @param {Object} data - 1023 */ 1024 }, { 1025 key: 'eventTrigger', 1026 value: function eventTrigger(element, eventName, data) { 1027 try { 1028 var event = new CustomEvent(eventName, { 1029 detail: data 1030 }); 1031 } catch (e) { 1032 var event = document.createEvent('CustomEvent'); 1033 event.initCustomEvent(eventName, true, true, data); 1034 } 1035 element.dispatchEvent(event); 1036 } 1037 1038 /** 1039 * Extend options object with defaults. 1040 * @function 1041 * @static 1042 */ 1043 }, { 1044 key: 'extend', 1045 value: function extend(defaults, options) { 1046 var results = {}; 1047 for (var key in defaults) { 1048 if ('undefined' !== typeof options[key]) results[key] = options[key];else results[key] = defaults[key]; 1049 } 1050 return results; 1051 } 1052 1053 /** 1054 * Get current coordinates left and top of specific element. 1055 * @static 1056 */ 1057 }, { 1058 key: 'offsetRelative', 1059 value: function offsetRelative(element) { 1060 var result = { 1061 left: 0, 1062 top: 0 1063 }; 1064 do { 1065 var offsetTop = element.offsetTop; 1066 var offsetLeft = element.offsetLeft; 1067 if (!isNaN(offsetTop)) result.top += offsetTop; 1068 if (!isNaN(offsetLeft)) result.left += offsetLeft; 1069 element = 'BODY' === element.tagName ? element.parentElement : element.offsetParent; 1070 } while (element); 1071 return result; 1072 } 1073 1074 /** 1075 * Add specific class name to specific element. 1076 * @static 1077 * @param {ObjectDOM} element 1078 * @param {String} className 1079 */ 1080 }, { 1081 key: 'addClass', 1082 value: function addClass(element, className) { 1083 if (!StickySidebar.hasClass(element, className)) { 1084 if (element.classList) element.classList.add(className);else element.className += ' ' + className; 1085 } 1086 } 1087 1088 /** 1089 * Remove specific class name to specific element 1090 * @static 1091 * @param {ObjectDOM} element 1092 * @param {String} className 1093 */ 1094 }, { 1095 key: 'removeClass', 1096 value: function removeClass(element, className) { 1097 if (StickySidebar.hasClass(element, className)) { 1098 if (element.classList) element.classList.remove(className);else element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); 1099 } 1100 } 1101 1102 /** 1103 * Determine weather the element has specific class name. 1104 * @static 1105 * @param {ObjectDOM} element 1106 * @param {String} className 1107 */ 1108 }, { 1109 key: 'hasClass', 1110 value: function hasClass(element, className) { 1111 if (element.classList) return element.classList.contains(className);else return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className); 1112 } 1113 }]); 1114 return StickySidebar; 1115 }(); 1116 return StickySidebar; 1117 }(); 1118 1119 // Global 1120 // ------------------------- 1121 window.StickySidebar = StickySidebar; 1122 (function () { 1123 if ('undefined' === typeof window) return; 1124 var plugin = window.$ || window.jQuery || window.Zepto; 1125 var DATA_NAMESPACE = 'stickySidebar'; 1126 1127 // Make sure the site has jquery or zepto plugin. 1128 if (plugin) { 1129 /** 1130 * Sticky Sidebar Plugin Defintion. 1131 * @param {Object|String} - config 1132 */ 1133 var _jQueryPlugin = function _jQueryPlugin(config) { 1134 return this.each(function () { 1135 var $this = plugin(this), 1136 data = plugin(this).data(DATA_NAMESPACE); 1137 if (!data) { 1138 data = new StickySidebar(this, _typeof(config) == 'object' && config); 1139 $this.data(DATA_NAMESPACE, data); 1140 } 1141 if ('string' === typeof config) { 1142 if (data[config] === undefined && ['destroy', 'updateSticky'].indexOf(config) === -1) throw new Error('No method n
1142amed "' + config + '"'); 1143 data[config](); 1144 } 1145 }); 1146 }; 1147 plugin.fn.stickySidebar = _jQueryPlugin; 1148 plugin.fn.stickySidebar.Constructor = StickySidebar; 1149 var old = plugin.fn.stickySidebar; 1150 1151 /** 1152 * Sticky Sidebar No Conflict. 1153 */ 1154 plugin.fn.stickySidebar.noConflict = function () { 1155 plugin.fn.stickySidebar = old; 1156 return this; 1157 }; 1158 } 1159 })(); 1160});; 1161"use strict"; 1162 1163// JavaScript should be made compatible with libraries other than jQuery by 1164// wrapping it with an "anonymous closure". See: 1165// - https://drupal.org/node/1446420 1166// - http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth 1167(function (Drupal, $) { 1168 'use strict'; 1169 1170 Drupal.behaviors.SidebarStickyInit = { 1171 attach: function attach(context, settings) { 1172 once('processed', '.page-node__sidebar', context).forEach(function (el) { 1173 $(el).stickySidebar({ 1174 topSpacing: 120, 1175 bottomSpacing: 0, 1176 containerSelector: false, 1177 innerWrapperSelector: '.sidebar__inner', 1178 resizeSensor: true, 1179 stickyClass: 'is-affixed', 1180 minWidth: 710 1181 }); 1182 }); 1183 } 1184 }; 1185 1186 // We pass the parameters of this anonymous function are the global variables 1187 // that this script depend on. For example, if the above script requires 1188 // jQuery, you should change (Drupal) to (Drupal, jQuery) in the line below 1189 // and, in this file's first line of JS, change function (Drupal) to 1190 // (Drupal, $) 1191})(Drupal, jQuery);; 1192(function(Drupal){Drupal.AjaxCommands.prototype.gtagEvent=function(ajax,response){gtag('event',response.event_name,response.data);};})(Drupal);; 1193((Drupal)=>{Drupal.behaviors.lazy={attach(context,settings){const utils={extend(obj,src){Object.keys(src).forEach((key)=>{obj[key]=src[key];});return obj;},once(selector){return (context||document).querySelector(selector);},loadScript(url){if(document.querySelectorAll(`script[src="${url}"]`).length===0){const script=document.createElement('script');const scripts=document.getElementsByTagName('script')[0];script.src=url;script.async=true;scripts.parentNode.insertBefore(script,scripts);}}};if(utils.once('body',context)){const lazysizes=settings.lazy.lazysizes||{};if(!settings.lazy.preferNative){window.lazySizesConfig=window.lazySizesConfig||{};window.lazySizesConfig=utils.extend(window.lazySizesConfig,lazysizes);if(!Object.entries)Object.entries=(obj)=>{const ownProps=Object.keys(obj);let i=ownProps.length;const resArray=new Array(i);while(i--)resArray[i]=[ownProps[i],obj[ownProps[i]]];return resArray;};const min=settings.lazy.minified?'.min':'';Object.entries(lazysizes.plugins).forEach((path)=>{utils.loadScript(`${settings.lazy.libraryPath}/plugins/${path[1]}${min}.js`);});utils.loadScript(`${settings.lazy.libraryPath}/lazysizes${min}.js`);}}}};})(Drupal);;
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.