Skip to content

Commit

Permalink
Remove check for session storage support
Browse files Browse the repository at this point in the history
We don’t do anything different if we detect the browser doesn’t support session storage, so we don’t really care.

We do need to wrap attempts to set *or get* from sessions storage in try blocks because setItem can throw `QuotaExceededError` exceptions [1] and some older browsers will throw other exceptions if session storage isn’t available (disabled, or using private browsing) [2] [3]

However we don’t need to do anything different if exceptions are thrown – we can safely catch those exceptions and swallow them.

[1]: https://html.spec.whatwg.org/multipage/webstorage.html#dom-storage-setitem
[2]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API#feature-detecting_localstorage
[3]: https://gist.github.com/paulirish/5558557
  • Loading branch information
36degrees committed Jun 4, 2024
1 parent bb3c8bc commit e1e7e26
Showing 1 changed file with 35 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,6 @@ export class Accordion extends GOVUKFrontendComponent {
/** @private */
$sections

/** @private */
browserSupportsSessionStorage = false

/**
* @private
* @type {HTMLButtonElement | null}
Expand Down Expand Up @@ -146,7 +143,6 @@ export class Accordion extends GOVUKFrontendComponent {
}

this.$sections = $sections
this.browserSupportsSessionStorage = helper.checkForSessionStorage()

this.initControls()
this.initSectionHeaders()
Expand Down Expand Up @@ -515,6 +511,22 @@ export class Accordion extends GOVUKFrontendComponent {
this.$showAllIcon.classList.toggle(this.downChevronIconClass, !expanded)
}

/**
* Get the identifier for a section
*
* We need a unique way of identifying each content in the Accordion.
* Since an `#id` should be unique and an `id` is required for `aria-`
* attributes `id` can be safely used.
*
* @param {Element} $section - Section element
* @returns {string | undefined | null} Identifier for section
*/
getIdentifier($section) {
const $button = $section.querySelector(`.${this.sectionButtonClass}`)

return $button?.getAttribute('aria-controls')
}

/**
* Set the state of the accordions in sessionStorage
*
Expand All @@ -523,19 +535,16 @@ export class Accordion extends GOVUKFrontendComponent {
* @param {boolean} isExpanded - Whether the section is expanded
*/
storeState($section, isExpanded) {
if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
// We need a unique way of identifying each content in the Accordion.
// Since an `#id` should be unique and an `id` is required for `aria-`
// attributes `id` can be safely used.
const $button = $section.querySelector(`.${this.sectionButtonClass}`)
if (!this.config.rememberExpanded) {
return
}

if ($button) {
const contentId = $button.getAttribute('aria-controls')
const id = this.getIdentifier($section)

if (contentId) {
window.sessionStorage.setItem(contentId, isExpanded.toString())
}
}
if (id) {
try {
window.sessionStorage.setItem(id, isExpanded.toString())
} catch (exception) {}
}
}

Expand All @@ -546,19 +555,20 @@ export class Accordion extends GOVUKFrontendComponent {
* @param {Element} $section - Section element
*/
setInitialState($section) {
if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
const $button = $section.querySelector(`.${this.sectionButtonClass}`)
if (!this.config.rememberExpanded) {
return
}

if ($button) {
const contentId = $button.getAttribute('aria-controls')
const contentState = contentId
? window.sessionStorage.getItem(contentId)
: null
const id = this.getIdentifier($section)

if (contentState !== null) {
this.setExpanded(contentState === 'true', $section)
if (id) {
try {
const state = window.sessionStorage.getItem(id)

if (state !== null) {
this.setExpanded(state === 'true', $section)
}
}
} catch (exception) {}
}
}

Expand Down Expand Up @@ -621,27 +631,6 @@ export class Accordion extends GOVUKFrontendComponent {
})
}

const helper = {
/**
* Check for `window.sessionStorage`, and that it actually works.
*
* @returns {boolean} True if session storage is available
*/
checkForSessionStorage: function () {
const testString = 'this is the test string'
let result
try {
window.sessionStorage.setItem(testString, testString)
result =
window.sessionStorage.getItem(testString) === testString.toString()
window.sessionStorage.removeItem(testString)
return result
} catch (exception) {
return false
}
}
}

/**
* Accordion config
*
Expand Down

0 comments on commit e1e7e26

Please sign in to comment.