history.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. export function pushUrl(url, html) {
  2. updateUrl('pushState', url, html)
  3. }
  4. export function replaceUrl(url, html) {
  5. updateUrl('replaceState', url, html)
  6. }
  7. function updateUrl(method, url, html) {
  8. let key = (new Date).getTime()
  9. tryToStoreInSession(key, JSON.stringify({ html: html }))
  10. let state = Object.assign(history.state || {}, { alpine: key })
  11. // 640k character limit:
  12. history[method](state, document.title, url)
  13. }
  14. export function fromSessionStorage(event) {
  15. if (! event.state.alpine) return {}
  16. let state = JSON.parse(sessionStorage.getItem('alpine:'+event.state.alpine))
  17. return state
  18. }
  19. function tryToStoreInSession(timestamp, value) {
  20. // sessionStorage has a max storage limit (usally 5MB).
  21. // If we meet that limit, we'll start removing entries
  22. // (oldest first), until there's enough space to store
  23. // the new one.
  24. try {
  25. sessionStorage.setItem('alpine:'+timestamp, value)
  26. } catch (error) {
  27. // 22 is Chrome, 1-14 is other browsers.
  28. if (! [22, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14].includes(error.code)) return
  29. let oldestTimestamp = Object.keys(sessionStorage)
  30. .map(key => Number(key.replace('alpine:', '')))
  31. .sort()
  32. .shift()
  33. if (! oldestTimestamp) return
  34. sessionStorage.removeItem('alpine:'+oldestTimestamp)
  35. tryToStoreInSession(timestamp, value)
  36. }
  37. }