9e23d70d47d7779ac126b7aa1d5e01b410da0f32daf1e00e39c9329f1733aa9fceb164b2e330d97ee4219a4dbf92ce5e0f1d8f6e2ce05848196fdbb7946c30 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. /* @flow */
  2. import { inBrowser } from './dom'
  3. import { saveScrollPosition } from './scroll'
  4. import { genStateKey, setStateKey, getStateKey } from './state-key'
  5. import { extend } from './misc'
  6. export const supportsPushState =
  7. inBrowser &&
  8. (function () {
  9. const ua = window.navigator.userAgent
  10. if (
  11. (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
  12. ua.indexOf('Mobile Safari') !== -1 &&
  13. ua.indexOf('Chrome') === -1 &&
  14. ua.indexOf('Windows Phone') === -1
  15. ) {
  16. return false
  17. }
  18. return window.history && typeof window.history.pushState === 'function'
  19. })()
  20. export function pushState (url?: string, replace?: boolean) {
  21. saveScrollPosition()
  22. // try...catch the pushState call to get around Safari
  23. // DOM Exception 18 where it limits to 100 pushState calls
  24. const history = window.history
  25. try {
  26. if (replace) {
  27. // preserve existing history state as it could be overriden by the user
  28. const stateCopy = extend({}, history.state)
  29. stateCopy.key = getStateKey()
  30. history.replaceState(stateCopy, '', url)
  31. } else {
  32. history.pushState({ key: setStateKey(genStateKey()) }, '', url)
  33. }
  34. } catch (e) {
  35. window.location[replace ? 'replace' : 'assign'](url)
  36. }
  37. }
  38. export function replaceState (url?: string) {
  39. pushState(url, true)
  40. }