From 7388d0c0573b6d6bab43baa1f66fd7e59385bcea Mon Sep 17 00:00:00 2001 From: MichaelWest22 Date: Tue, 17 Jun 2025 11:08:34 +1200 Subject: [PATCH] Move History storage to sessionStorage (#3305) * Move History storage to sessionStorage and history path to window * Fix type warnings * Revert currentPathForHistory to move it to its own PR * fix test --- src/htmx.js | 18 +++--- test/attributes/hx-history.js | 8 +-- test/attributes/hx-push-url.js | 60 +++++++++---------- test/attributes/hx-replace-url.js | 8 +-- test/core/perf.js | 8 +-- test/manual/history/index.html | 4 +- test/manual/history_regression/index.html | 4 +- .../manual/history_regression/test/index.html | 4 +- test/manual/history_regression2/index.html | 4 +- test/manual/history_regression2/page2.html | 4 +- test/manual/history_safari_ios_bug/index.html | 4 +- test/manual/history_safari_ios_bug/page2.html | 4 +- test/manual/history_safari_ios_bug/page3.html | 4 +- test/manual/history_style/index.html | 4 +- test/util/scratch_server.js | 6 +- 15 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/htmx.js b/src/htmx.js index 55d8fb73..df4bf12f 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -82,7 +82,7 @@ var htmx = (function() { */ historyEnabled: true, /** - * The number of pages to keep in **localStorage** for history support. + * The number of pages to keep in **sessionStorage** for history support. * @type number * @default 10 */ @@ -819,10 +819,10 @@ var htmx = (function() { * @returns {boolean} */ function canAccessLocalStorage() { - const test = 'htmx:localStorageTest' + const test = 'htmx:sessionStorageTest' try { - localStorage.setItem(test, test) - localStorage.removeItem(test) + sessionStorage.setItem(test, test) + sessionStorage.removeItem(test) return true } catch (e) { return false @@ -3137,13 +3137,13 @@ var htmx = (function() { if (htmx.config.historyCacheSize <= 0) { // make sure that an eventually already existing cache is purged - localStorage.removeItem('htmx-history-cache') + sessionStorage.removeItem('htmx-history-cache') return } url = normalizePath(url) - const historyCache = parseJSON(localStorage.getItem('htmx-history-cache')) || [] + const historyCache = parseJSON(sessionStorage.getItem('htmx-history-cache')) || [] for (let i = 0; i < historyCache.length; i++) { if (historyCache[i].url === url) { historyCache.splice(i, 1) @@ -3164,7 +3164,7 @@ var htmx = (function() { // keep trying to save the cache until it succeeds or is empty while (historyCache.length > 0) { try { - localStorage.setItem('htmx-history-cache', JSON.stringify(historyCache)) + sessionStorage.setItem('htmx-history-cache', JSON.stringify(historyCache)) break } catch (e) { triggerErrorEvent(getDocument().body, 'htmx:historyCacheError', { cause: e, cache: historyCache }) @@ -3192,7 +3192,7 @@ var htmx = (function() { url = normalizePath(url) - const historyCache = parseJSON(localStorage.getItem('htmx-history-cache')) || [] + const historyCache = parseJSON(sessionStorage.getItem('htmx-history-cache')) || [] for (let i = 0; i < historyCache.length; i++) { if (historyCache[i].url === url) { return historyCache[i] @@ -3226,7 +3226,7 @@ var htmx = (function() { // is present *anywhere* in the current document we're about to save, // so we can prevent privileged data entering the cache. // The page will still be reachable as a history entry, but htmx will fetch it - // live from the server onpopstate rather than look in the localStorage cache + // live from the server onpopstate rather than look in the sessionStorage cache const disableHistoryCache = getDocument().querySelector('[hx-history="false" i],[data-hx-history="false" i]') if (!disableHistoryCache) { triggerEvent(getDocument().body, 'htmx:beforeHistorySave', { path, historyElt: elt }) diff --git a/test/attributes/hx-history.js b/test/attributes/hx-history.js index 2df7d1b3..f92a2ee8 100644 --- a/test/attributes/hx-history.js +++ b/test/attributes/hx-history.js @@ -4,12 +4,12 @@ describe('hx-history attribute', function() { beforeEach(function() { this.server = makeServer() clearWorkArea() - localStorage.removeItem(HTMX_HISTORY_CACHE_NAME) + sessionStorage.removeItem(HTMX_HISTORY_CACHE_NAME) }) afterEach(function() { this.server.restore() clearWorkArea() - localStorage.removeItem(HTMX_HISTORY_CACHE_NAME) + sessionStorage.removeItem(HTMX_HISTORY_CACHE_NAME) }) it('history cache should not contain embargoed content', function() { @@ -32,8 +32,8 @@ describe('hx-history attribute', function() { this.server.respond() workArea.textContent.should.equal('test3') - // embargoed content should NOT be in the localStorage cache - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + // embargoed content should NOT be in the sessionStorage cache + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(2) // on history navigation, embargoed content is retrieved from server diff --git a/test/attributes/hx-push-url.js b/test/attributes/hx-push-url.js index 80ae0f79..fd70fcd2 100644 --- a/test/attributes/hx-push-url.js +++ b/test/attributes/hx-push-url.js @@ -5,12 +5,12 @@ describe('hx-push-url attribute', function() { beforeEach(function() { this.server = makeServer() clearWorkArea() - localStorage.removeItem(HTMX_HISTORY_CACHE_NAME) + sessionStorage.removeItem(HTMX_HISTORY_CACHE_NAME) }) afterEach(function() { this.server.restore() clearWorkArea() - localStorage.removeItem(HTMX_HISTORY_CACHE_NAME) + sessionStorage.removeItem(HTMX_HISTORY_CACHE_NAME) }) it('navigation should push an element into the cache when true', function() { @@ -22,7 +22,7 @@ describe('hx-push-url attribute', function() { div.click() this.server.respond() getWorkArea().textContent.should.equal('second') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache[cache.length - 1].url.should.equal('/test') }) @@ -35,7 +35,7 @@ describe('hx-push-url attribute', function() { div.click() this.server.respond() getWorkArea().textContent.should.equal('second') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) should.equal(cache, null) }) @@ -48,7 +48,7 @@ describe('hx-push-url attribute', function() { div.click() this.server.respond() getWorkArea().textContent.should.equal('second') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(2) cache[1].url.should.equal('/abc123') }) @@ -68,7 +68,7 @@ describe('hx-push-url attribute', function() { this.server.respond() workArea.textContent.should.equal('test2') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(2) htmx._('restoreHistory')('/test1') @@ -106,7 +106,7 @@ describe('hx-push-url attribute', function() { byId('d1').click() this.server.respond() } - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(10) // should only be 10 elements }) @@ -125,10 +125,10 @@ describe('hx-push-url attribute', function() { this.server.respond() workArea.textContent.should.equal('test2') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(2) - localStorage.removeItem(HTMX_HISTORY_CACHE_NAME) // clear cache + sessionStorage.removeItem(HTMX_HISTORY_CACHE_NAME) // clear cache htmx._('restoreHistory')('/test1') this.server.respond() getWorkArea().textContent.should.equal('test1') @@ -138,7 +138,7 @@ describe('hx-push-url attribute', function() { htmx.config.refreshOnHistoryMiss = true var refresh = false htmx.location = { reload: function() { refresh = true } } - localStorage.removeItem(HTMX_HISTORY_CACHE_NAME) // clear cache + sessionStorage.removeItem(HTMX_HISTORY_CACHE_NAME) // clear cache htmx._('restoreHistory')('/test3') refresh.should.equal(true) htmx.location = window.location @@ -152,20 +152,20 @@ describe('hx-push-url attribute', function() { div.click() this.server.respond() getWorkArea().textContent.should.equal('second') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(1) }) it('deals with malformed JSON in history cache when getting', function() { - localStorage.setItem(HTMX_HISTORY_CACHE_NAME, 'Invalid JSON') + sessionStorage.setItem(HTMX_HISTORY_CACHE_NAME, 'Invalid JSON') var history = htmx._('getCachedHistory')('url') should.equal(history, null) }) it('deals with malformed JSON in history cache when saving', function() { - localStorage.setItem(HTMX_HISTORY_CACHE_NAME, 'Invalid JSON') + sessionStorage.setItem(HTMX_HISTORY_CACHE_NAME, 'Invalid JSON') htmx._('saveToHistoryCache')('url', make('
')) - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(1) }) @@ -174,17 +174,17 @@ describe('hx-push-url attribute', function() { htmx._('saveToHistoryCache')('url2', make('
')) htmx._('saveToHistoryCache')('url3', make('
')) htmx._('saveToHistoryCache')('url2', make('
')) - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(3) }) it('setting history cache size to 0 clears cache', function() { htmx._('saveToHistoryCache')('url1', make('
')) - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(1) htmx.config.historyCacheSize = 0 htmx._('saveToHistoryCache')('url2', make('
')) - cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) should.equal(cache, null) htmx.config.historyCacheSize = 10 }) @@ -195,7 +195,7 @@ describe('hx-push-url attribute', function() { htmx._('saveToHistoryCache')('url3', make('
')) htmx._('saveToHistoryCache')('url2', make('
')) htmx._('saveToHistoryCache')('url1', make('
')) - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(3) cache[0].url.should.equal('/url3') cache[1].url.should.equal('/url2') @@ -246,19 +246,19 @@ describe('hx-push-url attribute', function() { bigContent += bigContent } try { - localStorage.removeItem('htmx-history-cache') + sessionStorage.removeItem('htmx-history-cache') htmx._('saveToHistoryCache')('/dummy', make('
' + bigContent + '
'), 'Foo', 0) - should.equal(localStorage.getItem('htmx-history-cache'), null) + should.equal(sessionStorage.getItem('htmx-history-cache'), null) } finally { // clear history cache afterwards - localStorage.removeItem('htmx-history-cache') + sessionStorage.removeItem('htmx-history-cache') } }) if (/chrome/i.test(navigator.userAgent)) { - it('when localStorage disabled history not saved fine', function() { - var setItem = localStorage.setItem - localStorage.setItem = undefined + it('when sessionStorage disabled history not saved fine', function() { + var setItem = sessionStorage.setItem + sessionStorage.setItem = undefined this.server.respondWith('GET', '/test', 'second') getWorkArea().innerHTML.should.be.equal('') var div = make('
first
') @@ -269,7 +269,7 @@ describe('hx-push-url attribute', function() { getWorkArea().textContent.should.equal('second') var hist = htmx._('getCachedHistory')('/test') should.equal(hist, null) - localStorage.setItem = setItem + sessionStorage.setItem = setItem }) } @@ -277,7 +277,7 @@ describe('hx-push-url attribute', function() { // path normalization has a bug breaking it right now preventing this test htmx._('saveToHistoryCache')('http://', make('
')) htmx._('saveToHistoryCache')('http//', make('
')) - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(2) cache[0].url.should.equal('http://') // no normalization as invalid cache[1].url.should.equal('/http') // can normalize this one @@ -285,7 +285,7 @@ describe('hx-push-url attribute', function() { it('history cache clears out disabled attribute', function() { htmx._('saveToHistoryCache')('/url1', make('
')) - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(1) cache[0].url.should.equal('/url1') cache[0].content.should.equal('
') @@ -337,7 +337,7 @@ describe('hx-push-url attribute', function() { div1.click() this.server.respond() div1.innerHTML.should.equal('Result') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(1) path.should.equal('/pushpath') htmx.off('htmx:pushedIntoHistory', handler) @@ -353,7 +353,7 @@ describe('hx-push-url attribute', function() { div1.click() this.server.respond() div1.innerHTML.should.equal('Result') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(1) path.should.equal('/pushpath') htmx.off('htmx:pushedIntoHistory', handler) @@ -369,7 +369,7 @@ describe('hx-push-url attribute', function() { div1.click() this.server.respond() div1.innerHTML.should.equal('Result') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) should.equal(cache, null) path.should.equal('') htmx.off('htmx:pushedIntoHistory', handler) diff --git a/test/attributes/hx-replace-url.js b/test/attributes/hx-replace-url.js index 70f5d1ea..3661a2f8 100644 --- a/test/attributes/hx-replace-url.js +++ b/test/attributes/hx-replace-url.js @@ -4,12 +4,12 @@ describe('hx-replace-url attribute', function() { beforeEach(function() { this.server = makeServer() clearWorkArea() - localStorage.removeItem(HTMX_HISTORY_CACHE_NAME) + sessionStorage.removeItem(HTMX_HISTORY_CACHE_NAME) }) afterEach(function() { this.server.restore() clearWorkArea() - localStorage.removeItem(HTMX_HISTORY_CACHE_NAME) + sessionStorage.removeItem(HTMX_HISTORY_CACHE_NAME) }) it('navigation should replace an element into the cache when true', function() { @@ -21,7 +21,7 @@ describe('hx-replace-url attribute', function() { div.click() this.server.respond() getWorkArea().textContent.should.equal('second') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache[cache.length - 1].url.should.equal('/test') }) @@ -35,7 +35,7 @@ describe('hx-replace-url attribute', function() { div1.click() this.server.respond() div1.innerHTML.should.equal('Result') - var cache = JSON.parse(localStorage.getItem(HTMX_HISTORY_CACHE_NAME)) + var cache = JSON.parse(sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME)) cache.length.should.equal(1) path.should.equal('/pushpath') htmx.off('htmx:replacedInHistory', handler) diff --git a/test/core/perf.js b/test/core/perf.js index 3d2cd565..1d14f8db 100644 --- a/test/core/perf.js +++ b/test/core/perf.js @@ -5,12 +5,12 @@ describe('Core htmx perf Tests', function() { beforeEach(function() { this.server = makeServer() clearWorkArea() - localStorage.removeItem(HTMX_HISTORY_CACHE_NAME) + sessionStorage.removeItem(HTMX_HISTORY_CACHE_NAME) }) afterEach(function() { this.server.restore() clearWorkArea() - localStorage.removeItem(HTMX_HISTORY_CACHE_NAME) + sessionStorage.removeItem(HTMX_HISTORY_CACHE_NAME) }) function stringRepeat(str, num) { @@ -39,8 +39,8 @@ describe('Core htmx perf Tests', function() { } var start = performance.now() var string = JSON.stringify(array) - localStorage.setItem(HTMX_HISTORY_CACHE_NAME, string) - var reReadString = localStorage.getItem(HTMX_HISTORY_CACHE_NAME) + sessionStorage.setItem(HTMX_HISTORY_CACHE_NAME, string) + var reReadString = sessionStorage.getItem(HTMX_HISTORY_CACHE_NAME) var finalJson = JSON.parse(reReadString) var end = performance.now() var timeInMs = end - start diff --git a/test/manual/history/index.html b/test/manual/history/index.html index d1462194..c49f0d58 100644 --- a/test/manual/history/index.html +++ b/test/manual/history/index.html @@ -7,9 +7,9 @@ diff --git a/test/manual/history_regression/index.html b/test/manual/history_regression/index.html index b9de0e7e..36718cf4 100644 --- a/test/manual/history_regression/index.html +++ b/test/manual/history_regression/index.html @@ -6,9 +6,9 @@ diff --git a/test/manual/history_regression/test/index.html b/test/manual/history_regression/test/index.html index 20650e42..d9493541 100644 --- a/test/manual/history_regression/test/index.html +++ b/test/manual/history_regression/test/index.html @@ -6,9 +6,9 @@ diff --git a/test/manual/history_regression2/index.html b/test/manual/history_regression2/index.html index 8d9480d6..8a3c7b24 100644 --- a/test/manual/history_regression2/index.html +++ b/test/manual/history_regression2/index.html @@ -6,9 +6,9 @@ diff --git a/test/manual/history_regression2/page2.html b/test/manual/history_regression2/page2.html index b72c59b2..f7b35ab7 100644 --- a/test/manual/history_regression2/page2.html +++ b/test/manual/history_regression2/page2.html @@ -6,9 +6,9 @@ diff --git a/test/manual/history_safari_ios_bug/index.html b/test/manual/history_safari_ios_bug/index.html index add271df..ec45b951 100644 --- a/test/manual/history_safari_ios_bug/index.html +++ b/test/manual/history_safari_ios_bug/index.html @@ -6,9 +6,9 @@ diff --git a/test/manual/history_safari_ios_bug/page2.html b/test/manual/history_safari_ios_bug/page2.html index 4da1274e..b714c759 100644 --- a/test/manual/history_safari_ios_bug/page2.html +++ b/test/manual/history_safari_ios_bug/page2.html @@ -6,9 +6,9 @@ diff --git a/test/manual/history_safari_ios_bug/page3.html b/test/manual/history_safari_ios_bug/page3.html index 225472c3..10df3306 100644 --- a/test/manual/history_safari_ios_bug/page3.html +++ b/test/manual/history_safari_ios_bug/page3.html @@ -6,9 +6,9 @@ diff --git a/test/manual/history_style/index.html b/test/manual/history_style/index.html index 87565a85..ff62d97b 100644 --- a/test/manual/history_style/index.html +++ b/test/manual/history_style/index.html @@ -7,9 +7,9 @@ diff --git a/test/util/scratch_server.js b/test/util/scratch_server.js index 8217630a..407c134c 100644 --- a/test/util/scratch_server.js +++ b/test/util/scratch_server.js @@ -1,5 +1,5 @@ var server = makeServer() -var autoRespond = localStorage.getItem('hx-scratch-autorespond') == 'true' +var autoRespond = sessionStorage.getItem('hx-scratch-autorespond') == 'true' server.autoRespond = autoRespond ready(function() { if (autoRespond) { @@ -8,10 +8,10 @@ ready(function() { }) function toggleAutoRespond() { if (server.autoRespond) { - localStorage.removeItem('hx-scratch-autorespond') + sessionStorage.removeItem('hx-scratch-autorespond') server.autoRespond = false } else { - localStorage.setItem('hx-scratch-autorespond', 'true') + sessionStorage.setItem('hx-scratch-autorespond', 'true') server.autoRespond = true } }