UNPKG

electron-react-boilerplate

Version:

Electron application boilerplate based on React, React Router, Webpack, React Hot Loader for rapid application development

266 lines (209 loc) 7.7 kB
'use strict'; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; import warning from 'warning'; import deepEqual from 'deep-equal'; import { parsePath } from './PathUtils'; import { loopAsync } from './AsyncUtils'; import { PUSH, REPLACE, POP } from './Actions'; import _createLocation from './createLocation'; import runTransitionHook from './runTransitionHook'; import deprecate from './deprecate'; function createRandomKey(length) { return Math.random().toString(36).substr(2, length); } function locationsAreEqual(a, b) { return a.pathname === b.pathname && a.search === b.search && //a.action === b.action && // Different action !== location change. a.key === b.key && deepEqual(a.state, b.state); } var DefaultKeyLength = 6; function createHistory() { var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var getCurrentLocation = options.getCurrentLocation; var finishTransition = options.finishTransition; var saveState = options.saveState; var go = options.go; var getUserConfirmation = options.getUserConfirmation; var keyLength = options.keyLength; if (typeof keyLength !== 'number') keyLength = DefaultKeyLength; var transitionHooks = []; function listenBefore(hook) { transitionHooks.push(hook); return function () { transitionHooks = transitionHooks.filter(function (item) { return item !== hook; }); }; } var allKeys = []; var changeListeners = []; var location = undefined; function getCurrent() { if (pendingLocation && pendingLocation.action === POP) { return allKeys.indexOf(pendingLocation.key); } else if (location) { return allKeys.indexOf(location.key); } else { return -1; } } function updateLocation(newLocation) { var current = getCurrent(); location = newLocation; if (location.action === PUSH) { allKeys = [].concat(allKeys.slice(0, current + 1), [location.key]); } else if (location.action === REPLACE) { allKeys[current] = location.key; } changeListeners.forEach(function (listener) { listener(location); }); } function listen(listener) { changeListeners.push(listener); if (location) { listener(location); } else { var _location = getCurrentLocation(); allKeys = [_location.key]; updateLocation(_location); } return function () { changeListeners = changeListeners.filter(function (item) { return item !== listener; }); }; } function confirmTransitionTo(location, callback) { loopAsync(transitionHooks.length, function (index, next, done) { runTransitionHook(transitionHooks[index], location, function (result) { if (result != null) { done(result); } else { next(); } }); }, function (message) { if (getUserConfirmation && typeof message === 'string') { getUserConfirmation(message, function (ok) { callback(ok !== false); }); } else { callback(message !== false); } }); } var pendingLocation = undefined; function transitionTo(nextLocation) { if (location && locationsAreEqual(location, nextLocation)) return; // Nothing to do. pendingLocation = nextLocation; confirmTransitionTo(nextLocation, function (ok) { if (pendingLocation !== nextLocation) return; // Transition was interrupted. if (ok) { // treat PUSH to current path like REPLACE to be consistent with browsers if (nextLocation.action === PUSH) { var prevPath = createPath(location); var nextPath = createPath(nextLocation); if (nextPath === prevPath && deepEqual(location.state, nextLocation.state)) nextLocation.action = REPLACE; } if (finishTransition(nextLocation) !== false) updateLocation(nextLocation); } else if (location && nextLocation.action === POP) { var prevIndex = allKeys.indexOf(location.key); var nextIndex = allKeys.indexOf(nextLocation.key); if (prevIndex !== -1 && nextIndex !== -1) go(prevIndex - nextIndex); // Restore the URL. } }); } function push(location) { transitionTo(createLocation(location, PUSH, createKey())); } function replace(location) { transitionTo(createLocation(location, REPLACE, createKey())); } function goBack() { go(-1); } function goForward() { go(1); } function createKey() { return createRandomKey(keyLength); } function createPath(location) { if (location == null || typeof location === 'string') return location; var pathname = location.pathname; var search = location.search; var hash = location.hash; var result = pathname; if (search) result += search; if (hash) result += hash; return result; } function createHref(location) { return createPath(location); } function createLocation(location, action) { var key = arguments.length <= 2 || arguments[2] === undefined ? createKey() : arguments[2]; if (typeof action === 'object') { process.env.NODE_ENV !== 'production' ? warning(false, 'The state (2nd) argument to history.createLocation is deprecated; use a ' + 'location descriptor instead') : undefined; if (typeof location === 'string') location = parsePath(location); location = _extends({}, location, { state: action }); action = key; key = arguments[3] || createKey(); } return _createLocation(location, action, key); } // deprecated function setState(state) { if (location) { updateLocationState(location, state); updateLocation(location); } else { updateLocationState(getCurrentLocation(), state); } } function updateLocationState(location, state) { location.state = _extends({}, location.state, state); saveState(location.key, location.state); } // deprecated function registerTransitionHook(hook) { if (transitionHooks.indexOf(hook) === -1) transitionHooks.push(hook); } // deprecated function unregisterTransitionHook(hook) { transitionHooks = transitionHooks.filter(function (item) { return item !== hook; }); } // deprecated function pushState(state, path) { if (typeof path === 'string') path = parsePath(path); push(_extends({ state: state }, path)); } // deprecated function replaceState(state, path) { if (typeof path === 'string') path = parsePath(path); replace(_extends({ state: state }, path)); } return { listenBefore: listenBefore, listen: listen, transitionTo: transitionTo, push: push, replace: replace, go: go, goBack: goBack, goForward: goForward, createKey: createKey, createPath: createPath, createHref: createHref, createLocation: createLocation, setState: deprecate(setState, 'setState is deprecated; use location.key to save state instead'), registerTransitionHook: deprecate(registerTransitionHook, 'registerTransitionHook is deprecated; use listenBefore instead'), unregisterTransitionHook: deprecate(unregisterTransitionHook, 'unregisterTransitionHook is deprecated; use the callback returned from listenBefore instead'), pushState: deprecate(pushState, 'pushState is deprecated; use push instead'), replaceState: deprecate(replaceState, 'replaceState is deprecated; use replace instead') }; } export default createHistory;