UNPKG

react-view-router

Version:
320 lines (317 loc) 11.2 kB
import "core-js/modules/es6.symbol.js"; import "core-js/modules/es6.array.filter.js"; import "core-js/modules/es7.object.get-own-property-descriptors.js"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import "core-js/modules/es6.regexp.search.js"; import { Action, HistoryType } from './types'; import { createPath, freeze, createEvents, parsePath, createKey, allowTx, allowTxWithParams, copyOwnProperties } from './utils'; // const BeforeUnloadEventType = 'beforeunload'; export var HashChangeEventType = 'hashchange'; export var PopStateEventType = 'popstate'; export function createHistory(options) { var _window = options.window, type = options.type, getLocationPath = options.getLocationPath, createHref = options.createHref; var globalHistory = _window.history; function getIndexAndLocation() { var _getLocationPath = getLocationPath(), _getLocationPath$path = _getLocationPath.pathname, pathname = _getLocationPath$path === void 0 ? '/' : _getLocationPath$path, _getLocationPath$sear = _getLocationPath.search, search = _getLocationPath$sear === void 0 ? '' : _getLocationPath$sear, _getLocationPath$hash = _getLocationPath.hash, hash = _getLocationPath$hash === void 0 ? '' : _getLocationPath$hash; var state = globalHistory.state || {}; return [state.idx, freeze({ pathname, search, hash, state: state.usr || null, key: state.key || 'default' })]; } var action = Action.Push; var _getIndexAndLocation = getIndexAndLocation(), _getIndexAndLocation2 = _slicedToArray(_getIndexAndLocation, 2), index = _getIndexAndLocation2[0], location = _getIndexAndLocation2[1]; var listeners = createEvents(); var blockers = createEvents(); function getIndex(delta) { var ret = index; if (delta) ret = Math.max(index + delta, 0); return ret; } function getNextLocation(to, state = null) { return freeze(copyOwnProperties(copyOwnProperties(_objectSpread({}, location), typeof to === 'string' ? parsePath(to) : to, true), { state, key: createKey() }, true)); } function getHistoryState(nextLocation, index) { return { usr: nextLocation.state, key: nextLocation.key, idx: index }; } function getHistoryStateAndUrl(nextLocation, index) { return [getHistoryState(nextLocation, index), createHref(nextLocation)]; } function applyTx(nextAction, payload) { action = nextAction; var prevIndex = index; var _getIndexAndLocation3 = getIndexAndLocation(); var _getIndexAndLocation4 = _slicedToArray(_getIndexAndLocation3, 2); index = _getIndexAndLocation4[0]; location = _getIndexAndLocation4[1]; if (index == null && prevIndex != null) { index = nextAction === Action.Push ? prevIndex + 1 : nextAction === Action.Replace ? prevIndex : prevIndex - 1; } listeners.call({ action, index, location }, payload); } function pushHistoryState(location, index) { var _getHistoryStateAndUr = getHistoryStateAndUrl(location, index), _getHistoryStateAndUr2 = _slicedToArray(_getHistoryStateAndUr, 2), historyState = _getHistoryStateAndUr2[0], url = _getHistoryStateAndUr2[1]; // TODO: Support forced reloading // try...catch because iOS limits us to 100 pushState calls :/ try { globalHistory.pushState(historyState, '', url); } catch (error) { // They are going to lose state here, but there is no real // way to warn them about it since the page will refresh... _window.location.assign(url); } return index; } function replaceHistoryState(location, index) { var _getHistoryStateAndUr3 = getHistoryStateAndUrl(location, index), _getHistoryStateAndUr4 = _slicedToArray(_getHistoryStateAndUr3, 2), historyState = _getHistoryStateAndUr4[0], url = _getHistoryStateAndUr4[1]; // TODO: Support forced reloading globalHistory.replaceState(historyState, '', url); return index; } var blockedPopTx = null; var blockedPopAp = null; var blockedPopDc = null; function go(delta) { blockedPopTx = null; globalHistory.go(delta); } function handlePop(e) { var index = getIndex(); var _getIndexAndLocation5 = getIndexAndLocation(), _getIndexAndLocation6 = _slicedToArray(_getIndexAndLocation5, 2), nextIndex = _getIndexAndLocation6[0], nextLocation = _getIndexAndLocation6[1]; if (nextIndex == null) { if (index == null || isNaN(index)) index = 0; nextIndex = createPath(nextLocation) === createPath(location) ? index : index + 1; replaceHistoryState(nextLocation, nextIndex); if (!blockedPopAp && !blockedPopTx && nextIndex === index) return; } var delta = index - nextIndex; var nextAction = !delta ? Action.Replace : delta > 0 ? Action.Pop : Action.Push; if (blockedPopDc) { blockedPopDc({ index: nextIndex, location: nextLocation }); blockedPopDc = null; } else if (blockedPopAp) { if (nextIndex === blockedPopAp.prevIndex) { go(blockedPopAp.delta); return; } blockedPopAp.cb && blockedPopAp.cb(); blockedPopAp = null; } else if (blockers.length && delta) { var seed = 0; var callback = (ok, payload) => { if (!blockedPopTx) return; if (ok) { blockedPopTx = null; applyTx(nextAction, payload); return; } blockedPopTx.backCallback(seed); }; nextLocation.fromEvent = true; blockedPopTx = { seed, index, nextIndex, action: nextAction, location: nextLocation, callback, backCallback(seed) { if (this.seed !== seed) return; blockedPopTx = null; blockedPopAp = { action, index, location, prevIndex: nextIndex, delta }; go(blockedPopAp.delta); } }; allowTxWithParams(blockers, blockedPopTx); } else { applyTx(nextAction); } } _window.addEventListener(PopStateEventType, handlePop); if (type === HistoryType.hash) { // popstate does not fire on hashchange in IE 11 and old (trident) Edge // https://developer.mozilla.org/de/docs/Web/API/Window/popstate_event _window.addEventListener(HashChangeEventType, e => { if (blockedPopTx || blockedPopAp) return; var _getIndexAndLocation7 = getIndexAndLocation(), _getIndexAndLocation8 = _slicedToArray(_getIndexAndLocation7, 2), nextLocation = _getIndexAndLocation8[1]; // Ignore extraneous hashchange events. if (createPath(nextLocation) !== createPath(location)) { handlePop(e); } }); } if (index == null) { index = 0; globalHistory.replaceState(_objectSpread(_objectSpread({}, globalHistory.state), {}, { idx: index }), ''); } function push(to, state) { var nextAction = Action.Push; var nextLocation = getNextLocation(to, state); var seed = blockedPopTx ? ++blockedPopTx.seed : -1; var callback = (ok, payload) => { if (!ok) { if (blockedPopTx) blockedPopTx.backCallback(seed); return; } if (blockedPopTx && blockedPopTx.seed === seed) { blockedPopTx = null; } var _cb = index => { pushHistoryState(nextLocation, index + 1); applyTx(nextAction, payload); }; if (typeof to !== 'string' && to.delta) { blockedPopDc = ({ index }) => _cb(index); go(to.delta); return; } if (blockedPopAp) blockedPopAp.cb = () => _cb(index);else _cb(index); }; if (allowTx(blockers, nextAction, nextLocation, index, getIndex(typeof to !== 'string' ? to.delta : undefined) + 1, callback)) { callback(true, to); } } function replace(to, state) { var nextAction = Action.Replace; var nextLocation = getNextLocation(to, state); var seed = blockedPopTx ? ++blockedPopTx.seed : -1; var callback = (ok, payload) => { if (!ok) { if (blockedPopTx) blockedPopTx.backCallback(seed); return; } if (blockedPopTx && blockedPopTx.seed === seed) { blockedPopTx = null; } var _cb = index => { replaceHistoryState(nextLocation, index); applyTx(nextAction, payload); }; if (typeof to !== 'string' && to.delta) { blockedPopDc = ({ index }) => _cb(index); go(to.delta); return; } if (blockedPopAp) blockedPopAp.cb = () => _cb(index);else _cb(index); }; if (allowTx(blockers, nextAction, nextLocation, index, getIndex(typeof to !== 'string' ? to.delta : undefined), callback)) { callback(true); } } var history = { get extra() { return options.extra; }, get type() { return type; }, get action() { return action; }, get location() { return location; }, get index() { return index; }, get length() { return globalHistory.length; }, get state() { return getHistoryState(location, index).usr; }, get realtimeLocation() { var _getIndexAndLocation9 = getIndexAndLocation(), _getIndexAndLocation0 = _slicedToArray(_getIndexAndLocation9, 2), current = _getIndexAndLocation0[1]; return current.pathname === location.pathname && current.search === location.search && current.hash === location.hash ? location : current; }, createHref, getIndexAndLocation, push, replace, replaceState(state) { var historyState = getHistoryState(location, index); historyState.usr = state; globalHistory.replaceState(historyState, ''); return state; }, refresh() { var _getIndexAndLocation1 = getIndexAndLocation(); var _getIndexAndLocation10 = _slicedToArray(_getIndexAndLocation1, 2); index = _getIndexAndLocation10[0]; location = _getIndexAndLocation10[1]; return [index, location]; }, go, back() { go(-1); }, forward() { go(1); }, listen(listener) { return listeners.push(listener); }, block(blocker) { return blockers.push(blocker); } }; return history; } //# sourceMappingURL=history.js.map