Skip to content

Commit 7e40603

Browse files
authored
Merge pull request #16 from jklina/restore-fields-not-immediately-present-on-dom
Track fields not always available in the DOM
2 parents e2cd2a6 + 0d40211 commit 7e40603

2 files changed

Lines changed: 91 additions & 14 deletions

File tree

src/index.ts

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,20 @@ export function persistResumableFields(id: string, options?: PersistOptions): vo
2020
}
2121
}
2222

23-
const fields = resumables.filter(field => shouldResumeField(field)).map(field => [field.id, field.value])
23+
let fields = resumables.filter(field => shouldResumeField(field)).map(field => [field.id, field.value])
2424

2525
if (fields.length) {
2626
try {
27+
const previouslyStoredFieldsJson = sessionStorage.getItem(key)
28+
29+
if (previouslyStoredFieldsJson !== null) {
30+
const previouslyStoredFields: string[][] = JSON.parse(previouslyStoredFieldsJson)
31+
const fieldsNotReplaced: string[][] = previouslyStoredFields.filter(function (oldField) {
32+
return !fields.some(field => field[0] === oldField[0])
33+
})
34+
fields = fields.concat(fieldsNotReplaced)
35+
}
36+
2737
sessionStorage.setItem(key, JSON.stringify(fields))
2838
} catch {
2939
// Ignore browser private mode error.
@@ -46,13 +56,8 @@ export function restoreResumableFields(id: string, options?: RestoreOptions): vo
4656

4757
if (!fields) return
4858

49-
try {
50-
sessionStorage.removeItem(key)
51-
} catch {
52-
// Ignore browser private mode error.
53-
}
54-
5559
const changedFields: Array<HTMLInputElement | HTMLTextAreaElement> = []
60+
const storedFieldsNotFound: string[][] = []
5661

5762
for (const [fieldId, value] of JSON.parse(fields)) {
5863
const resumeEvent = new CustomEvent('session:resume', {
@@ -63,17 +68,30 @@ export function restoreResumableFields(id: string, options?: RestoreOptions): vo
6368

6469
if (document.dispatchEvent(resumeEvent)) {
6570
const field = document.getElementById(fieldId)
66-
if (
67-
field &&
68-
(field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement) &&
69-
field.value === field.defaultValue
70-
) {
71-
field.value = value
72-
changedFields.push(field)
71+
if (field && (field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement)) {
72+
if (field.value === field.defaultValue) {
73+
field.value = value
74+
changedFields.push(field)
75+
}
76+
} else {
77+
storedFieldsNotFound.push([fieldId, value])
7378
}
7479
}
7580
}
7681

82+
// Some fields we want to restore are not always immediately present in the
83+
// DOM and may be added later. This holds onto the values until
84+
// they're needed.
85+
if (storedFieldsNotFound.length === 0) {
86+
try {
87+
sessionStorage.removeItem(key)
88+
} catch {
89+
// Ignore browser private mode error.
90+
}
91+
} else {
92+
sessionStorage.setItem(key, JSON.stringify(storedFieldsNotFound))
93+
}
94+
7795
setTimeout(function () {
7896
for (const el of changedFields) {
7997
el.dispatchEvent(new CustomEvent('change', {bubbles: true, cancelable: true}))

test/test.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,38 @@ describe('session-resume', function () {
2020
assert.equal(document.querySelector('#my-second-field').value, 'second-field-value')
2121
})
2222

23+
it('leaves unrestored values in session storage', function () {
24+
sessionStorage.setItem(
25+
'session-resume:test-persist',
26+
JSON.stringify([
27+
['my-first-field', 'test2'],
28+
['non-existant-field', 'test3']
29+
])
30+
)
31+
document.querySelector('#my-first-field').value = 'first-field-value'
32+
document.querySelector('#my-second-field').value = 'second-field-value'
33+
34+
restoreResumableFields('test-persist')
35+
36+
assert.equal(document.querySelector('#my-first-field').value, 'test2')
37+
assert.equal(document.querySelector('#my-second-field').value, 'second-field-value')
38+
39+
// Some fields we want to restore are not always present in the DOM
40+
// and may be added later. We hold onto the values until they're needed.
41+
assert.deepEqual(JSON.parse(sessionStorage.getItem('session-resume:test-persist')), [
42+
['non-existant-field', 'test3']
43+
])
44+
})
45+
46+
it('removes the sessionStore key when all the fields were found', function () {
47+
sessionStorage.setItem('session-resume:test-persist', JSON.stringify([['my-first-field', 'test2']]))
48+
restoreResumableFields('test-persist')
49+
50+
// Some fields we want to restore are not always present in the DOM
51+
// and may be added later. We hold onto the values until they're needed.
52+
assert.equal(sessionStorage.getItem('session-resume:test-persist'), null)
53+
})
54+
2355
it('fires off session:resume events for changed fields', function () {
2456
const fieldsRestored = {}
2557
document.addEventListener('session:resume', function (event) {
@@ -55,5 +87,32 @@ describe('session-resume', function () {
5587
['my-second-field', 'test2']
5688
])
5789
})
90+
91+
it('holds onto existing values in the store', function () {
92+
sessionStorage.setItem('session-resume:test-persist', JSON.stringify([['non-existant-field', 'test3']]))
93+
document.querySelector('#my-first-field').value = 'test1'
94+
document.querySelector('#my-second-field').value = 'test2'
95+
96+
persistResumableFields('test-persist')
97+
98+
assert.deepEqual(JSON.parse(sessionStorage.getItem('session-resume:test-persist')), [
99+
['my-first-field', 'test1'],
100+
['my-second-field', 'test2'],
101+
['non-existant-field', 'test3']
102+
])
103+
})
104+
105+
it('replaces old values with the latest field values', function () {
106+
sessionStorage.setItem('session-resume:test-persist', JSON.stringify([['my-first-field', 'old data']]))
107+
document.querySelector('#my-first-field').value = 'test1'
108+
document.querySelector('#my-second-field').value = 'test2'
109+
110+
persistResumableFields('test-persist')
111+
112+
assert.deepEqual(JSON.parse(sessionStorage.getItem('session-resume:test-persist')), [
113+
['my-first-field', 'test1'],
114+
['my-second-field', 'test2']
115+
])
116+
})
58117
})
59118
})

0 commit comments

Comments
 (0)