// Source from https://github.com/alitaheri/normalize-scroll-left let cachedType; /** * Based on the jquery plugin https://github.com/othree/jquery.rtl-scroll-type * * Types of scrollLeft, assuming scrollWidth=100 and direction is rtl. * * Type | <- Most Left | Most Right -> | Initial * ---------------- | ------------ | ------------- | ------- * default | 0 | 100 | 100 * negative (spec*) | -100 | 0 | 0 * reverse | 100 | 0 | 0 * * Edge 85: default * Safari 14: negative * Chrome 85: negative * Firefox 81: negative * IE11: reverse * * spec* https://drafts.csswg.org/cssom-view/#dom-window-scroll */ export function detectScrollType() { if (cachedType) { return cachedType; } const dummy = document.createElement('div'); const container = document.createElement('div'); container.style.width = '10px'; container.style.height = '1px'; dummy.appendChild(container); dummy.dir = 'rtl'; dummy.style.fontSize = '14px'; dummy.style.width = '4px'; dummy.style.height = '1px'; dummy.style.position = 'absolute'; dummy.style.top = '-1000px'; dummy.style.overflow = 'scroll'; document.body.appendChild(dummy); cachedType = 'reverse'; if (dummy.scrollLeft > 0) { cachedType = 'default'; } else { dummy.scrollLeft = 1; if (dummy.scrollLeft === 0) { cachedType = 'negative'; } } document.body.removeChild(dummy); return cachedType; } // Based on https://stackoverflow.com/a/24394376 export function getNormalizedScrollLeft(element, direction) { const scrollLeft = element.scrollLeft; // Perform the calculations only when direction is rtl to avoid messing up the ltr behavior if (direction !== 'rtl') { return scrollLeft; } const type = detectScrollType(); switch (type) { case 'negative': return element.scrollWidth - element.clientWidth + scrollLeft; case 'reverse': return element.scrollWidth - element.clientWidth - scrollLeft; default: return scrollLeft; } }