1!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define("resizeSensor",[],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.resizeSensor=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 2var css = (function (global) { 3 'use strict'; 4 5 /** @var {null|Object} */ 6 var animationPropertiesForBrowser = null; 7 /** @var {null|boolean} */ 8 var isCssAnimationSupported = null; 9 10 /** 11 * Determines which style convention (properties) to follow 12 * @see https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations/Detecting_CSS_animation_support 13 * @returns {{keyframesRule: string, styleDeclaration: string, animationStartEvent: string, animationName: string}} 14 */ 15 function getAnimationPropertiesForBrowser () { 16 if (animationPropertiesForBrowser !== null) { 17 return animationPropertiesForBrowser; 18 } 19 20 var testElement = global.document.createElement('div'); 21 var supportsUnprefixedAnimationProperties = ('animationName' in testElement.style); 22 23 // Unprefixed animation properties 24 var animationStartEvent = 'animationstart'; 25 var animationName = 'resizeanim'; 26 27 if (supportsUnprefixedAnimationProperties) { 28 return { 29 keyframesRule: '@keyframes ' + animationName + ' {from { opacity: 0; } to { opacity: 0; }}', 30 styleDeclaration: 'animation: 1ms ' + animationName + ';', 31 animationStartEvent: animationStartEvent, 32 animationName: animationName 33 }; 34 } 35 36 // Browser specific animation properties 37 var keyframePrefix = ''; 38 var browserPrefixes = ['Webkit', 'Moz', 'O', 'ms']; 39 var startEvents = ['webkitAnimationStart', 'animationstart', 'oAnimationStart', 'MSAnimationStart']; 40 41 var i; 42 var l = browserPrefixes.length; 43 44 for (i = 0; i < l; i++) { 45 if ((browserPrefixes[i] + 'AnimationName') in testElement.style) { 46 keyframePrefix = '-' + browserPrefixes[i].toLowerCase() + '-'; 47 animationStartEvent = startEvents[i]; 48 break; 49 } 50 } 51 52 animationPropertiesForBrowser = { 53 keyframesRule: '@' + keyframePrefix + 'keyframes ' + animationName + ' {from { opacity: 0; } to { opacity: 0; }}', 54 styleDeclaration: keyframePrefix + 'animation: 1ms ' + animationName + ';', 55 animationStartEvent: animationStartEvent, 56 animationName: animationName 57 }; 58 59 return animationPropertiesForBrowser; 60 } 61 62 /** 63 * @returns {boolean} 64 */ 65 function isCSSAnimationSupported () { 66 if (isCssAnimationSupported !== null) { 67 return isCssAnimationSupported; 68 } 69 70 var testElement = global.document.createElement('div'); 71 var isAnimationSupported = ('animationName' in testElement.style); 72 73 if (isAnimationSupported) { 74 isCssAnimationSupported = true; 75 return isCssAnimationSupported; 76 } 77 78 var browserPrefixes = 'Webkit Moz O ms'.split(' '); 79 var i = 0; 80 var l = browserPrefixes.length; 81 82 for (; i < l; i++) { 83 if ((browserPrefixes[i] + 'AnimationName') in testElement.style) { 84 isCssAnimationSupported = true; 85 return isCssAnimationSupported; 86 } 87 } 88 89 isCssAnimationSupported = false; 90 return isCssAnimationSupported; 91 } 92 93 /** 94 * Adds a style block that contains CSS essential for detecting resize events 95 */ 96 function insertResizeSensorStyles () { 97 var cssRules = [ 98 (getAnimationPropertiesForBrowser().keyframesRule) ? getAnimationPropertiesForBrowser().keyframesRule : '', 99 '.ResizeSensor__resizeTriggers { ' + ((getAnimationPropertiesForBrowser().styleDeclaration) ? getAnimationPropertiesForBrowser().styleDeclaration : '') + ' visibility: hidden; opacity: 0; }', 100 '.ResizeSensor__resizeTriggers, .ResizeSensor__resizeTriggers > div, .ResizeSensor__contractTrigger:before { content: \' \'; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .ResizeSensor__resizeTriggers > div { background: #eee; overflow: auto; } .ResizeSensor__contractTrigger:before { width: 200%; height: 200%; }' 101 ]; 102 103 cssRules = cssRules.join(' '); 104 105 var headElem = global.document.head || global.document.getElementsByTagName('head')[0]; 106 107 var styleElem = global.document.createElement('style'); 108 styleElem.type = 'text/css'; 109 110 if (styleElem.styleSheet) { 111 styleElem.styleSheet.cssText = cssRules; 112 } else { 113 styleElem.appendChild(global.document.createTextNode(cssRules)); 114 } 115 116 headElem.appendChild(styleElem); 117 } 118 119 return { 120 insertResizeSensorStyles: insertResizeSensorStyles, 121 isAnimationSupported: isCSSAnimationSupported, 122 getAnimationPropertiesForBrowser: getAnimationPropertiesForBrowser 123 }; 124})(typeof window !== 'undefined' ? window : this); 125 126module.exports = css; 127 128},{}],2:[function(require,module,exports){ 129var getStyle = (function (global) { 130 'use strict'; 131 132 /** 133 * @param {HTMLElement} element 134 * @param {string} property 135 * @returns {null|string} 136 */ 137 return function (element, property) { 138 if (!('currentStyle' in element) && !('getComputedStyle' in global)) { 139 return null; 140 } 141 142 if (element.currentStyle) { 143 return element.currentStyle[property]; 144 } 145 146 return global.document.defaultView.getComputedStyle(element, null).getPropertyValue(property); 147 }; 148})(typeof window !== 'undefined' ? window : this); 149 150module.exports = getStyle; 151 152},{}],3:[function(require,module,exports){ 153var polyfill = (function (global) { 154 'use strict'; 155 156 /** 157 * @see https://gist.github.com/mrdoob/838785 158 */ 159 function polyfillRequestAnimationFrame () { 160 if (!global.requestAnimationFrame) { 161 global.requestAnimationFrame = (function () { 162 return global.webkitRequestAnimationFrame || 163 global.mozRequestAnimationFrame || 164 global.oRequestAnimationFrame || 165 global.msRequestAnimationFrame || 166 function (callback) { 167 global.setTimeout(callback, 1000 / 60); 168 }; 169 })(); 170 } 171 172 if (!global.cancelAnimationFrame) { 173 global.cancelAnimationFrame = (function () { 174 return global.webkitCancelAnimationFrame || 175 global.mozCancelAnimationFrame || 176 global.oCancelAnimationFrame || 177 global.msCancelAnimationFrame || 178 global.clearTimeout; 179 })(); 180 } 181 } 182 183 return { 184 requestAnimationFrame: polyfillRequestAnimationFrame 185 }; 186})(typeof window !== 'undefined' ? window : this); 187 188module.exports = polyfill; 189 190},{}],4:[function(require,module,exports){ 191var resizeSensorFactory = (function (global) { 192 'use strict'; 193 194 /** @var {Function} */ 195 var getStyle = require('./getStyle'); 196 /** @var {Object} */ 197 var css = require('./css'); 198 199 /** 200 * @param {HTMLElement} targetElement 201 * @param {Function} callback 202 * @constructor 203 */ 204 var resizeSensor = function (targetElement, callback) { 205 /** @var {HTMLElement} */ 206 this.targetElement = targetElement; 207 /** @var {Function} */ 208 this.callback = callback; 209 /** @var {{width: int, height: int}} */ 210 this.dimensions = { 211 width: 0, 212 height: 0 213 }; 214 215 if ('attachEvent' in global.document) { 216 this.boundOnResizeHandler = this.onElementResize.bind(this); 217 this.targetElement.attachEvent('onresize', this.boundOnResizeHandler); 218 return; 219 } 220 221 /** @var {{container: HTMLElement, expand: HTMLElement, expandChild: HTMLElement, contract: HTMLElement}} */ 222 this.triggerElements = {}; 223 /** @var {int} */ 224 this.resizeRAF = 0; 225 226 this.setup(); 227 }; 228 229 resizeSensor.prototype.setup = function () { 230 // Make sure the target element is "positioned" 231 if (getStyle(this.targetElement, 'position') === 'static') { 232 this.targetElement.style.position = 'relative'; 233 } 234 235 // Create and append resize trigger elements 236 this.insertResizeTriggerElements(); 237 238 // Start listening to events 239 this.boundScrollListener = this.handleElementScroll.bind(this); 240 this.targetElement.addEventListener('scroll', this.boundScrollListener, true); 241 242 if (css.isAnimationSupported()) { 243 this.boundAnimationStartListener = this.resetTriggersOnAnimationStart.bind(this); 244 this.triggerElements.container.addEventListener( 245 css.getAnimationPropertiesForBrowser().animationStartEvent, 246 this.boundAnimationStartListener 247 ); 248 } 249 250 // Initial value reset of all triggers 251 this.resetTriggers(); 252 }; 253 254 resizeSensor.prototype.insertResizeTriggerElements = function () { 255 var resizeTrigger = global.document.createElement('div'); 256 var expandTrigger = global.document.createElement('div'); 257 var expandTriggerChild = global.document.createElement('div'); 258 var contractTrigger = global.document.createElement('div'); 259 260 resizeTrigger.className = 'ResizeSensor ResizeSensor__resizeTriggers'; 261 expandTrigger.className = 'ResizeSensor__expandTrigger'; 262 contractTrigger.className = 'ResizeSensor__contractTrigger'; 263 264 expandTrigger.appendChild(expandTriggerChild); 265 resizeTrigger.appendChild(expandTrigger); 266 resizeTrigger.appendChild(contractTrigger); 267 268 this.triggerElements.container = resizeTrigger; 269 this.triggerElements.expand = expandTrigger; 270 this.triggerElements.expandChild = expandTriggerChild; 271 this.triggerElements.contract = contractTrigger; 272 273 this.targetElement.appendChild(resizeTrigger); 274 }; 275 276 resizeSensor.prototype.onElementResize = function () { 277 var currentDimensions = this.getDimensions(); 278 279 if (this.isResized(currentDimensions)) { 280 this.dimensions.width = currentDimensions.width; 281 this.dimensions.height = currentDimensions.height; 282 this.elementResized(); 283 } 284 }; 285 286 resizeSensor.prototype.handleElementScroll = function () { 287 var _this = this; 288 289 this.resetTriggers(); 290 291 if (this.resizeRAF) { 292 global.cancelAnimationFrame(this.resizeRAF); 293 } 294 295 this.resizeRAF = global.requestAnimationFrame(function () { 296 var currentDimensions = _this.getDimensions(); 297 if (_this.isResized(currentDimensions)) { 298 _this.dimensions.width = currentDimensions.width; 299 _this.dimensions.height = currentDimensions.height; 300 _this.elementResized(); 301 } 302 }); 303 }; 304 305 /** 306 * @param {{width: number, height: number}} currentDimensions 307 * @returns {boolean} 308 */ 309 resizeSensor.prototype.isResized = function (currentDimensions) { 310 return (currentDimensions.width !== this.dimensions.width || currentDimensions.height !== this.dimensions.height); 311 }; 312 313 /** 314 * @returns {{width: number, height: number}} 315 */ 316 resizeSensor.prototype.getDimensions = function () { 317 return { 318 width: this.targetElement.offsetWidth, 319 height: this.targetElement.offsetHeight 320 }; 321 }; 322 323 /** 324 * @param {Event} event 325 */ 326 resizeSensor.prototype.resetTriggersOnAnimationStart = function (event) { 327 if (event.animationName === css.getAnimationPropertiesForBrowser().animationName) { 328 this.resetTriggers(); 329 } 330 }; 331 332 resizeSensor.prototype.resetTriggers = function () { 333 this.triggerElements.contract.scrollLeft = this.triggerElements.contract.scrollWidth; 334 this.triggerElements.contract.scrollTop = this.triggerElements.contract.scrollHeight; 335 this.triggerElements.expandChild.style.width = this.triggerElements.expand.offsetWidth + 1 + 'px'; 336 this.triggerElements.expandChild.style.height = this.triggerElements.expand.offsetHeight + 1 + 'px'; 337 this.triggerElements.expand.scrollLeft = this.triggerElements.expand.scrollWidth; 338 this.triggerElements.expand.scrollTop = this.triggerElements.expand.scrollHeight; 339 }; 340 341 resizeSensor.prototype.elementResized = function () { 342 this.callback(this.dimensions); 343 }; 344 345 resizeSensor.prototype.destroy = function () { 346 this.removeEventListeners(); 347 this.targetElement.removeChild(this.triggerElements.container); 348 delete this.boundAnimationStartListener; 349 delete this.boundScrollListener; 350 delete this.callback; 351 delete this.targetElement; 352 }; 353 354 resizeSensor.prototype.removeEventListeners = function () { 355 if ('attachEvent' in global.document) { 356 this.targetElement.detachEvent('onresize', this.boundOnResizeHandler); 357 return; 358 } 359 360 this.triggerElements.container.removeEventListener( 361 css.getAnimationPropertiesForBrowser().animationStartEvent, 362 this.boundAnimationStartListener 363 ); 364 this.targetElement.removeEventListener('scroll', this.boundScrollListener, true); 365 }; 366 367 return { 368 /** 369 * @param {Element} targetElement 370 * @param {Function} callback 371 * @returns {resizeSensor} 372 */ 373 create: function (targetElement, callback) { 374 return new resizeSensor(targetElement, callback); 375 } 376 }; 377})(typeof window !== 'undefined' ? window : this); 378 379module.exports = resizeSensorFactory; 380 381},{"./css":1,"./getStyle":2}],5:[function(require,module,exports){ 382var sensors = (function (global) { 383 'use strict'; 384 385 /** @var {Object} */ 386 var css = require('./css'); 387 /** @var {Object} */ 388 var polyfill = require('./polyfill'); 389 /** @var {Object} */ 390 var resizeSensorFactory = require('./resizeSensor'); 391 392 /** {array} */ 393 var unsuitableElements = ['IMG', 'COL', 'TR', 'THEAD', 'TFOOT']; 394 /** {boolean} */ 395 var supportsAttachEvent = ('attachEvent' in global.document); 396 397 /** {{}} Map of all resize sensors (id => ResizeSensor) */ 398 var allResizeSensors = {}; 399 400 if (!supportsAttachEvent) { 401 css.insertResizeSensorStyles(); 402 403 if (!('requestAnimationFrame' in global) || !('cancelAnimationFrame' in global)) { 404 polyfill.requestAnimationFrame(); 405 } 406 } 407 408 /** 409 * @param {Element} targetElement 410 * @param {Function} callback 411 * @returns {resizeSensor} 412 */ 413 function create (targetElement, callback) { 414 if (isUnsuitableElement(targetElement)) { 415 console && console.error("Given element isn't suitable to act as a resize sensor. Try wrapping it with one that is. Unsuitable elements are:", unsuitableElements); 416 return null; 417 } 418 419 var sensorId = getSensorId(targetElement); 420 421 if (allResizeSensors[sensorId]) { 422 return allResizeSensors[sensorId]; 423 } 424 425 var sensor = resizeSensorFactory.create(targetElement, callback); 426 allResizeSensors[sensorId] = sensor; 427 return sensor; 428 } 429 430 /** 431 * @param {Element} targetElement 432 */ 433 function destroy (targetElement) { 434 var sensorId = getSensorId(targetElement); 435 var sensor = allResizeSensors[sensorId]; 436 437 if (!sensor) { 438 console && console.error("Can't destroy Resi
438zeSensor (404 not found).", targetElement); 439 } 440 441 sensor.destroy(); 442 delete allResizeSensors[sensorId]; 443 } 444 445 /** 446 * @param {Element} targetElement 447 * @returns {string} 448 */ 449 function getSensorId (targetElement) { 450 return targetElement.id; 451 } 452 453 /** 454 * @param {HTMLElement} targetElement 455 * @returns {boolean} 456 */ 457 function isUnsuitableElement (targetElement) { 458 var tagName = targetElement.tagName.toUpperCase(); 459 return (unsuitableElements.indexOf(tagName) > -1); 460 } 461 462 return { 463 create: create, 464 destroy: destroy 465 }; 466})(typeof window !== 'undefined' ? window : this); 467 468module.exports = sensors; 469},{"./css":1,"./polyfill":3,"./resizeSensor":4}]},{},[5])(5) 470}); 471 472/*! 473 * Theia Sticky Sidebar v1.7.0 474 * https://github.com/WeCodePixels/theia-sticky-sidebar 475 * 476 * Glues your website's sidebars, making them permanently visible while scrolling. 477 * 478 * Copyright 2013-2016 WeCodePixels and other contributors 479 * Released under the MIT license 480 */ 481 482(function ($) { 483 $.fn.theiaStickySidebar = function (options) { 484 var defaults = { 485 'containerSelector': '', 486 'additionalMarginTop': 0, 487 'additionalMarginBottom': 0, 488 'updateSidebarHeight': true, 489 'minWidth': 0, 490 'disableOnResponsiveLayouts': true, 491 'sidebarBehavior': 'modern', 492 'defaultPosition': 'relative', 493 'namespace': 'TSS' 494 }; 495 options = $.extend(defaults, options); 496 497 // Validate options 498 options.additionalMarginTop = parseInt(options.additionalMarginTop) || 0; 499 options.additionalMarginBottom = parseInt(options.additionalMarginBottom) || 0; 500 501 tryInitOrHookIntoEvents(options, this); 502 503 // Try doing init, otherwise hook into window.resize and document.scroll and try again then. 504 function tryInitOrHookIntoEvents(options, $that) { 505 var success = tryInit(options, $that); 506 507 if (!success) {
508 console.log('TSS: Body width smaller than options.minWidth. Init is delayed.'); 509 510 $(document).on('scroll.' + options.namespace, function (options, $that) { 511 return function (evt) { 512 var success = tryInit(options, $that); 513 514 if (success) { 515 $(this).unbind(evt); 516 } 517 }; 518 }(options, $that)); 519 $(window).on('resize.' + options.namespace, function (options, $that) { 520 return function (evt) { 521 var success = tryInit(options, $that); 522 523 if (success) { 524 $(this).unbind(evt); 525 } 526 }; 527 }(options, $that)) 528 } 529 } 530 531 // Try doing init if proper conditions are met. 532 function tryInit(options, $that) { 533 if (options.initialized === true) { 534 return true; 535 } 536 537 if ($('body').width() < options.minWidth) { 538 return false; 539 } 540 541 init(options, $that); 542 543 return true; 544 } 545 546 // Init the sticky sidebar(s). 547 function init(options, $that) { 548 options.initialized = true; 549 550 // Add CSS 551 var existingStylesheet = $('#theia-sticky-sidebar-stylesheet-' + options.namespace); 552 if (existingStylesheet.length === 0) { 553 $('head').append($('<style id="theia-sticky-sidebar-stylesheet-' + options.namespace + '">.theiaStickySidebar:after {content: ""; display: table; clear: both;}</style>')); 554 } 555 556 $that.each(function () { 557 var o = {}; 558 559 o.sidebar = $(this); 560 561 // Save options 562 o.options = options || {}; 563 564 // Get container 565 o.container = $(o.options.containerSelector); 566 if (o.container.length == 0) { 567 o.container = o.sidebar.parent(); 568 } 569 570 // Create sticky sidebar 571 o.sidebar.parents().css('-webkit-transform', 'none'); // Fix for WebKit bug - https://code.google.com/p/chromium/issues/detail?id=20574 572 o.sidebar.css({ 573 'position': o.options.defaultPosition, 574 'overflow': 'visible', 575 // The "box-sizing" must be set to "content-box" because we set a fixed height to this element when the sticky
575sidebar has a fixed position. 576 '-webkit-box-sizing': 'border-box', 577 '-moz-box-sizing': 'border-box', 578 'box-sizing': 'border-box' 579 }); 580 581 // Get the sticky sidebar element. If none has been found, then create one. 582 o.stickySidebar = o.sidebar.find('.theiaStickySidebar'); 583 if (o.stickySidebar.length == 0) { 584 // Remove <script> tags, otherwise they will be run again when added to the stickySidebar. 585 var javaScriptMIMETypes = /(?:text|application)\/(?:x-)?(?:javascript|ecmascript)/i; 586 o.sidebar.find('script').filter(function (index, script) { 587 return script.type.length === 0 || script.type.match(javaScriptMIMETypes); 588 }).remove(); 589 590 o.stickySidebar = $('<div>').addClass('theiaStickySidebar').append(o.sidebar.children()); 591 o.sidebar.append(o.stickySidebar); 592 } 593 594 // Get existing top and bottom margins and paddings 595 o.marginBottom = parseInt(o.sidebar.css('margin-bottom')); 596 o.paddingTop = parseInt(o.sidebar.css('padding-top')); 597 o.paddingBottom = parseInt(o.sidebar.css('padding-bottom')); 598
599 // Add a temporary padding rule to check for collapsable margins. 600 var collapsedTopHeight = o.stickySidebar.offset().top; 601 var collapsedBottomHeight = o.stickySidebar.outerHeight(); 602 o.stickySidebar.css('padding-top', 1); 603 o.stickySidebar.css('padding-bottom', 1); 604 collapsedTopHeight -= o.stickySidebar.offset().top; 605 collapsedBottomHeight = o.stickySidebar.outerHeight() - collapsedBottomHeight - collapsedTopHeight; 606 if (collapsedTopHeight == 0) { 607 o.stickySidebar.css('padding-top', 0); 608 o.stickySidebarPaddingTop = 0; 609 } 610 else { 611 o.stickySidebarPaddingTop = 1; 612 } 613 614 if (collapsedBottomHeight == 0) { 615 o.stickySidebar.css('padding-bottom', 0); 616 o.stickySidebarPaddingBottom = 0; 617 } 618 else { 619 o.stickySidebarPaddingBottom = 1; 620 } 621 622 // We use this to know whether the user is scrolling up or down. 623 o.previousScrollTop = null; 624 625 // Scroll top (value) when the sidebar has fixed position. 626 o.fixedScrollTop = 0; 627 628 // Set sidebar to default values. 629 resetSidebar(); 630 631 o.onScroll = function (o) { 632 // Stop if the sidebar isn't visible. 633 if (!o.stickySidebar.is(":visible")) { 634 return; 635 } 636 637 // Stop if the window is too small. 638 if ($('body').width() < o.options.minWidth) { 639 resetSidebar(); 640 return; 641 } 642 643 // Stop if the sidebar width is larger than the container width (e.g. the theme is responsive and the sidebar is now below the content) 644 if (o.options.disableOnResponsiveLayouts) { 645 var sidebarWidth = o.sidebar.outerWidth(o.sidebar.css('float') == 'none'); 646 647 if (sidebarWidth + 50 > o.container.width()) { 648 resetSidebar(); 649 return; 650 } 651 } 652 653 var scrollTop = $(document).scrollTop(); 654 var position = 'static'; 655 656 // If the user has scrolled down enough for the sidebar to be clipped at the top, then we can consider changing its position. 657 if (scrollTop >= o.sidebar.offset().top + (o.paddingTop - o.options.additionalMarginTop)) { 658 // The top and bottom offsets, used in various calculations. 659 var offsetTop = o.paddingTop + options.additionalMarginTop; 660 var offsetBottom = o.paddingBottom + o.marginBottom + options.additionalMarginBottom; 661 662 // All top and bottom positions are relative to the window, not to the parent elemnts. 663 var containerTop = o.sidebar.offset().top; 664 var containerBottom = o.sidebar.offset().top + getClearedHeight(o.container); 665 666 // The top and bottom offsets relative to the window screen top (zero) and bottom (window height). 667 var windowOffsetTop = 0 + options.additionalMarginTop; 668 var windowOffsetBottom; 669 670 var sidebarSmallerThanWindow = (o.stickySidebar.outerHeight() + offsetTop + offsetBottom) < $(window).height(); 671 if (sidebarSmallerThanWindow) { 672 windowOffsetBottom = windowOffsetTop + o.stickySidebar.outerHeight(); 673 } 674 else { 675 windowOffsetBottom = $(window).height() - o.marginBottom - o.paddingBottom - options.additionalMarginBottom; 676 } 677 678 var staticLimitTop = containerTop - scrollTop + o.paddingTop; 679 var staticLimitBottom = containerBottom - scrollTop - o.paddingBottom - o.marginBottom; 680 681 var top = o.stickySidebar.offset().top - scrollTop; 682 var scrollTopDiff = o.previousScrollTop - scrollTop; 683 684 // If the sidebar position is fixed, then it won't move up or down by itself. So, we manually adjust the top coordinate. 685 if (o.stickySidebar.css('position') == 'fixed') { 686 if (o.options.sidebarBehavior == 'modern') { 687 top += scrollTopDiff; 688 } 689 } 690 691 if (o.options.sidebarBehavior == 'stick-to-top') { 692 top = options.additionalMarginTop; 693 } 694 695 if (o.options.sidebarBehavior == 'stick-to-bottom') { 696 top = windowOffsetBottom - o.stickySidebar.outerHeight(); 697 } 698 699 if (scrollTopDiff > 0) { // If the user is scrolling up. 700 top = Math.min(top, windowOffsetTop); 701 } 702 else { // If the user is scrolling down. 703 top = Math.max(top, windowOffsetBottom - o.stickySidebar.outerHeight()); 704 } 705 706 top = Math.max(top, staticLimitTop); 707 708 top = Math.min(top, staticLimitBottom - o.stickySidebar.outerHeight()); 709 710 // If the sidebar is the same height as the container, we won't use fixed positioning. 711 var sidebarSameHeightAsContainer = o.container.height() == o.stickySidebar.outerHeight(); 712 713 if (!sidebarSameHeightAsContainer && top == windowOffsetTop) { 714 position = 'fixed'; 715 } 716 else if (!sidebarSameHeightAsContainer && top == windowOffsetBottom - o.stickySidebar.outerHeight()) { 717 position = 'fixed'; 718 } 719 else if (scrollTop + top - o.sidebar.offset().top - o.paddingTop <= options.additionalMarginTop) { 720 // Stuck to the top of the page. No special behavior. 721 position = 'static'; 722 } 723 else { 724 // Stuck to the bottom of the page. 725 position = 'absolute'; 726 } 727 } 728 729 /*
730 * Performance notice: It's OK to set these CSS values at each resize/scroll, even if they don't change. 731 * It's way slower to first check if the values have changed. 732 */ 733 if (position == 'fixed') { 734 var scrollLeft = $(document).scrollLeft(); 735 736 o.stickySidebar.css({ 737 'position': 'fixed', 738 'width': getWidthForObject(o.stickySidebar) + 'px', 739 'transform': 'translateY(' + top + 'px)', 740 'left': (o.sidebar.offset().left + parseInt(o.sidebar.css('padding-left')) - scrollLeft) + 'px', 741 'top': '0px' 742 }); 743 } 744 else if (position == 'absolute') { 745 var css = {}; 746 747 if (o.stickySidebar.css('position') != 'absolute') { 748 css.position = 'absolute'; 749 css.transform = 'translateY(' + (scrollTop + top - o.sidebar.offset().top - o.stickySidebarPaddingTop - o.stickySidebarPaddingBottom) + 'px)'; 750 css.top = '0px'; 751 } 752 753 css.width = getWidthForObject(o.stickySidebar) + 'px'; 754 css.left = ''; 755 756 o.stickySidebar.css(css); 757 } 758 else if (position == 'static') { 759 resetSidebar(); 760 } 761 762 if (position != 'static') { 763 if (o.options.updateSidebarHeight == true) { 764 o.sidebar.css({ 765 'min-height': o.stickySidebar.outerHeight() + o.stickySidebar.offset().top - o.sidebar.offset().top + o.paddingBottom 766 }); 767 } 768 } 769 770 o.previousScrollTop = scrollTop; 771 }; 772 773 // Initialize the sidebar's position. 774 o.onScroll(o); 775 776 // Recalculate the sidebar's position on every scroll and resize. 777 $(document).on('scroll.' + o.options.namespace, function (o) { 778 return function () { 779 o.onScroll(o); 780 }; 781 }(o)); 782 $(window).on('resize.' + o.options.namespace, function (o) { 783 return function () { 784 o.stickySidebar.css({'position': 'static'}); 785 o.onScroll(o); 786 }; 787 }(o)); 788 789 // Recalculate the sidebar's position every time the sidebar changes its size. 790 if (typeof ResizeSensor !== 'undefined') { 791 new ResizeSensor(o.stickySidebar[0], function (o) { 792 return function () { 793 o.onScroll(o); 794 }; 795 }(o)); 796 } 797 798 // Reset the sidebar to its default state 799 function resetSidebar() { 800 o.fixedScrollTop = 0; 801 o.sidebar.css({ 802 'min-height': '1px' 803 }); 804 o.stickySidebar.css({ 805 'position': 'static', 806 'width': '', 807 'transform': 'none' 808 }); 809 } 810 811 // Get the height of a div as if its floated children were cleared. Note that this function fails if the floats are more than one level deep. 812 function getClearedHeight(e) { 813 var height = e.height(); 814 815 e.children().each(function () { 816 height = Math.max(height, $(this).height()); 817 }); 818 819 return height; 820 } 821 }); 822 } 823 824 function getWidthForObject(object) { 825 var width; 826 827 try { 828 width = object[0].getBoundingClientRect().width; 829 } 830 catch (err) { 831 } 832 833 if (typeof width === "undefined") { 834 width = object.width(); 835 } 836 837 return width; 838 } 839 840 return this; 841 } 842})(jQuery); 843 844//# sourceMappingURL=maps/theia-sticky-sidebar.js.map
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.