{"version":3,"file":"ScrollSnapping.js","names":["ScrollSnapping","a","setters","Component","default","deepMerge","scrollTo","mediaQuery","Event","once","isChrome","execute","constructor","element","options","arguments","length","topThreshold","bottomThreshold","_scrollable","initCache","selectors","sectionsMobile","document","querySelectorAll","sectionsAll","sectionsUpdate","initState","sections","state","currentSectionIndex","scrollTopOffset","headerHeight","stickyPanelHeight","lastScrollTop","documentElement","scrollTop","isScrollSnapping","isScrollEnded","afterInit","updateStickyPanelHeight","setStartSection","onMediaQueryChange","destroy","bindEvents","is","sectionsArr","Array","from","productStickyBar","querySelector","on","onHeaderUpdate","event","updateHeaderHeight","height","classList","contains","offsetHeight","add","remove","getVisiblePixels","scrollDirection","rect","getBoundingClientRect","windowHeight","window","innerHeight","clientHeight","rectTop","top","rectBottom","bottom","nextSectionIndex","findIndex","section","snapToSection","scrollToNextSection","index","scrollToPrevSection","prevSectionIndex","findLastIndex","waitForScrollEnd","then","onScroll","handleScroll","bind","scrollDown","lastChangedFrame","lastX","scrollX","lastY","scrollY","Promise","resolve","tick","frames","requestAnimationFrame","removeListener","onEvent"],"sources":["components/global/ScrollSnapping.js"],"sourcesContent":["import Component from 'core/Component';\nimport { deepMerge } from 'toolbox/deepMerge';\nimport { scrollTo } from 'toolbox/scroll';\nimport { mediaQuery } from 'toolbox/mediaQuery';\nimport { Event } from 'services/EventEmitter';\nimport { once } from 'toolbox/event';\nimport { isChrome } from 'core/shims/support';\n\n/**\n * This is a description of the ScrollSnapping constructor function.\n *\n * @class\n * @classdesc Implements the scroll snapping logic - \"locks\" the viewport to certain elements\n * after a user has finished scrolling (scrolls the page to align the top of a section with the viewport).\n * Can be enabled per section only for mobile or for all breakpoints.\n * Takes into account sticky header and sticky PDP bar to calculate the offset and align the section properly.\n * @extends Component\n */\nexport default class ScrollSnapping extends Component {\n /**\n * @property {number} topThreshold - visible height in px of the item to trigger the scroll snap\n * @property {number} bottomThreshold - visible height in px of the previous item to trigger the scroll snap\n */\n /**\n * Constructor of the class that mainly merge the options of the components\n * @param {HTMLElement} element HTMLElement of the component\n * @param {object} options options that belongs to the component\n */\n constructor(element, options = {}) {\n super(element, deepMerge({\n topThreshold: 0,\n bottomThreshold: 0,\n _scrollable: true,\n }, options));\n }\n\n /**\n * All selectors must be cached. Never cache elements that are out of the component scope\n */\n initCache() {\n this.selectors.sectionsMobile = document.querySelectorAll('[data-js-scroll-snap-section=\"mobile\"], [data-js-scroll-snap-section=\"all\"]');\n this.selectors.sectionsAll = document.querySelectorAll('[data-js-scroll-snap-section=\"all\"]');\n\n this.sectionsUpdate();\n }\n\n /**\n * Init the different state of the component\n * It helps to avoid heavy DOM manipulation\n */\n initState() {\n if (this.selectors.sections.length > 0) {\n this.state.currentSectionIndex = -1;\n this.state.scrollTopOffset = 0;\n this.state.headerHeight = 0;\n this.state.stickyPanelHeight = 0;\n this.state.lastScrollTop = document.documentElement.scrollTop;\n this.state.isScrollSnapping = false;\n this.state.isScrollEnded = true;\n this.state.isChrome = isChrome();\n }\n }\n\n /**\n * After init\n * Run any script after the component is fully initialized\n */\n afterInit() {\n if (this.selectors.sections.length > 0) {\n this.updateStickyPanelHeight();\n this.setStartSection();\n }\n }\n\n /**\n * onMediaQueryChange event handler\n */\n onMediaQueryChange() {\n this.destroy();\n this.sectionsUpdate();\n this.updateStickyPanelHeight();\n this.setStartSection();\n this.bindEvents();\n }\n\n /**\n * Update sections based on the media query\n */\n sectionsUpdate() {\n if (this.selectors.sectionsMobile.length && mediaQuery.is('medium down')) {\n this.selectors.sections = this.selectors.sectionsMobile;\n } else {\n this.selectors.sections = this.selectors.sectionsAll;\n }\n if (this.selectors.sections.length > 0) {\n this.selectors.sectionsArr = Array.from(this.selectors.sections);\n this.selectors.productStickyBar = document.querySelector('[data-js-product-sticky-bar-bar]');\n }\n }\n\n /**\n * Should contain only event listeners and nothing else\n * All the event handlers should be into a separated function. No usage of anonyous function\n */\n bindEvents() {\n if (this.selectors.sections.length > 0) {\n Event.on('header.updateHeight', this.onHeaderUpdate, this);\n }\n }\n\n /**\n * On header update callback\n *\n * @param {Object} event of the header\n */\n onHeaderUpdate(event) {\n this.updateHeaderHeight(event);\n }\n\n /**\n * Update top offset based on the sticky header state\n *\n * @param {Object} event of the header\n */\n updateHeaderHeight(event) {\n this.state.headerHeight = event.height !== undefined ? event.height : this.state.headerHeight;\n this.state.scrollTopOffset = this.state.headerHeight + this.state.stickyPanelHeight;\n }\n\n /**\n * Update top offset based on the PDP sticky panel state\n */\n updateStickyPanelHeight() {\n if (this.selectors.productStickyBar) {\n if (this.selectors.productStickyBar.classList.contains('m-sticked')) {\n this.state.stickyPanelHeight = this.selectors.productStickyBar.offsetHeight;\n } else if (mediaQuery.is('large')) {\n this.selectors.productStickyBar.classList.add('m-sticked');\n this.state.stickyPanelHeight = this.selectors.productStickyBar.offsetHeight;\n this.selectors.productStickyBar.classList.remove('m-sticked');\n }\n } else {\n this.state.stickyPanelHeight = 0;\n }\n this.state.scrollTopOffset = this.state.headerHeight + this.state.stickyPanelHeight;\n }\n\n /**\n * get visible pixels of the element\n * @param {HTMLElement} element - HTMLElement of the component\n * @param {String} scrollDirection - scroll direction\n * @returns {Number} visible number of pixels in a viewport\n */\n getVisiblePixels(element, scrollDirection) {\n const rect = element.getBoundingClientRect();\n const windowHeight = (window.innerHeight || document.documentElement.clientHeight);\n\n if (scrollDirection === 'down') {\n const rectTop = rect.top;\n\n if (rectTop >= 0 && rectTop < windowHeight) {\n // Top part of the element is visible, return number of pixels visible to a user\n return windowHeight - rectTop;\n }\n } else {\n const rectBottom = rect.bottom;\n\n if (rectBottom >= this.state.scrollTopOffset && rectBottom < windowHeight) {\n // Bottom part of the element is visible, return number of pixels visible to a user\n return rectBottom - this.state.scrollTopOffset;\n }\n }\n\n // Element is not visible\n return 0;\n }\n\n /**\n * Set start section if the user opened the page in the middle of a scroll\n * or scrolled the page before it is fully loaded\n */\n setStartSection() {\n const nextSectionIndex = this.selectors.sectionsArr\n .findIndex(section => this.getVisiblePixels(section, 'down') > this.options.topThreshold);\n\n if (nextSectionIndex !== -1) {\n this.snapToSection(this.selectors.sectionsArr[nextSectionIndex]);\n\n this.state.currentSectionIndex = nextSectionIndex;\n }\n }\n\n /**\n * Scroll to the next section\n */\n scrollToNextSection() {\n // Find the next section index\n // check if index is greater to currentSectionIndex to avoid useless calculations\n // if yes check if visible pixels exceed the threshold\n const nextSectionIndex = this.selectors.sectionsArr\n .findIndex((section, index) => index > this.state.currentSectionIndex\n && this.getVisiblePixels(section, 'down') > this.options.topThreshold);\n\n if (nextSectionIndex !== -1) {\n // If nextSectionIndex is found snap to section and update currentSectionIndex\n this.snapToSection(this.selectors.sectionsArr[nextSectionIndex]);\n\n this.state.currentSectionIndex = nextSectionIndex;\n }\n }\n\n /**\n * Scroll to the previous section\n */\n scrollToPrevSection() {\n if (this.state.currentSectionIndex <= 0) {\n // If user scrolls up above the first snappable section set the current index to -1\n // to trigger the scroll snap to the first section later when he scrolls down\n this.state.currentSectionIndex = -1;\n return;\n }\n\n // Find the previous section index\n // check if index is less than currentSectionIndex to avoid useless calculations\n // if yes check if visible pixels exceed the threshold\n const prevSectionIndex = this.selectors.sectionsArr\n .findLastIndex((section, index) => index < this.state.currentSectionIndex\n && this.getVisiblePixels(section, 'up') > this.options.bottomThreshold);\n\n if (prevSectionIndex !== -1) {\n // If prevSectionIndex is found snap to section and update currentSectionIndex\n this.snapToSection(this.selectors.sectionsArr[prevSectionIndex]);\n\n this.state.currentSectionIndex = prevSectionIndex;\n }\n }\n\n /**\n * Snap to section action\n * @param {HTMLElement} section element you want to scroll to\n */\n snapToSection(section) {\n if (this.state.isScrollSnapping) {\n // Do nothing if the previous scroll snapping action is not finished\n return;\n }\n this.state.isScrollSnapping = true;\n scrollTo(section, this.state.scrollTopOffset);\n // Freeze scroll snapping actions for the moment of animation to avoid trigering snapping of the next section\n // as a result of scroll snapping itself. The scroll snapping should be triggered by user's scroll only\n if ('onscrollend' in document) {\n once('scrollend', window, () => {\n this.state.isScrollSnapping = false;\n });\n } else {\n // Fallback function for browsers not supporting 'scrollend' event natively (e.g. Safari)\n this.waitForScrollEnd().then(() => {\n this.state.isScrollSnapping = false;\n });\n }\n }\n\n /**\n * Window Scroll event callback\n */\n onScroll() {\n if (!this.selectors.sections.length > 0 || !this.state.isScrollEnded) {\n return;\n }\n if (this.state.isScrollSnapping) {\n this.state.lastScrollTop = document.documentElement.scrollTop;\n return;\n }\n\n if (this.state.isChrome) {\n // Delay the scroll snap calculation until the scroll ends\n // due to the buggy behavior of the built-in Chrome smooth scroll\n if ('onscrollend' in document) {\n once('scrollend', window, this.handleScroll.bind(this));\n } else {\n // Fallback function for browsers/OS not supporting 'scrollend' event natively (e.g. Chrome in iOS)\n this.waitForScrollEnd().then(() => {\n this.handleScroll();\n });\n }\n this.state.isScrollEnded = false;\n this.state.lastScrollTop = document.documentElement.scrollTop;\n } else {\n this.handleScroll();\n }\n }\n\n\n /**\n * Scroll event callback\n *\n */\n handleScroll() {\n this.state.isScrollEnded = true;\n\n // Determine scroll direction\n const scrollDown = document.documentElement.scrollTop > this.state.lastScrollTop;\n if (scrollDown) {\n this.scrollToNextSection();\n } else {\n this.scrollToPrevSection();\n }\n\n this.state.lastScrollTop = document.documentElement.scrollTop;\n }\n\n /**\n * Waiting for scroll end polyfill for browser not supporting scrollend event (e.g. Safari)\n * Usage: this.waitForScrollEnd().then(() => this.handleScroll());\n * @returns {Promise} - promise object\n */\n waitForScrollEnd() {\n let lastChangedFrame = 0;\n let lastX = window.scrollX;\n let lastY = window.scrollY;\n\n return new Promise((resolve) => {\n /**\n * We requestAnimationFrame either for 500 frames or until 20 frames with no change have been observed.\n * @param {number} frames - number of frames\n */\n function tick(frames) {\n if (frames >= 500 || frames - lastChangedFrame > 20) {\n resolve();\n } else {\n if (window.scrollX !== lastX || window.scrollY !== lastY) {\n lastChangedFrame = frames;\n lastX = window.scrollX;\n lastY = window.scrollY;\n }\n requestAnimationFrame(tick.bind(null, frames + 1));\n }\n }\n tick(0);\n });\n }\n\n /**\n * Destroy is called automatically after the component is being removed from the DOM\n * You must always destroy the listeners attached to an element to avoid any memory leaks\n */\n destroy() {\n if (this.selectors.sections.length > 0) {\n Event.removeListener('header.updateHeight', this.onEvent, this);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}