{"version":3,"sources":["node_modules/browser-pack/_prelude.js","src/sticky.ts"],"names":["f","exports","module","define","amd","window","global","self","this","stickyts","r","e","n","t","o","i","c","require","u","a","Error","code","p","call","length","1","Sticky","_this","selector","arguments","undefined","options","_classCallCheck","elements","vp","getViewportSize","body","document","querySelector","firstRender","scrollTop","getScrollTopPosition","wrap","marginTop","marginBottom","stickyFor","stickyClass","stickyContainer","addEventListener","run","_this2","pageLoaded","setInterval","readyState","querySelectorAll","forEach","element","renderElement","clearInterval","update","_this3","dataMarginTop","getAttribute","dataMarginBottom","dataStickyFor","sticky","active","parseInt","rect","getRectangle","hasAttribute","container","getStickyContainer","tagName","toLowerCase","onload","wrapElement","activate","insertAdjacentHTML","previousSibling","appendChild","top","height","width","setAttribute","indexOf","push","resizeEvent","initResizeEvents","scrollEvent","initScrollEvents","setPosition","_this4","resizeListener","onResizeEvents","removeEventListener","_this5","scrollListener","onScrollEvents","css","position","left","parentNode","display","innerHeight","offsetHeight","classList","remove","add","_this6","_this7","destroyResizeEvents","destroyScrollEvents","Math","max","offsetWidth","clientWidth","scrollWidth","clientHeight","scrollHeight","offsetTop","offsetLeft","offsetParent","documentElement","innerWidth","properties","property","hasOwnProperty","style","pageYOffset","clientTop"],"mappings":"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","file":"sticky.min.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i {\n this.scrollTop = this.getScrollTopPosition()\n })\n window.addEventListener('scroll', () => {\n this.scrollTop = this.getScrollTopPosition()\n })\n\n this.run()\n }\n \n \n /**\n * Waits for page to be fully loaded, then renders & activates every sticky element found with the specified selector.\n * @function\n */\n run(): void {\n const pageLoaded = setInterval(() => {\n if (document.readyState === 'interactive' && this.firstRender === false) {\n this.firstRender = true\n \n const elements: NodeListOf = document.querySelectorAll(this.selector)\n elements.forEach((element: IStickyElement) => this.renderElement(element))\n return\n }\n \n if (document.readyState === 'complete') {\n clearInterval(pageLoaded)\n this.update()\n }\n }, 10)\n }\n \n \n /**\n * Assigns the needed variables for sticky elements, that are used in the future for calculations.\n * @function\n * @param element - Element to be rendered\n */\n renderElement(element: IStickyElement): void {\n let dataMarginTop = element.getAttribute('data-margin-top') || '0'\n let dataMarginBottom = element.getAttribute('data-margin-bottom') || '0'\n let dataStickyFor = element.getAttribute('data-sticky-for') || '0'\n // Create a container for variables needed in future and set defaults.\n element.sticky = {\n active: false,\n marginTop: parseInt(dataMarginTop, 10) || this.options.marginTop,\n marginBottom: parseInt(dataMarginBottom, 10) || this.options.marginBottom,\n rect: this.getRectangle(element),\n stickyFor: parseInt(dataStickyFor, 10) || this.options.stickyFor,\n stickyClass: element.getAttribute('data-sticky-class') || this.options.stickyClass,\n // TODO: attribute for stickyContainer\n // element.sticky.stickyContainer = element.getAttribute('data-sticky-container') || this.options.stickyContainer\n stickyContainer: this.options.stickyContainer,\n wrap: element.hasAttribute('data-sticky-wrap') ? true : this.options.wrap,\n }\n element.sticky.container = this.getStickyContainer(element)\n element.sticky.container.rect = this.getRectangle(element.sticky.container)\n \n // TODO: Fix when element is image that has not yet loaded and width, height = 0\n if (element.tagName.toLowerCase() === 'img') {\n element.onload = () => element.sticky.rect = this.getRectangle(element)\n }\n \n if (element.sticky.wrap) {\n this.wrapElement(element)\n }\n\n this.activate(element)\n }\n \n \n /**\n * Wraps element with a placeholder element.\n * @function\n * @param element - Element to be wrapped.\n */\n wrapElement(element: IStickyElement): void {\n element.insertAdjacentHTML('beforebegin', '')\n let previousSibling: Node = element.previousSibling as Node\n previousSibling.appendChild(element)\n }\n \n \n /**\n * Function that activates element when specified conditions are met and then initalise events\n * @function\n * @param element - Element to be activated\n */\n activate(element: IStickyElement): void {\n if (\n ((element.sticky.rect.top + element.sticky.rect.height) < (element.sticky.container.rect.top + element.sticky.container.rect.height))\n && (element.sticky.stickyFor as number < this.vp.width)\n && !element.sticky.active\n ) {\n element.sticky.active = true\n element.setAttribute( 'data-sticky-rendered', '' )\n }\n \n if (this.elements.indexOf(element) < 0) {\n this.elements.push(element)\n }\n \n if (!element.sticky.resizeEvent) {\n this.initResizeEvents(element)\n element.sticky.resizeEvent = true\n }\n \n if (!element.sticky.scrollEvent) {\n this.initScrollEvents(element)\n element.sticky.scrollEvent = true\n }\n \n this.setPosition(element)\n }\n \n \n /**\n * Adds onResizeEvents to window listener and assigns function to element as resizeListener.\n * @function\n * @param element - Element for which resize events are initialised\n */\n initResizeEvents(element: IStickyElement): void {\n element.sticky.resizeListener = () => this.onResizeEvents(element)\n window.addEventListener('resize', element.sticky.resizeListener)\n }\n \n \n /**\n * Removes element listener from resize event.\n * @function\n * @param element - Element from which listener is deleted.\n */\n destroyResizeEvents(element: IStickyElement): void {\n window.removeEventListener('resize', element.sticky.resizeListener as EventListener)\n }\n \n \n /**\n * Fired when user resizes window. It checks if element should be activated or deactivated and then runs setPosition function.\n * @function\n * @param element - Element for which event function is fired\n */\n onResizeEvents(element: IStickyElement): void {\n this.vp = this.getViewportSize()\n \n element.sticky.rect = this.getRectangle(element)\n element.sticky.container.rect = this.getRectangle(element.sticky.container)\n \n if (\n ((element.sticky.rect.top + element.sticky.rect.height) < (element.sticky.container.rect.top + element.sticky.container.rect.height))\n && (element.sticky.stickyFor as number < this.vp.width)\n && !element.sticky.active\n ) {\n element.sticky.active = true\n } else if (\n ((element.sticky.rect.top + element.sticky.rect.height) >= (element.sticky.container.rect.top + element.sticky.container.rect.height))\n || element.sticky.stickyFor as number >= this.vp.width\n && element.sticky.active\n ) {\n element.sticky.active = false\n }\n \n this.setPosition(element)\n }\n \n \n /**\n * Adds onScrollEvents to window listener and assigns function to element as scrollListener.\n * @function\n * @param element - Element for which scroll events are initialised\n */\n initScrollEvents(element: IStickyElement): void {\n element.sticky.scrollListener = () => this.onScrollEvents(element)\n window.addEventListener('scroll', element.sticky.scrollListener)\n }\n \n \n /**\n * Removes element listener from scroll event.\n * @function\n * @param element - Element from which listener is deleted.\n */\n destroyScrollEvents(element: IStickyElement): void {\n window.removeEventListener('scroll', element.sticky.scrollListener as EventListener)\n }\n \n \n /**\n * Fired when user scrolls window. Invokes setPosition function if element is active.\n * @function\n * @param element - Element for which event function is fired\n */\n onScrollEvents(element: IStickyElement): void {\n if (element.sticky.active) {\n this.setPosition(element)\n }\n }\n \n \n /**\n * Main function for the library. Here are some condition calculations and css appending for sticky element when user scroll window\n * @function\n * @param element - Element that will be positioned if it's active\n */\n setPosition(element: IStickyElement): void {\n this.css(element, { position: '', width: '', top: '', left: '' })\n \n if ((this.vp.height < element.sticky.rect.height) || !element.sticky.active) {\n return\n }\n \n if (!element.sticky.rect.width) {\n element.sticky.rect = this.getRectangle(element)\n }\n \n if (element.sticky.wrap) {\n this.css((element as Element).parentNode as HTMLElement, {\n display: 'block',\n width: element.sticky.rect.width + 'px',\n height: element.sticky.rect.height + 'px',\n })\n }\n \n if (element.sticky.marginBottom) {\n if (\n element.sticky.rect.top === 0\n && element.sticky.container === this.body\n ) {\n this.css(element, {\n position: 'fixed',\n top: element.sticky.rect.top + 'px',\n left: element.sticky.rect.left + 'px',\n width: element.sticky.rect.width + 'px',\n })\n } else if (\n this.scrollTop + window.innerHeight >\n (element.sticky.rect.top + element.sticky.rect.height + element.sticky.marginBottom)\n ) {\n // Stick element\n this.css(element, {\n position: 'fixed',\n width: element.sticky.rect.width + 'px',\n left: element.sticky.rect.left + 'px',\n })\n \n if ( // Unstick, but keep setting it's top position\n (this.scrollTop + window.innerHeight - element.sticky.marginBottom) >\n (element.sticky.container.rect.top + element.sticky.container.offsetHeight)\n ) {\n \n if (element.sticky.stickyClass) {\n element.classList.remove(element.sticky.stickyClass)\n }\n \n this.css(element, {\n top: (element.sticky.container.rect.top + element.sticky.container.offsetHeight) -\n (this.scrollTop + element.sticky.rect.height) + 'px',\n })\n } else { // Add top position to tick\n if (element.sticky.stickyClass) {\n element.classList.add(element.sticky.stickyClass)\n }\n \n this.css(element, { top: window.innerHeight - element.sticky.marginBottom - element.sticky.rect.height + 'px' })\n }\n } else { // Unstick and clear styles, when element is below the stick position\n if (element.sticky.stickyClass) {\n element.classList.remove(element.sticky.stickyClass)\n }\n \n this.css(element, { position: '', width: '', top: '', left: '' })\n \n if (element.sticky.wrap) {\n this.css(element.parentNode as HTMLElement, { display: '', width: '', height: '' })\n }\n }\n }\n // If doesn't have marginBottom option\n else {\n if ( element.sticky.rect.top === 0 && element.sticky.container === this.body ) {\n this.css(element, {\n position: 'fixed',\n top: element.sticky.rect.top + 'px',\n left: element.sticky.rect.left + 'px',\n width: element.sticky.rect.width + 'px',\n })\n } else if (this.scrollTop > (element.sticky.rect.top - (element.sticky.marginTop as number))) {\n this.css(element, {\n position: 'fixed',\n width: element.sticky.rect.width + 'px',\n left: element.sticky.rect.left + 'px',\n })\n \n if (\n (this.scrollTop + element.sticky.rect.height + element.sticky.marginTop)\n > (element.sticky.container.rect.top + element.sticky.container.offsetHeight)\n ) {\n \n if (element.sticky.stickyClass) {\n element.classList.remove(element.sticky.stickyClass)\n }\n \n this.css(element, {\n top: (element.sticky.container.rect.top + element.sticky.container.offsetHeight) - (this.scrollTop + element.sticky.rect.height) + 'px' }\n )\n } else {\n if (element.sticky.stickyClass) {\n element.classList.add(element.sticky.stickyClass)\n }\n \n this.css(element, { top: element.sticky.marginTop + 'px' })\n }\n } else {\n if (element.sticky.stickyClass) {\n element.classList.remove(element.sticky.stickyClass)\n }\n \n this.css(element, { position: '', width: '', top: '', left: '' })\n \n if (element.sticky.wrap) {\n this.css(element.parentNode as HTMLElement, { display: '', width: '', height: '' })\n }\n }\n }\n }\n \n \n /**\n * Updates element sticky rectangle (with sticky container), then activates or deactivates element and updates its position if it's active.\n * @function\n */\n update(): void {\n const elements: NodeListOf = document.querySelectorAll(this.selector)\n elements.forEach((element: IStickyElement) => {\n // if this element has not already been rendered\n if ( element.getAttribute( 'data-sticky-rendered' ) === null ) {\n element.setAttribute( 'data-sticky-rendered', '' )\n this.elements.push( element )\n this.renderElement(element)\n } else {\n element.sticky.rect = this.getRectangle(element)\n element.sticky.container.rect = this.getRectangle(element.sticky.container)\n \n this.activate(element)\n this.setPosition(element)\n }\n })\n }\n \n \n /**\n * Destroys sticky element, remove listeners\n * @function\n */\n destroy(): void {\n this.elements.forEach((element: IStickyElement) => {\n this.destroyResizeEvents(element)\n this.destroyScrollEvents(element)\n delete element.sticky\n })\n }\n \n \n /**\n * Function that returns container element in which sticky element is stuck (if is not specified, then it's stuck to body)\n * @function\n * @param element - Element which sticky container are looked for\n * @return Node - Sticky container\n */\n getStickyContainer(element: IStickyElement): Node {\n let container = element.parentNode\n \n while (\n !(container as Element).hasAttribute('data-sticky-container')\n && !((container as Node).parentNode as Element).querySelector(element.sticky.stickyContainer as string)\n && container !== this.body\n ) {\n container = (container as Node).parentNode\n }\n \n return container as Node\n }\n \n \n /**\n * Returns an element's rectangle & position.\n * @function\n * @param element - Element in which position & rectangle are returned.\n * @return\n */\n getRectangle(element: IStickyElement): IRectangle {\n this.css(element, {position: '', width: '', top: '', left: '' })\n \n const width = Math.max(element.offsetWidth, element.clientWidth, element.scrollWidth)\n const height = Math.max(element.offsetHeight, element.clientHeight, element.scrollHeight)\n \n let top = 0\n let left = 0\n \n do {\n top += element.offsetTop || 0\n left += element.offsetLeft || 0\n element = element.offsetParent as IStickyElement \n } while (element)\n \n return { top, left, width, height }\n }\n \n \n /**\n * Returns viewport dimensions.\n * @function\n * @return\n */\n getViewportSize(): IViewportData {\n return {\n width: Math.max(document.documentElement.clientWidth, window.innerWidth || 0),\n height: Math.max(document.documentElement.clientHeight, window.innerHeight || 0),\n }\n }\n \n /**\n * Helper function to add/remove css properties for specified element.\n * @param element - DOM element\n * @param properties - CSS properties that will be added/removed from specified element\n */\n css(element: HTMLElement, properties: {[key: string]: any}): void {\n for (let property in properties) {\n if (properties.hasOwnProperty(property)) {\n element.style[property as any] = properties[property];\n }\n }\n }\n /**\n * Returns the window scroll position.\n * @function\n * @return Number - scroll position\n */\n private getScrollTopPosition(): number {\n return (window.pageYOffset || document.body.scrollTop) - (document.body.clientTop || 0) || 0\n }\n }"]}