Skip to content

Commit e2d3656

Browse files
authored
Merge pull request #38 from Bestra/bestra/add-storage-option
Allow callers to pass in a Storage implementation
2 parents 1011459 + 662a1a7 commit e2d3656

2 files changed

Lines changed: 55 additions & 9 deletions

File tree

src/index.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@ function shouldResumeField(field: HTMLInputElement | HTMLTextAreaElement): boole
55
return !!field.id && field.value !== field.defaultValue && field.form !== submittedForm
66
}
77

8-
type PersistOptions = {selector?: string; keyPrefix?: string}
8+
type PersistOptions = {
9+
selector?: string
10+
keyPrefix?: string
11+
storage?: Pick<Storage, 'getItem' | 'setItem'>
12+
}
913

1014
// Write all ids and values of the selected fields on the page into sessionStorage.
1115
export function persistResumableFields(id: string, options?: PersistOptions): void {
1216
const selector = options?.selector ?? '.js-session-resumable'
1317
const keyPrefix = options?.keyPrefix ?? 'session-resume:'
18+
const storage = options?.storage ?? sessionStorage
1419
const key = `${keyPrefix}${id}`
1520
const resumables = []
1621

@@ -24,7 +29,7 @@ export function persistResumableFields(id: string, options?: PersistOptions): vo
2429

2530
if (fields.length) {
2631
try {
27-
const previouslyStoredFieldsJson = sessionStorage.getItem(key)
32+
const previouslyStoredFieldsJson = storage.getItem(key)
2833

2934
if (previouslyStoredFieldsJson !== null) {
3035
const previouslyStoredFields: string[][] = JSON.parse(previouslyStoredFieldsJson)
@@ -34,22 +39,23 @@ export function persistResumableFields(id: string, options?: PersistOptions): vo
3439
fields = fields.concat(fieldsNotReplaced)
3540
}
3641

37-
sessionStorage.setItem(key, JSON.stringify(fields))
42+
storage.setItem(key, JSON.stringify(fields))
3843
} catch {
3944
// Ignore browser private mode error.
4045
}
4146
}
4247
}
4348

44-
type RestoreOptions = {keyPrefix?: string}
49+
type RestoreOptions = {keyPrefix?: string; storage?: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>}
4550

4651
export function restoreResumableFields(id: string, options?: RestoreOptions): void {
4752
const keyPrefix = options?.keyPrefix ?? 'session-resume:'
53+
const storage = options?.storage ?? sessionStorage
4854
const key = `${keyPrefix}${id}`
4955
let fields
5056

5157
try {
52-
fields = sessionStorage.getItem(key)
58+
fields = storage.getItem(key)
5359
} catch {
5460
// Ignore browser private mode error.
5561
}
@@ -84,12 +90,12 @@ export function restoreResumableFields(id: string, options?: RestoreOptions): vo
8490
// they're needed.
8591
if (storedFieldsNotFound.length === 0) {
8692
try {
87-
sessionStorage.removeItem(key)
93+
storage.removeItem(key)
8894
} catch {
8995
// Ignore browser private mode error.
9096
}
9197
} else {
92-
sessionStorage.setItem(key, JSON.stringify(storedFieldsNotFound))
98+
storage.setItem(key, JSON.stringify(storedFieldsNotFound))
9399
}
94100

95101
setTimeout(function () {

test/test.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,32 @@ describe('session-resume', function () {
1414
})
1515

1616
describe('restoreResumableFields', function () {
17-
it('restores fields values from session storage', function () {
17+
it('restores fields values from session storage by default', function () {
1818
sessionStorage.setItem('session-resume:test-persist', JSON.stringify([['my-first-field', 'test2']]))
1919
restoreResumableFields('test-persist')
2020

2121
assert.equal(document.querySelector('#my-first-field').value, 'test2')
2222
assert.equal(document.querySelector('#my-second-field').value, 'second-field-value')
2323
})
2424

25+
it('uses a Storage object when provided as an option', function () {
26+
const fakeStorageBackend = {}
27+
const fakeStorage = {
28+
setItem(key, value) {
29+
fakeStorageBackend[key] = JSON.stringify(value)
30+
},
31+
getItem(key) {
32+
return JSON.parse(fakeStorageBackend[key] || null)
33+
}
34+
}
35+
36+
fakeStorage.setItem('session-resume:test-persist', JSON.stringify([['my-first-field', 'test2']]))
37+
restoreResumableFields('test-persist', {storage: fakeStorage})
38+
39+
assert.equal(document.querySelector('#my-first-field').value, 'test2')
40+
assert.equal(document.querySelector('#my-second-field').value, 'second-field-value')
41+
})
42+
2543
it('leaves unrestored values in session storage', function () {
2644
sessionStorage.setItem(
2745
'session-resume:test-persist',
@@ -79,7 +97,7 @@ describe('session-resume', function () {
7997
})
8098

8199
describe('persistResumableFields', function () {
82-
it('persist fields values to session storage', function () {
100+
it('persist fields values to session storage by default', function () {
83101
document.querySelector('#my-first-field').value = 'test1'
84102
document.querySelector('#my-second-field').value = 'test2'
85103
persistResumableFields('test-persist')
@@ -90,6 +108,28 @@ describe('session-resume', function () {
90108
])
91109
})
92110

111+
it('uses a Storage object when provided as an option', function () {
112+
document.querySelector('#my-first-field').value = 'test1'
113+
document.querySelector('#my-second-field').value = 'test2'
114+
115+
const fakeStorageBackend = {}
116+
const fakeStorage = {
117+
setItem(key, value) {
118+
fakeStorageBackend[key] = JSON.stringify(value)
119+
},
120+
getItem(key) {
121+
return JSON.parse(fakeStorageBackend[key] || null)
122+
}
123+
}
124+
125+
persistResumableFields('test-persist', {storage: fakeStorage})
126+
127+
assert.deepEqual(JSON.parse(fakeStorage.getItem('session-resume:test-persist')), [
128+
['my-first-field', 'test1'],
129+
['my-second-field', 'test2']
130+
])
131+
})
132+
93133
it('holds onto existing values in the store', function () {
94134
sessionStorage.setItem('session-resume:test-persist', JSON.stringify([['non-existant-field', 'test3']]))
95135
document.querySelector('#my-first-field').value = 'test1'

0 commit comments

Comments
 (0)