{"version":3,"file":"index.umd.min.js","sources":["../src/lib/shared.js","../src/lib/api.js","../src/lib/events.js","../src/lib/defaults.js","../src/lib/markup.js","../src/lib/styles.js","../src/lib/setup.js","../src/lib/index.js"],"sourcesContent":["const _shared = {\n pullStartY: null,\n pullMoveY: null,\n handlers: [],\n styleEl: null,\n events: null,\n dist: 0,\n state: 'pending',\n timeout: null,\n distResisted: 0,\n supportsPassive: false,\n supportsPointerEvents: !!window.PointerEvent,\n};\n\ntry {\n window.addEventListener('test', null, {\n get passive() { // eslint-disable-line getter-return\n _shared.supportsPassive = true;\n },\n });\n} catch (e) {\n // do nothing\n}\n\nexport default _shared;\n","import _shared from './shared';\n\nfunction setupDOM(handler) {\n if (!handler.ptrElement) {\n const ptr = document.createElement('div');\n\n if (handler.mainElement !== document.body) {\n handler.mainElement.parentNode.insertBefore(ptr, handler.mainElement);\n } else {\n document.body.insertBefore(ptr, document.body.firstChild);\n }\n\n ptr.classList.add(`${handler.classPrefix}ptr`);\n ptr.innerHTML = handler.getMarkup()\n .replace(/__PREFIX__/g, handler.classPrefix);\n\n handler.ptrElement = ptr;\n\n if (typeof handler.onInit === 'function') {\n handler.onInit(handler);\n }\n\n // Add the css styles to the style node, and then\n // insert it into the dom\n if (!_shared.styleEl) {\n _shared.styleEl = document.createElement('style');\n _shared.styleEl.setAttribute('id', 'pull-to-refresh-js-style');\n\n document.head.appendChild(_shared.styleEl);\n }\n\n _shared.styleEl.textContent = handler.getStyles()\n .replace(/__PREFIX__/g, handler.classPrefix)\n .replace(/\\s+/g, ' ');\n }\n\n return handler;\n}\n\nfunction onReset(handler) {\n handler.ptrElement.classList.remove(`${handler.classPrefix}refresh`);\n handler.ptrElement.style[handler.cssProp] = '0px';\n\n setTimeout(() => {\n // remove previous ptr-element from DOM\n if (handler.ptrElement && handler.ptrElement.parentNode) {\n handler.ptrElement.parentNode.removeChild(handler.ptrElement);\n handler.ptrElement = null;\n }\n\n // reset state\n _shared.state = 'pending';\n }, handler.refreshTimeout);\n}\n\nfunction update(handler) {\n const iconEl = handler.ptrElement.querySelector(`.${handler.classPrefix}icon`);\n const textEl = handler.ptrElement.querySelector(`.${handler.classPrefix}text`);\n\n if (iconEl) {\n if (_shared.state === 'refreshing') {\n iconEl.innerHTML = handler.iconRefreshing;\n } else {\n iconEl.innerHTML = handler.iconArrow;\n }\n }\n\n if (textEl) {\n if (_shared.state === 'releasing') {\n textEl.innerHTML = handler.instructionsReleaseToRefresh;\n }\n\n if (_shared.state === 'pulling' || _shared.state === 'pending') {\n textEl.innerHTML = handler.instructionsPullToRefresh;\n }\n\n if (_shared.state === 'refreshing') {\n textEl.innerHTML = handler.instructionsRefreshing;\n }\n }\n}\n\nexport default {\n setupDOM,\n onReset,\n update,\n};\n","import _ptr from './api';\nimport _shared from './shared';\n\nconst screenY = function screenY(event) {\n if (_shared.pointerEventsEnabled && _shared.supportsPointerEvents) {\n return event.screenY;\n }\n return event.touches[0].screenY;\n};\n\nexport default () => {\n let _el;\n\n function _onTouchStart(e) {\n // here, we must pick a handler first, and then append their html/css on the DOM\n const target = _shared.handlers.filter(h => h.contains(e.target))[0];\n\n _shared.enable = !!target;\n\n if (target && _shared.state === 'pending') {\n _el = _ptr.setupDOM(target);\n\n if (target.shouldPullToRefresh()) {\n _shared.pullStartY = screenY(e);\n }\n\n clearTimeout(_shared.timeout);\n\n _ptr.update(target);\n }\n }\n\n function _onTouchMove(e) {\n if (!(_el && _el.ptrElement && _shared.enable)) {\n return;\n }\n\n if (!_shared.pullStartY) {\n if (_el.shouldPullToRefresh()) {\n _shared.pullStartY = screenY(e);\n }\n } else {\n _shared.pullMoveY = screenY(e);\n }\n\n if (_shared.state === 'refreshing') {\n if (e.cancelable && _el.shouldPullToRefresh() && _shared.pullStartY < _shared.pullMoveY) {\n e.preventDefault();\n }\n\n return;\n }\n\n if (_shared.state === 'pending') {\n _el.ptrElement.classList.add(`${_el.classPrefix}pull`);\n _shared.state = 'pulling';\n _ptr.update(_el);\n }\n\n if (_shared.pullStartY && _shared.pullMoveY) {\n _shared.dist = _shared.pullMoveY - _shared.pullStartY;\n }\n\n _shared.distExtra = _shared.dist - _el.distIgnore;\n\n if (_shared.distExtra > 0) {\n if (e.cancelable) {\n e.preventDefault();\n }\n\n _el.ptrElement.style[_el.cssProp] = `${_shared.distResisted}px`;\n\n _shared.distResisted = _el.resistanceFunction(_shared.distExtra / _el.distThreshold)\n * Math.min(_el.distMax, _shared.distExtra);\n\n if (_shared.state === 'pulling' && _shared.distResisted > _el.distThreshold) {\n _el.ptrElement.classList.add(`${_el.classPrefix}release`);\n _shared.state = 'releasing';\n _ptr.update(_el);\n }\n\n if (_shared.state === 'releasing' && _shared.distResisted < _el.distThreshold) {\n _el.ptrElement.classList.remove(`${_el.classPrefix}release`);\n _shared.state = 'pulling';\n _ptr.update(_el);\n }\n }\n }\n\n function _onTouchEnd() {\n if (!(_el && _el.ptrElement && _shared.enable)) {\n return;\n }\n\n if (_shared.state === 'releasing' && _shared.distResisted > _el.distThreshold) {\n _shared.state = 'refreshing';\n\n _el.ptrElement.style[_el.cssProp] = `${_el.distReload}px`;\n _el.ptrElement.classList.add(`${_el.classPrefix}refresh`);\n\n _shared.timeout = setTimeout(() => {\n const retval = _el.onRefresh(() => _ptr.onReset(_el));\n\n if (retval && typeof retval.then === 'function') {\n retval.then(() => _ptr.onReset(_el));\n }\n\n if (!retval && !_el.onRefresh.length) {\n _ptr.onReset(_el);\n }\n }, _el.refreshTimeout);\n } else {\n if (_shared.state === 'refreshing') {\n return;\n }\n\n _el.ptrElement.style[_el.cssProp] = '0px';\n\n _shared.state = 'pending';\n }\n\n _ptr.update(_el);\n\n _el.ptrElement.classList.remove(`${_el.classPrefix}release`);\n _el.ptrElement.classList.remove(`${_el.classPrefix}pull`);\n\n _shared.pullStartY = _shared.pullMoveY = null;\n _shared.dist = _shared.distResisted = 0;\n }\n\n function _onScroll() {\n if (_el) {\n _el.mainElement.classList.toggle(`${_el.classPrefix}top`, _el.shouldPullToRefresh());\n }\n }\n\n const _passiveSettings = _shared.supportsPassive\n ? { passive: _shared.passive || false }\n : undefined;\n\n if (_shared.pointerEventsEnabled && _shared.supportsPointerEvents) {\n window.addEventListener('pointerup', _onTouchEnd);\n window.addEventListener('pointerdown', _onTouchStart);\n window.addEventListener('pointermove', _onTouchMove, _passiveSettings);\n } else {\n window.addEventListener('touchend', _onTouchEnd);\n window.addEventListener('touchstart', _onTouchStart);\n window.addEventListener('touchmove', _onTouchMove, _passiveSettings);\n }\n\n window.addEventListener('scroll', _onScroll);\n\n return {\n onTouchEnd: _onTouchEnd,\n onTouchStart: _onTouchStart,\n onTouchMove: _onTouchMove,\n onScroll: _onScroll,\n\n destroy() {\n if (_shared.pointerEventsEnabled && _shared.supportsPointerEvents) {\n window.removeEventListener('pointerdown', _onTouchStart);\n window.removeEventListener('pointerup', _onTouchEnd);\n window.removeEventListener('pointermove', _onTouchMove, _passiveSettings);\n } else {\n window.removeEventListener('touchstart', _onTouchStart);\n window.removeEventListener('touchend', _onTouchEnd);\n window.removeEventListener('touchmove', _onTouchMove, _passiveSettings);\n }\n\n window.removeEventListener('scroll', _onScroll);\n },\n };\n};\n","import _ptrMarkup from './markup';\nimport _ptrStyles from './styles';\n\nexport default {\n distThreshold: 60,\n distMax: 80,\n distReload: 50,\n distIgnore: 0,\n mainElement: 'body',\n triggerElement: 'body',\n ptrElement: '.ptr',\n classPrefix: 'ptr--',\n cssProp: 'min-height',\n iconArrow: '⇣',\n iconRefreshing: '…',\n instructionsPullToRefresh: 'Pull down to refresh',\n instructionsReleaseToRefresh: 'Release to refresh',\n instructionsRefreshing: 'Refreshing',\n refreshTimeout: 500,\n getMarkup: () => _ptrMarkup,\n getStyles: () => _ptrStyles,\n onInit: () => {},\n onRefresh: () => location.reload(),\n resistanceFunction: t => Math.min(1, t / 2.5),\n shouldPullToRefresh: () => !window.scrollY,\n};\n","export default `\n