UNPKG

react-selectize

Version:

A Stateless & Flexible Select component for React inspired by Selectize

119 lines (95 loc) 3.01 kB
import invariant from 'invariant' import { PUSH, POP } from './Actions' import { canUseDOM } from './ExecutionEnvironment' import { addEventListener, removeEventListener, getWindowPath, supportsHistory } from './DOMUtils' import { saveState, readState } from './DOMStateStorage' import createDOMHistory from './createDOMHistory' import createLocation from './createLocation' /** * Creates and returns a history object that uses HTML5's history API * (pushState, replaceState, and the popstate event) to manage history. * This is the recommended method of managing history in browsers because * it provides the cleanest URLs. * * Note: In browsers that do not support the HTML5 history API full * page reloads will be used to preserve URLs. */ function createBrowserHistory(options) { invariant( canUseDOM, 'Browser history needs a DOM' ) let isSupported = supportsHistory() function getCurrentLocation(historyState) { historyState = historyState || window.history.state || {} let path = getWindowPath() let { key } = historyState let state if (key) { state = readState(key) } else { state = null key = history.createKey() window.history.replaceState({ ...historyState, key }, null, path) } return createLocation(path, state, undefined, key) } function startPopStateListener({ transitionTo }) { function popStateListener(event) { if (event.state === undefined) return // Ignore extraneous popstate events in WebKit. transitionTo( getCurrentLocation(event.state) ) } addEventListener(window, 'popstate', popStateListener) return function () { removeEventListener(window, 'popstate', popStateListener) } } function finishTransition(location) { let { basename, pathname, search, state, action, key } = location if (action === POP) return // Nothing to do. saveState(key, state) let path = (basename || '') + pathname + search let historyState = { key } if (action === PUSH) { if (isSupported) { window.history.pushState(historyState, null, path) } else { window.location.href = path // Use page reload to preserve the URL. } } else { // REPLACE if (isSupported) { window.history.replaceState(historyState, null, path) } else { window.location.replace(path) // Use page reload to preserve the URL. } } } let history = createDOMHistory({ ...options, getCurrentLocation, finishTransition, saveState }) let listenerCount = 0, stopPopStateListener function listen(listener) { if (++listenerCount === 1) stopPopStateListener = startPopStateListener(history) let unlisten = history.listen(listener) return function () { unlisten() if (--listenerCount === 0) stopPopStateListener() } } return { ...history, listen } } export default createBrowserHistory