Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove session storage checks from accordion JavaScript #5044

Merged
merged 2 commits into from
Jun 11, 2024

Conversation

36degrees
Copy link
Contributor

@36degrees 36degrees commented Jun 4, 2024

We don’t do anything different if we detect the browser doesn’t support session storage, so we don’t really need to care whether it works or not.

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

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

Copy link

github-actions bot commented Jun 4, 2024

📋 Stats

File sizes

File Size
dist/govuk-frontend-development.min.css 113.37 KiB
dist/govuk-frontend-development.min.js 41.88 KiB
packages/govuk-frontend/dist/govuk/all.bundle.js 87.42 KiB
packages/govuk-frontend/dist/govuk/all.bundle.mjs 82.11 KiB
packages/govuk-frontend/dist/govuk/all.mjs 981 B
packages/govuk-frontend/dist/govuk/govuk-frontend-component.mjs 359 B
packages/govuk-frontend/dist/govuk/govuk-frontend.min.css 113.36 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend.min.js 41.87 KiB
packages/govuk-frontend/dist/govuk/i18n.mjs 5.55 KiB
packages/govuk-frontend/dist/govuk/init.mjs 4.86 KiB

Modules

File Size (bundled) Size (minified)
all.mjs 79.24 KiB 39.84 KiB
accordion.mjs 23.5 KiB 12.39 KiB
button.mjs 5.98 KiB 2.69 KiB
character-count.mjs 22.4 KiB 9.92 KiB
checkboxes.mjs 5.83 KiB 2.83 KiB
error-summary.mjs 7.89 KiB 3.46 KiB
exit-this-page.mjs 17.1 KiB 9.26 KiB
header.mjs 4.46 KiB 2.6 KiB
notification-banner.mjs 6.26 KiB 2.62 KiB
password-input.mjs 15.15 KiB 7.25 KiB
radios.mjs 4.83 KiB 2.38 KiB
skip-link.mjs 4.39 KiB 2.18 KiB
tabs.mjs 10.13 KiB 6.11 KiB

View stats and visualisations on the review app


Action run for df11d0b

Copy link

github-actions bot commented Jun 4, 2024

JavaScript changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
index 83477260f..754775151 100644
--- a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
+++ b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
@@ -1,44 +1,44 @@
 const version = "development";
 
 function normaliseString(e, t) {
-    const s = e ? e.trim() : "";
-    let n, i = null == t ? void 0 : t.type;
-    switch (i || (["true", "false"].includes(s) && (i = "boolean"), s.length > 0 && isFinite(Number(s)) && (i = "number")), i) {
+    const n = e ? e.trim() : "";
+    let i, s = null == t ? void 0 : t.type;
+    switch (s || (["true", "false"].includes(n) && (s = "boolean"), n.length > 0 && isFinite(Number(n)) && (s = "number")), s) {
         case "boolean":
-            n = "true" === s;
+            i = "true" === n;
             break;
         case "number":
-            n = Number(s);
+            i = Number(n);
             break;
         default:
-            n = e
+            i = e
     }
-    return n
+    return i
 }
 
 function mergeConfigs(...e) {
     const t = {};
-    for (const s of e)
-        for (const e of Object.keys(s)) {
-            const n = t[e],
-                i = s[e];
-            isObject(n) && isObject(i) ? t[e] = mergeConfigs(n, i) : t[e] = i
+    for (const n of e)
+        for (const e of Object.keys(n)) {
+            const i = t[e],
+                s = n[e];
+            isObject(i) && isObject(s) ? t[e] = mergeConfigs(i, s) : t[e] = s
         }
     return t
 }
 
-function extractConfigByNamespace(e, t, s) {
-    const n = e.schema.properties[s];
-    if ("object" !== (null == n ? void 0 : n.type)) return;
-    const i = {
-        [s]: {}
+function extractConfigByNamespace(e, t, n) {
+    const i = e.schema.properties[n];
+    if ("object" !== (null == i ? void 0 : i.type)) return;
+    const s = {
+        [n]: {}
     };
     for (const [o, r] of Object.entries(t)) {
-        let e = i;
+        let e = s;
         const t = o.split(".");
-        for (const [n, i] of t.entries()) "object" == typeof e && (n < t.length - 1 ? (isObject(e[i]) || (e[i] = {}), e = e[i]) : o !== s && (e[i] = normaliseString(r)))
+        for (const [i, s] of t.entries()) "object" == typeof e && (i < t.length - 1 ? (isObject(e[s]) || (e[s] = {}), e = e[s]) : o !== n && (e[s] = normaliseString(r)))
     }
-    return i[s]
+    return s[n]
 }
 
 function getFragmentFromUrl(e) {
@@ -54,20 +54,20 @@ function getBreakpoint(e) {
 }
 
 function setFocus(e, t = {}) {
-    var s;
-    const n = e.getAttribute("tabindex");
+    var n;
+    const i = e.getAttribute("tabindex");
 
     function onBlur() {
-        var s;
-        null == (s = t.onBlur) || s.call(e), n || e.removeAttribute("tabindex")
+        var n;
+        null == (n = t.onBlur) || n.call(e), i || e.removeAttribute("tabindex")
     }
-    n || e.setAttribute("tabindex", "-1"), e.addEventListener("focus", (function() {
+    i || e.setAttribute("tabindex", "-1"), e.addEventListener("focus", (function() {
         e.addEventListener("blur", onBlur, {
             once: !0
         })
     }), {
         once: !0
-    }), null == (s = t.onBeforeFocus) || s.call(e), e.focus()
+    }), null == (n = t.onBeforeFocus) || n.call(e), e.focus()
 }
 
 function isSupported(e = document.body) {
@@ -81,9 +81,9 @@ function isObject(e) {
 }
 
 function normaliseDataset(e, t) {
-    const s = {};
-    for (const [n, i] of Object.entries(e.schema.properties)) n in t && (s[n] = normaliseString(t[n], i)), "object" === (null == i ? void 0 : i.type) && (s[n] = extractConfigByNamespace(e, t, n));
-    return s
+    const n = {};
+    for (const [i, s] of Object.entries(e.schema.properties)) i in t && (n[i] = normaliseString(t[i], s)), "object" === (null == s ? void 0 : s.type) && (n[i] = extractConfigByNamespace(e, t, i));
+    return n
 }
 class GOVUKFrontendError extends Error {
     constructor(...e) {
@@ -106,12 +106,12 @@ class ElementError extends GOVUKFrontendError {
         let t = "string" == typeof e ? e : "";
         if ("object" == typeof e) {
             const {
-                componentName: s,
-                identifier: n,
-                element: i,
+                componentName: n,
+                identifier: i,
+                element: s,
                 expectedType: o
             } = e;
-            t = `${s}: ${n}`, t += i ? ` is not of type ${null!=o?o:"HTMLElement"}` : " not found"
+            t = `${n}: ${i}`, t += s ? ` is not of type ${null!=o?o:"HTMLElement"}` : " not found"
         }
         super(t), this.name = "ElementError"
     }
@@ -126,31 +126,31 @@ class GOVUKFrontendComponent {
 }
 class I18n {
     constructor(e = {}, t = {}) {
-        var s;
-        this.translations = void 0, this.locale = void 0, this.translations = e, this.locale = null != (s = t.locale) ? s : document.documentElement.lang || "en"
+        var n;
+        this.translations = void 0, this.locale = void 0, this.translations = e, this.locale = null != (n = t.locale) ? n : document.documentElement.lang || "en"
     }
     t(e, t) {
         if (!e) throw new Error("i18n: lookup key missing");
-        let s = this.translations[e];
-        if ("number" == typeof(null == t ? void 0 : t.count) && "object" == typeof s) {
-            const n = s[this.getPluralSuffix(e, t.count)];
-            n && (s = n)
+        let n = this.translations[e];
+        if ("number" == typeof(null == t ? void 0 : t.count) && "object" == typeof n) {
+            const i = n[this.getPluralSuffix(e, t.count)];
+            i && (n = i)
         }
-        if ("string" == typeof s) {
-            if (s.match(/%{(.\S+)}/)) {
+        if ("string" == typeof n) {
+            if (n.match(/%{(.\S+)}/)) {
                 if (!t) throw new Error("i18n: cannot replace placeholders in string if no option data provided");
-                return this.replacePlaceholders(s, t)
+                return this.replacePlaceholders(n, t)
             }
-            return s
+            return n
         }
         return e
     }
     replacePlaceholders(e, t) {
-        const s = Intl.NumberFormat.supportedLocalesOf(this.locale).length ? new Intl.NumberFormat(this.locale) : void 0;
-        return e.replace(/%{(.\S+)}/g, (function(e, n) {
-            if (Object.prototype.hasOwnProperty.call(t, n)) {
-                const e = t[n];
-                return !1 === e || "number" != typeof e && "string" != typeof e ? "" : "number" == typeof e ? s ? s.format(e) : `${e}` : e
+        const n = Intl.NumberFormat.supportedLocalesOf(this.locale).length ? new Intl.NumberFormat(this.locale) : void 0;
+        return e.replace(/%{(.\S+)}/g, (function(e, i) {
+            if (Object.prototype.hasOwnProperty.call(t, i)) {
+                const e = t[i];
+                return !1 === e || "number" != typeof e && "string" != typeof e ? "" : "number" == typeof e ? n ? n.format(e) : `${e}` : e
             }
             throw new Error(`i18n: no data found to replace ${e} placeholder in string`)
         }))
@@ -160,11 +160,11 @@ class I18n {
     }
     getPluralSuffix(e, t) {
         if (t = Number(t), !isFinite(t)) return "other";
-        const s = this.translations[e],
-            n = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(t) : this.selectPluralFormUsingFallbackRules(t);
-        if ("object" == typeof s) {
-            if (n in s) return n;
-            if ("other" in s) return console.warn(`i18n: Missing plural form ".${n}" for "${this.locale}" locale. Falling back to ".other".`), "other"
+        const n = this.translations[e],
+            i = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(t) : this.selectPluralFormUsingFallbackRules(t);
+        if ("object" == typeof n) {
+            if (i in n) return i;
+            if ("other" in n) return console.warn(`i18n: Missing plural form ".${i}" for "${this.locale}" locale. Falling back to ".other".`), "other"
         }
         throw new Error(`i18n: Plural form ".other" is required for "${this.locale}" locale`)
     }
@@ -176,8 +176,8 @@ class I18n {
     getPluralRulesForLocale() {
         const e = this.locale.split("-")[0];
         for (const t in I18n.pluralRulesMap) {
-            const s = I18n.pluralRulesMap[t];
-            if (s.includes(this.locale) || s.includes(e)) return t
+            const n = I18n.pluralRulesMap[t];
+            if (n.includes(this.locale) || n.includes(e)) return t
         }
     }
 }
@@ -199,27 +199,27 @@ I18n.pluralRulesMap = {
     irish: e => 1 === e ? "one" : 2 === e ? "two" : e >= 3 && e <= 6 ? "few" : e >= 7 && e <= 10 ? "many" : "other",
     russian(e) {
         const t = e % 100,
-            s = t % 10;
-        return 1 === s && 11 !== t ? "one" : s >= 2 && s <= 4 && !(t >= 12 && t <= 14) ? "few" : 0 === s || s >= 5 && s <= 9 || t >= 11 && t <= 14 ? "many" : "other"
+            n = t % 10;
+        return 1 === n && 11 !== t ? "one" : n >= 2 && n <= 4 && !(t >= 12 && t <= 14) ? "few" : 0 === n || n >= 5 && n <= 9 || t >= 11 && t <= 14 ? "many" : "other"
     },
     scottish: e => 1 === e || 11 === e ? "one" : 2 === e || 12 === e ? "two" : e >= 3 && e <= 10 || e >= 13 && e <= 19 ? "few" : "other",
     spanish: e => 1 === e ? "one" : e % 1e6 == 0 && 0 !== e ? "many" : "other",
     welsh: e => 0 === e ? "zero" : 1 === e ? "one" : 2 === e ? "two" : 3 === e ? "few" : 6 === e ? "many" : "other"
 };
 class Accordion extends GOVUKFrontendComponent {
-    constructor(t, s = {}) {
-        if (super(), this.$module = void 0, this.config = void 0, this.i18n = void 0, this.controlsClass = "govuk-accordion__controls", this.showAllClass = "govuk-accordion__show-all", this.showAllTextClass = "govuk-accordion__show-all-text", this.sectionClass = "govuk-accordion__section", this.sectionExpandedClass = "govuk-accordion__section--expanded", this.sectionButtonClass = "govuk-accordion__section-button", this.sectionHeaderClass = "govuk-accordion__section-header", this.sectionHeadingClass = "govuk-accordion__section-heading", this.sectionHeadingDividerClass = "govuk-accordion__section-heading-divider", this.sectionHeadingTextClass = "govuk-accordion__section-heading-text", this.sectionHeadingTextFocusClass = "govuk-accordion__section-heading-text-focus", this.sectionShowHideToggleClass = "govuk-accordion__section-toggle", this.sectionShowHideToggleFocusClass = "govuk-accordion__section-toggle-focus", this.sectionShowHideTextClass = "govuk-accordion__section-toggle-text", this.upChevronIconClass = "govuk-accordion-nav__chevron", this.downChevronIconClass = "govuk-accordion-nav__chevron--down", this.sectionSummaryClass = "govuk-accordion__section-summary", this.sectionSummaryFocusClass = "govuk-accordion__section-summary-focus", this.sectionContentClass = "govuk-accordion__section-content", this.$sections = void 0, this.browserSupportsSessionStorage = !1, this.$showAllButton = null, this.$showAllIcon = null, this.$showAllText = null, !(t instanceof HTMLElement)) throw new ElementError({
+    constructor(e, t = {}) {
+        if (super(), this.$module = void 0, this.config = void 0, this.i18n = void 0, this.controlsClass = "govuk-accordion__controls", this.showAllClass = "govuk-accordion__show-all", this.showAllTextClass = "govuk-accordion__show-all-text", this.sectionClass = "govuk-accordion__section", this.sectionExpandedClass = "govuk-accordion__section--expanded", this.sectionButtonClass = "govuk-accordion__section-button", this.sectionHeaderClass = "govuk-accordion__section-header", this.sectionHeadingClass = "govuk-accordion__section-heading", this.sectionHeadingDividerClass = "govuk-accordion__section-heading-divider", this.sectionHeadingTextClass = "govuk-accordion__section-heading-text", this.sectionHeadingTextFocusClass = "govuk-accordion__section-heading-text-focus", this.sectionShowHideToggleClass = "govuk-accordion__section-toggle", this.sectionShowHideToggleFocusClass = "govuk-accordion__section-toggle-focus", this.sectionShowHideTextClass = "govuk-accordion__section-toggle-text", this.upChevronIconClass = "govuk-accordion-nav__chevron", this.downChevronIconClass = "govuk-accordion-nav__chevron--down", this.sectionSummaryClass = "govuk-accordion__section-summary", this.sectionSummaryFocusClass = "govuk-accordion__section-summary-focus", this.sectionContentClass = "govuk-accordion__section-content", this.$sections = void 0, this.$showAllButton = null, this.$showAllIcon = null, this.$showAllText = null, !(e instanceof HTMLElement)) throw new ElementError({
             componentName: "Accordion",
-            element: t,
+            element: e,
             identifier: "Root element (`$module`)"
         });
-        this.$module = t, this.config = mergeConfigs(Accordion.defaults, s, normaliseDataset(Accordion, t.dataset)), this.i18n = new I18n(this.config.i18n);
+        this.$module = e, this.config = mergeConfigs(Accordion.defaults, t, normaliseDataset(Accordion, e.dataset)), this.i18n = new I18n(this.config.i18n);
         const n = this.$module.querySelectorAll(`.${this.sectionClass}`);
         if (!n.length) throw new ElementError({
             componentName: "Accordion",
             identifier: `Sections (\`<div class="${this.sectionClass}">\`)`
         });
-        this.$sections = n, this.browserSupportsSessionStorage = e.checkForSessionStorage(), this.initControls(), this.initSectionHeaders(), this.updateShowAllButton(this.areAllSectionsOpen())
+        this.$sections = n, this.initControls(), this.initSectionHeaders(), this.updateShowAllButton(this.areAllSectionsOpen())
     }
     initControls() {
         this.$showAllButton = document.createElement("button"), this.$showAllButton.setAttribute("type", "button"), this.$showAllButton.setAttribute("class", this.showAllClass), this.$showAllButton.setAttribute("aria-expanded", "false"), this.$showAllIcon = document.createElement("span"), this.$showAllIcon.classList.add(this.upChevronIconClass), this.$showAllButton.appendChild(this.$showAllIcon);
@@ -228,53 +228,53 @@ class Accordion extends GOVUKFrontendComponent {
     }
     initSectionHeaders() {
         this.$sections.forEach(((e, t) => {
-            const s = e.querySelector(`.${this.sectionHeaderClass}`);
-            if (!s) throw new ElementError({
+            const n = e.querySelector(`.${this.sectionHeaderClass}`);
+            if (!n) throw new ElementError({
                 componentName: "Accordion",
                 identifier: `Section headers (\`<div class="${this.sectionHeaderClass}">\`)`
             });
-            this.constructHeaderMarkup(s, t), this.setExpanded(this.isExpanded(e), e), s.addEventListener("click", (() => this.onSectionToggle(e))), this.setInitialState(e)
+            this.constructHeaderMarkup(n, t), this.setExpanded(this.isExpanded(e), e), n.addEventListener("click", (() => this.onSectionToggle(e))), this.setInitialState(e)
         }))
     }
     constructHeaderMarkup(e, t) {
-        const s = e.querySelector(`.${this.sectionButtonClass}`),
-            n = e.querySelector(`.${this.sectionHeadingClass}`),
-            i = e.querySelector(`.${this.sectionSummaryClass}`);
-        if (!n) throw new ElementError({
+        const n = e.querySelector(`.${this.sectionButtonClass}`),
+            i = e.querySelector(`.${this.sectionHeadingClass}`),
+            s = e.querySelector(`.${this.sectionSummaryClass}`);
+        if (!i) throw new ElementError({
             componentName: "Accordion",
             identifier: `Section heading (\`.${this.sectionHeadingClass}\`)`
         });
-        if (!s) throw new ElementError({
+        if (!n) throw new ElementError({
             componentName: "Accordion",
             identifier: `Section button placeholder (\`<span class="${this.sectionButtonClass}">\`)`
         });
         const o = document.createElement("button");
         o.setAttribute("type", "button"), o.setAttribute("aria-controls", `${this.$module.id}-content-${t+1}`);
-        for (const d of Array.from(s.attributes)) "id" !== d.name && o.setAttribute(d.name, d.value);
+        for (const d of Array.from(n.attributes)) "id" !== d.name && o.setAttribute(d.name, d.value);
         const r = document.createElement("span");
-        r.classList.add(this.sectionHeadingTextClass), r.id = s.id;
+        r.classList.add(this.sectionHeadingTextClass), r.id = n.id;
         const a = document.createElement("span");
-        a.classList.add(this.sectionHeadingTextFocusClass), r.appendChild(a), Array.from(s.childNodes).forEach((e => a.appendChild(e)));
+        a.classList.add(this.sectionHeadingTextFocusClass), r.appendChild(a), Array.from(n.childNodes).forEach((e => a.appendChild(e)));
         const l = document.createElement("span");
         l.classList.add(this.sectionShowHideToggleClass), l.setAttribute("data-nosnippet", "");
         const c = document.createElement("span");
         c.classList.add(this.sectionShowHideToggleFocusClass), l.appendChild(c);
         const h = document.createElement("span"),
             u = document.createElement("span");
-        if (u.classList.add(this.upChevronIconClass), c.appendChild(u), h.classList.add(this.sectionShowHideTextClass), c.appendChild(h), o.appendChild(r), o.appendChild(this.getButtonPunctuationEl()), i) {
+        if (u.classList.add(this.upChevronIconClass), c.appendChild(u), h.classList.add(this.sectionShowHideTextClass), c.appendChild(h), o.appendChild(r), o.appendChild(this.getButtonPunctuationEl()), s) {
             const e = document.createElement("span"),
                 t = document.createElement("span");
             t.classList.add(this.sectionSummaryFocusClass), e.appendChild(t);
-            for (const s of Array.from(i.attributes)) e.setAttribute(s.name, s.value);
-            Array.from(i.childNodes).forEach((e => t.appendChild(e))), i.remove(), o.appendChild(e), o.appendChild(this.getButtonPunctuationEl())
+            for (const n of Array.from(s.attributes)) e.setAttribute(n.name, n.value);
+            Array.from(s.childNodes).forEach((e => t.appendChild(e))), s.remove(), o.appendChild(e), o.appendChild(this.getButtonPunctuationEl())
         }
-        o.appendChild(l), n.removeChild(s), n.appendChild(o)
+        o.appendChild(l), i.removeChild(n), i.appendChild(o)
     }
     onBeforeMatch(e) {
         const t = e.target;
         if (!(t instanceof Element)) return;
-        const s = t.closest(`.${this.sectionClass}`);
-        s && this.setExpanded(!0, s)
+        const n = t.closest(`.${this.sectionClass}`);
+        n && this.setExpanded(!0, n)
     }
     onSectionToggle(e) {
         const t = !this.isExpanded(e);
@@ -287,24 +287,24 @@ class Accordion extends GOVUKFrontendComponent {
         })), this.updateShowAllButton(e)
     }
     setExpanded(e, t) {
-        const s = t.querySelector(`.${this.upChevronIconClass}`),
-            n = t.querySelector(`.${this.sectionShowHideTextClass}`),
-            i = t.querySelector(`.${this.sectionButtonClass}`),
+        const n = t.querySelector(`.${this.upChevronIconClass}`),
+            i = t.querySelector(`.${this.sectionShowHideTextClass}`),
+            s = t.querySelector(`.${this.sectionButtonClass}`),
             o = t.querySelector(`.${this.sectionContentClass}`);
         if (!o) throw new ElementError({
             componentName: "Accordion",
             identifier: `Section content (\`<div class="${this.sectionContentClass}">\`)`
         });
-        if (!s || !n || !i) return;
+        if (!n || !i || !s) return;
         const r = e ? this.i18n.t("hideSection") : this.i18n.t("showSection");
-        n.textContent = r, i.setAttribute("aria-expanded", `${e}`);
+        i.textContent = r, s.setAttribute("aria-expanded", `${e}`);
         const a = [],
             l = t.querySelector(`.${this.sectionHeadingTextClass}`);
         l && a.push(`${l.textContent}`.trim());
         const c = t.querySelector(`.${this.sectionSummaryClass}`);
         c && a.push(`${c.textContent}`.trim());
         const h = e ? this.i18n.t("hideSectionAriaLabel") : this.i18n.t("showSectionAriaLabel");
-        a.push(h), i.setAttribute("aria-label", a.join(" , ")), e ? (o.removeAttribute("hidden"), t.classList.add(this.sectionExpandedClass), s.classList.remove(this.downChevronIconClass)) : (o.setAttribute("hidden", "until-found"), t.classList.remove(this.sectionExpandedClass), s.classList.add(this.downChevronIconClass)), this.updateShowAllButton(this.areAllSectionsOpen())
+        a.push(h), s.setAttribute("aria-label", a.join(" , ")), e ? (o.removeAttribute("hidden"), t.classList.add(this.sectionExpandedClass), n.classList.remove(this.downChevronIconClass)) : (o.setAttribute("hidden", "until-found"), t.classList.remove(this.sectionExpandedClass), n.classList.add(this.downChevronIconClass)), this.updateShowAllButton(this.areAllSectionsOpen())
     }
     isExpanded(e) {
         return e.classList.contains(this.sectionExpandedClass)
@@ -315,24 +315,24 @@ class Accordion extends GOVUKFrontendComponent {
     updateShowAllButton(e) {
         this.$showAllButton && this.$showAllText && this.$showAllIcon && (this.$showAllButton.setAttribute("aria-expanded", e.toString()), this.$showAllText.textContent = e ? this.i18n.t("hideAllSections") : this.i18n.t("showAllSections"), this.$showAllIcon.classList.toggle(this.downChevronIconClass, !e))
     }
+    getIdentifier(e) {
+        const t = e.querySelector(`.${this.sectionButtonClass}`);
+        return null == t ? void 0 : t.getAttribute("aria-controls")
+    }
     storeState(e, t) {
-        if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-            const s = e.querySelector(`.${this.sectionButtonClass}`);
-            if (s) {
-                const e = s.getAttribute("aria-controls");
-                e && window.sessionStorage.setItem(e, t.toString())
-            }
-        }
+        if (!this.config.rememberExpanded) return;
+        const n = this.getIdentifier(e);
+        if (n) try {
+            window.sessionStorage.setItem(n, t.toString())
+        } catch (i) {}
     }
     setInitialState(e) {
-        if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-            const t = e.querySelector(`.${this.sectionButtonClass}`);
-            if (t) {
-                const s = t.getAttribute("aria-controls"),
-                    n = s ? window.sessionStorage.getItem(s) : null;
-                null !== n && this.setExpanded("true" === n, e)
-            }
-        }
+        if (!this.config.rememberExpanded) return;
+        const t = this.getIdentifier(e);
+        if (t) try {
+            const n = window.sessionStorage.getItem(t);
+            null !== n && this.setExpanded("true" === n, e)
+        } catch (n) {}
     }
     getButtonPunctuationEl() {
         const e = document.createElement("span");
@@ -359,17 +359,6 @@ Accordion.moduleName = "govuk-accordion", Accordion.defaults = Object.freeze({
         }
     }
 });
-const e = {
-    checkForSessionStorage: function() {
-        const e = "this is the test string";
-        let t;
-        try {
-            return window.sessionStorage.setItem(e, e), t = window.sessionStorage.getItem(e) === e.toString(), window.sessionStorage.removeItem(e), t
-        } catch (s) {
-            return !1
-        }
-    }
-};
 class Button extends GOVUKFrontendComponent {
     constructor(e, t = {}) {
         if (super(), this.$module = void 0, this.config = void 0, this.debounceFormSubmitTimer = null, !(e instanceof HTMLElement)) throw new ElementError({
@@ -391,8 +380,8 @@ class Button extends GOVUKFrontendComponent {
 }
 
 function closestAttributeValue(e, t) {
-    const s = e.closest(`[${t}]`);
-    return s ? s.getAttribute(t) : null
+    const n = e.closest(`[${t}]`);
+    return n ? n.getAttribute(t) : null
 }
 Button.moduleName = "govuk-button", Button.defaults = Object.freeze({
     preventDoubleClick: !1
@@ -405,16 +394,16 @@ Button.moduleName = "govuk-button", Button.defaults = Object.freeze({
 });
 class CharacterCount extends GOVUKFrontendComponent {
     constructor(e, t = {}) {
-        var s, n;
+        var n, i;
         if (super(), this.$module = void 0, this.$textarea = void 0, this.$visibleCountMessage = void 0, this.$screenReaderCountMessage = void 0, this.lastInputTimestamp = null, this.lastInputValue = "", this.valueChecker = null, this.config = void 0, this.i18n = void 0, this.maxLength = void 0, !(e instanceof HTMLElement)) throw new ElementError({
             componentName: "Character count",
             element: e,
             identifier: "Root element (`$module`)"
         });
-        const i = e.querySelector(".govuk-js-character-count");
-        if (!(i instanceof HTMLTextAreaElement || i instanceof HTMLInputElement)) throw new ElementError({
+        const s = e.querySelector(".govuk-js-character-count");
+        if (!(s instanceof HTMLTextAreaElement || s instanceof HTMLInputElement)) throw new ElementError({
             componentName: "Character count",
-            element: i,
+            element: s,
             expectedType: "HTMLTextareaElement or HTMLInputElement",
             identifier: "Form field (`.govuk-js-character-count`)"
         });
@@ -425,24 +414,24 @@ class CharacterCount extends GOVUKFrontendComponent {
             maxwords: void 0
         }), this.config = mergeConfigs(CharacterCount.defaults, t, r, o);
         const a = function(e, t) {
-            const s = [];
-            for (const [n, i] of Object.entries(e)) {
+            const n = [];
+            for (const [i, s] of Object.entries(e)) {
                 const e = [];
-                if (Array.isArray(i)) {
+                if (Array.isArray(s)) {
                     for (const {
-                            required: s,
-                            errorMessage: n
+                            required: n,
+                            errorMessage: i
                         }
-                        of i) s.every((e => !!t[e])) || e.push(n);
-                    "anyOf" !== n || i.length - e.length >= 1 || s.push(...e)
+                        of s) n.every((e => !!t[e])) || e.push(i);
+                    "anyOf" !== i || s.length - e.length >= 1 || n.push(...e)
                 }
             }
-            return s
+            return n
         }(CharacterCount.schema, this.config);
         if (a[0]) throw new ConfigError(`Character count: ${a[0]}`);
         this.i18n = new I18n(this.config.i18n, {
             locale: closestAttributeValue(e, "lang")
-        }), this.maxLength = null != (s = null != (n = this.config.maxwords) ? n : this.config.maxlength) ? s : 1 / 0, this.$module = e, this.$textarea = i;
+        }), this.maxLength = null != (n = null != (i = this.config.maxwords) ? i : this.config.maxlength) ? n : 1 / 0, this.$module = e, this.$textarea = s;
         const l = `${this.$textarea.id}-info`,
             c = document.getElementById(l);
         if (!c) throw new ElementError({
@@ -499,8 +488,8 @@ class CharacterCount extends GOVUKFrontendComponent {
     }
     formatCountMessage(e, t) {
         if (0 === e) return this.i18n.t(`${t}AtLimit`);
-        const s = e < 0 ? "OverLimit" : "UnderLimit";
-        return this.i18n.t(`${t}${s}`, {
+        const n = e < 0 ? "OverLimit" : "UnderLimit";
+        return this.i18n.t(`${t}${n}`, {
             count: Math.abs(e)
         })
     }
@@ -587,10 +576,10 @@ class Checkboxes extends GOVUKFrontendComponent {
     syncConditionalRevealWithInputState(e) {
         const t = e.getAttribute("aria-controls");
         if (!t) return;
-        const s = document.getElementById(t);
-        if (null != s && s.classList.contains("govuk-checkboxes__conditional")) {
+        const n = document.getElementById(t);
+        if (null != n && n.classList.contains("govuk-checkboxes__conditional")) {
             const t = e.checked;
-            e.setAttribute("aria-expanded", t.toString()), s.classList.toggle("govuk-checkboxes__conditional--hidden", !t)
+            e.setAttribute("aria-expanded", t.toString()), n.classList.toggle("govuk-checkboxes__conditional--hidden", !t)
         }
     }
     unCheckAllInputsExcept(e) {
@@ -628,25 +617,25 @@ class ErrorSummary extends GOVUKFrontendComponent {
         if (!(e instanceof HTMLAnchorElement)) return !1;
         const t = getFragmentFromUrl(e.href);
         if (!t) return !1;
-        const s = document.getElementById(t);
-        if (!s) return !1;
-        const n = this.getAssociatedLegendOrLabel(s);
-        return !!n && (n.scrollIntoView(), s.focus({
+        const n = document.getElementById(t);
+        if (!n) return !1;
+        const i = this.getAssociatedLegendOrLabel(n);
+        return !!i && (i.scrollIntoView(), n.focus({
             preventScroll: !0
         }), !0)
     }
     getAssociatedLegendOrLabel(e) {
         var t;
-        const s = e.closest("fieldset");
-        if (s) {
-            const t = s.getElementsByTagName("legend");
+        const n = e.closest("fieldset");
+        if (n) {
+            const t = n.getElementsByTagName("legend");
             if (t.length) {
-                const s = t[0];
-                if (e instanceof HTMLInputElement && ("checkbox" === e.type || "radio" === e.type)) return s;
-                const n = s.getBoundingClientRect().top,
-                    i = e.getBoundingClientRect();
-                if (i.height && window.innerHeight) {
-                    if (i.top + i.height - n < window.innerHeight / 2) return s
+                const n = t[0];
+                if (e instanceof HTMLInputElement && ("checkbox" === e.type || "radio" === e.type)) return n;
+                const i = n.getBoundingClientRect().top,
+                    s = e.getBoundingClientRect();
+                if (s.height && window.innerHeight) {
+                    if (s.top + s.height - i < window.innerHeight / 2) return n
                 }
             }
         }
@@ -669,16 +658,16 @@ class ExitThisPage extends GOVUKFrontendComponent {
             element: e,
             identifier: "Root element (`$module`)"
         });
-        const s = e.querySelector(".govuk-exit-this-page__button");
-        if (!(s instanceof HTMLAnchorElement)) throw new ElementError({
+        const n = e.querySelector(".govuk-exit-this-page__button");
+        if (!(n instanceof HTMLAnchorElement)) throw new ElementError({
             componentName: "Exit this page",
-            element: s,
+            element: n,
             expectedType: "HTMLAnchorElement",
             identifier: "Button (`.govuk-exit-this-page__button`)"
         });
-        this.config = mergeConfigs(ExitThisPage.defaults, t, normaliseDataset(ExitThisPage, e.dataset)), this.i18n = new I18n(this.config.i18n), this.$module = e, this.$button = s;
-        const n = document.querySelector(".govuk-js-exit-this-page-skiplink");
-        n instanceof HTMLAnchorElement && (this.$skiplinkButton = n), this.buildIndicator(), this.initUpdateSpan(), this.initButtonClickHandler(), "govukFrontendExitThisPageKeypress" in document.body.dataset || (document.addEventListener("keyup", this.handleKeypress.bind(this), !0), document.body.dataset.govukFrontendExitThisPageKeypress = "true"), window.addEventListener("pageshow", this.resetPage.bind(this))
+        this.config = mergeConfigs(ExitThisPage.defaults, t, normaliseDataset(ExitThisPage, e.dataset)), this.i18n = new I18n(this.config.i18n), this.$module = e, this.$button = n;
+        const i = document.querySelector(".govuk-js-exit-this-page-skiplink");
+        i instanceof HTMLAnchorElement && (this.$skiplinkButton = i), this.buildIndicator(), this.initUpdateSpan(), this.initButtonClickHandler(), "govukFrontendExitThisPageKeypress" in document.body.dataset || (document.addEventListener("keyup", this.handleKeypress.bind(this), !0), document.body.dataset.govukFrontendExitThisPageKeypress = "true"), window.addEventListener("pageshow", this.resetPage.bind(this))
     }
     initUpdateSpan() {
         this.$updateSpan = document.createElement("span"), this.$updateSpan.setAttribute("role", "status"), this.$updateSpan.className = "govuk-visually-hidden", this.$module.appendChild(this.$updateSpan)
@@ -749,18 +738,18 @@ class Header extends GOVUKFrontendComponent {
         this.$module = e;
         const t = e.querySelector(".govuk-js-header-toggle");
         if (!t) return this;
-        const s = t.getAttribute("aria-controls");
-        if (!s) throw new ElementError({
+        const n = t.getAttribute("aria-controls");
+        if (!n) throw new ElementError({
             componentName: "Header",
             identifier: 'Navigation button (`<button class="govuk-js-header-toggle">`) attribute (`aria-controls`)'
         });
-        const n = document.getElementById(s);
-        if (!n) throw new ElementError({
+        const i = document.getElementById(n);
+        if (!i) throw new ElementError({
             componentName: "Header",
-            element: n,
-            identifier: `Navigation (\`<ul id="${s}">\`)`
+            element: i,
+            identifier: `Navigation (\`<ul id="${n}">\`)`
         });
-        this.$menu = n, this.$menuButton = t, this.setupResponsiveChecks(), this.$menuButton.addEventListener("click", (() => this.handleMenuButtonClick()))
+        this.$menu = i, this.$menuButton = t, this.setupResponsiveChecks(), this.$menuButton.addEventListener("click", (() => this.handleMenuButtonClick()))
     }
     setupResponsiveChecks() {
         const e = getBreakpoint("desktop");
@@ -804,27 +793,27 @@ class PasswordInput extends GOVUKFrontendComponent {
             element: e,
             identifier: "Root element (`$module`)"
         });
-        const s = e.querySelector(".govuk-js-password-input-input");
-        if (!(s instanceof HTMLInputElement)) throw new ElementError({
+        const n = e.querySelector(".govuk-js-password-input-input");
+        if (!(n instanceof HTMLInputElement)) throw new ElementError({
             componentName: "Password input",
-            element: s,
+            element: n,
             expectedType: "HTMLInputElement",
             identifier: "Form field (`.govuk-js-password-input-input`)"
         });
-        if ("password" !== s.type) throw new ElementError("Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.");
-        const n = e.querySelector(".govuk-js-password-input-toggle");
-        if (!(n instanceof HTMLButtonElement)) throw new ElementError({
+        if ("password" !== n.type) throw new ElementError("Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.");
+        const i = e.querySelector(".govuk-js-password-input-toggle");
+        if (!(i instanceof HTMLButtonElement)) throw new ElementError({
             componentName: "Password input",
-            element: n,
+            element: i,
             expectedType: "HTMLButtonElement",
             identifier: "Button (`.govuk-js-password-input-toggle`)"
         });
-        if ("button" !== n.type) throw new ElementError("Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.");
-        this.$module = e, this.$input = s, this.$showHideButton = n, this.config = mergeConfigs(PasswordInput.defaults, t, normaliseDataset(PasswordInput, e.dataset)), this.i18n = new I18n(this.config.i18n, {
+        if ("button" !== i.type) throw new ElementError("Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.");
+        this.$module = e, this.$input = n, this.$showHideButton = i, this.config = mergeConfigs(PasswordInput.defaults, t, normaliseDataset(PasswordInput, e.dataset)), this.i18n = new I18n(this.config.i18n, {
             locale: closestAttributeValue(e, "lang")
         }), this.$showHideButton.removeAttribute("hidden");
-        const i = document.createElement("div");
-        i.className = "govuk-password-input__sr-status govuk-visually-hidden", i.setAttribute("aria-live", "polite"), this.$screenReaderStatusMessage = i, this.$input.insertAdjacentElement("afterend", i), this.$showHideButton.addEventListener("click", this.toggle.bind(this)), this.$input.form && this.$input.form.addEventListener("submit", (() => this.hide())), window.addEventListener("pageshow", (e => {
+        const s = document.createElement("div");
+        s.className = "govuk-password-input__sr-status govuk-visually-hidden", s.setAttribute("aria-live", "polite"), this.$screenReaderStatusMessage = s, this.$input.insertAdjacentElement("afterend", s), this.$showHideButton.addEventListener("click", this.toggle.bind(this)), this.$input.form && this.$input.form.addEventListener("submit", (() => this.hide())), window.addEventListener("pageshow", (e => {
             e.persisted && "password" !== this.$input.type && this.hide()
         })), this.hide()
     }
@@ -841,9 +830,9 @@ class PasswordInput extends GOVUKFrontendComponent {
         if (e === this.$input.type) return;
         this.$input.setAttribute("type", e);
         const t = "password" === e,
-            s = t ? "show" : "hide",
-            n = t ? "passwordHidden" : "passwordShown";
-        this.$showHideButton.innerText = this.i18n.t(`${s}Password`), this.$showHideButton.setAttribute("aria-label", this.i18n.t(`${s}PasswordAriaLabel`)), this.$screenReaderStatusMessage.innerText = this.i18n.t(`${n}Announcement`)
+            n = t ? "show" : "hide",
+            i = t ? "passwordHidden" : "passwordShown";
+        this.$showHideButton.innerText = this.i18n.t(`${n}Password`), this.$showHideButton.setAttribute("aria-label", this.i18n.t(`${n}PasswordAriaLabel`)), this.$screenReaderStatusMessage.innerText = this.i18n.t(`${i}Announcement`)
     }
 }
 PasswordInput.moduleName = "govuk-password-input", PasswordInput.defaults = Object.freeze({
@@ -891,21 +880,21 @@ class Radios extends GOVUKFrontendComponent {
     syncConditionalRevealWithInputState(e) {
         const t = e.getAttribute("aria-controls");
         if (!t) return;
-        const s = document.getElementById(t);
-        if (null != s && s.classList.contains("govuk-radios__conditional")) {
+        const n = document.getElementById(t);
+        if (null != n && n.classList.contains("govuk-radios__conditional")) {
             const t = e.checked;
-            e.setAttribute("aria-expanded", t.toString()), s.classList.toggle("govuk-radios__conditional--hidden", !t)
+            e.setAttribute("aria-expanded", t.toString()), n.classList.toggle("govuk-radios__conditional--hidden", !t)
         }
     }
     handleClick(e) {
         const t = e.target;
         if (!(t instanceof HTMLInputElement) || "radio" !== t.type) return;
-        const s = document.querySelectorAll('input[type="radio"][aria-controls]'),
-            n = t.form,
-            i = t.name;
-        s.forEach((e => {
-            const t = e.form === n;
-            e.name === i && t && this.syncConditionalRevealWithInputState(e)
+        const n = document.querySelectorAll('input[type="radio"][aria-controls]'),
+            i = t.form,
+            s = t.name;
+        n.forEach((e => {
+            const t = e.form === i;
+            e.name === s && t && this.syncConditionalRevealWithInputState(e)
         }))
     }
 }
@@ -920,17 +909,17 @@ class SkipLink extends GOVUKFrontendComponent {
             identifier: "Root element (`$module`)"
         });
         this.$module = e;
-        const s = this.$module.hash,
-            n = null != (t = this.$module.getAttribute("href")) ? t : "";
-        let i;
+        const n = this.$module.hash,
+            i = null != (t = this.$module.getAttribute("href")) ? t : "";
+        let s;
         try {
-            i = new window.URL(this.$module.href)
+            s = new window.URL(this.$module.href)
         } catch (a) {
-            throw new ElementError(`Skip link: Target link (\`href="${n}"\`) is invalid`)
+            throw new ElementError(`Skip link: Target link (\`href="${i}"\`) is invalid`)
         }
-        if (i.origin !== window.location.origin || i.pathname !== window.location.pathname) return;
-        const o = getFragmentFromUrl(s);
-        if (!o) throw new ElementError(`Skip link: Target link (\`href="${n}"\`) has no hash fragment`);
+        if (s.origin !== window.location.origin || s.pathname !== window.location.pathname) return;
+        const o = getFragmentFromUrl(n);
+        if (!o) throw new ElementError(`Skip link: Target link (\`href="${i}"\`) has no hash fragment`);
         const r = document.getElementById(o);
         if (!r) throw new ElementError({
             componentName: "Skip link",
@@ -961,17 +950,17 @@ class Tabs extends GOVUKFrontendComponent {
             identifier: 'Links (`<a class="govuk-tabs__tab">`)'
         });
         this.$module = e, this.$tabs = t, this.boundTabClick = this.onTabClick.bind(this), this.boundTabKeydown = this.onTabKeydown.bind(this), this.boundOnHashChange = this.onHashChange.bind(this);
-        const s = this.$module.querySelector(".govuk-tabs__list"),
-            n = this.$module.querySelectorAll("li.govuk-tabs__list-item");
-        if (!s) throw new ElementError({
+        const n = this.$module.querySelector(".govuk-tabs__list"),
+            i = this.$module.querySelectorAll("li.govuk-tabs__list-item");
+        if (!n) throw new ElementError({
             componentName: "Tabs",
             identifier: 'List (`<ul class="govuk-tabs__list">`)'
         });
-        if (!n.length) throw new ElementError({
+        if (!i.length) throw new ElementError({
             componentName: "Tabs",
             identifier: 'List items (`<li class="govuk-tabs__list-item">`)'
         });
-        this.$tabList = s, this.$tabListItems = n, this.setupResponsiveChecks()
+        this.$tabList = n, this.$tabListItems = i, this.setupResponsiveChecks()
     }
     setupResponsiveChecks() {
         const e = getBreakpoint("tablet");
@@ -1007,8 +996,8 @@ class Tabs extends GOVUKFrontendComponent {
             t = this.getTab(e);
         if (!t) return;
         if (this.changingHash) return void(this.changingHash = !1);
-        const s = this.getCurrentTab();
-        s && (this.hideTab(s), this.showTab(t), t.focus())
+        const n = this.getCurrentTab();
+        n && (this.hideTab(n), this.showTab(t), t.focus())
     }
     hideTab(e) {
         this.unhighlightTab(e), this.hidePanel(e)
@@ -1023,8 +1012,8 @@ class Tabs extends GOVUKFrontendComponent {
         const t = getFragmentFromUrl(e.href);
         if (!t) return;
         e.setAttribute("id", `tab_${t}`), e.setAttribute("role", "tab"), e.setAttribute("aria-controls", t), e.setAttribute("aria-selected", "false"), e.setAttribute("tabindex", "-1");
-        const s = this.getPanel(e);
-        s && (s.setAttribute("role", "tabpanel"), s.setAttribute("aria-labelledby", e.id), s.classList.add(this.jsHiddenClass))
+        const n = this.getPanel(e);
+        n && (n.setAttribute("role", "tabpanel"), n.setAttribute("aria-labelledby", e.id), n.classList.add(this.jsHiddenClass))
     }
     unsetAttributes(e) {
         e.removeAttribute("id"), e.removeAttribute("role"), e.removeAttribute("aria-controls"), e.removeAttribute("aria-selected"), e.removeAttribute("tabindex");
@@ -1033,14 +1022,14 @@ class Tabs extends GOVUKFrontendComponent {
     }
     onTabClick(e) {
         const t = this.getCurrentTab(),
-            s = e.currentTarget;
-        t && s instanceof HTMLAnchorElement && (e.preventDefault(), this.hideTab(t), this.showTab(s), this.createHistoryEntry(s))
+            n = e.currentTarget;
+        t && n instanceof HTMLAnchorElement && (e.preventDefault(), this.hideTab(t), this.showTab(n), this.createHistoryEntry(n))
     }
     createHistoryEntry(e) {
         const t = this.getPanel(e);
         if (!t) return;
-        const s = t.id;
-        t.id = "", this.changingHash = !0, window.location.hash = s, t.id = s
+        const n = t.id;
+        t.id = "", this.changingHash = !0, window.location.hash = n, t.id = n
     }
     onTabKeydown(e) {
         switch (e.key) {
@@ -1062,16 +1051,16 @@ class Tabs extends GOVUKFrontendComponent {
         if (null == e || !e.parentElement) return;
         const t = e.parentElement.nextElementSibling;
         if (!t) return;
-        const s = t.querySelector("a.govuk-tabs__tab");
-        s && (this.hideTab(e), this.showTab(s), s.focus(), this.createHistoryEntry(s))
+        const n = t.querySelector("a.govuk-tabs__tab");
+        n && (this.hideTab(e), this.showTab(n), n.focus(), this.createHistoryEntry(n))
     }
     activatePreviousTab() {
         const e = this.getCurrentTab();
         if (null == e || !e.parentElement) return;
         const t = e.parentElement.previousElementSibling;
         if (!t) return;
-        const s = t.querySelector("a.govuk-tabs__tab");
-        s && (this.hideTab(e), this.showTab(s), s.focus(), this.createHistoryEntry(s))
+        const n = t.querySelector("a.govuk-tabs__tab");
+        n && (this.hideTab(e), this.showTab(n), n.focus(), this.createHistoryEntry(n))
     }
     getPanel(e) {
         const t = getFragmentFromUrl(e.href);
@@ -1099,7 +1088,7 @@ class Tabs extends GOVUKFrontendComponent {
 function initAll(e) {
     var t;
     if (e = void 0 !== e ? e : {}, !isSupported()) return void console.log(new SupportError);
-    const s = [
+    const n = [
             [Accordion, e.accordion],
             [Button, e.button],
             [CharacterCount, e.characterCount],
@@ -1113,19 +1102,19 @@ function initAll(e) {
             [SkipLink],
             [Tabs]
         ],
-        n = null != (t = e.scope) ? t : document;
-    s.forEach((([e, t]) => {
-        createAll(e, t, n)
+        i = null != (t = e.scope) ? t : document;
+    n.forEach((([e, t]) => {
+        createAll(e, t, i)
     }))
 }
 
-function createAll(e, t, s = document) {
-    const n = s.querySelectorAll(`[data-module="${e.moduleName}"]`);
-    return Array.from(n).map((s => {
+function createAll(e, t, n = document) {
+    const i = n.querySelectorAll(`[data-module="${e.moduleName}"]`);
+    return Array.from(i).map((n => {
         try {
-            return "defaults" in e && void 0 !== t ? new e(s, t) : new e(s)
-        } catch (n) {
-            return console.log(n), null
+            return "defaults" in e && void 0 !== t ? new e(n, t) : new e(n)
+        } catch (i) {
+            return console.log(i), null
         }
     })).filter(Boolean)
 }

Action run for df11d0b

Copy link

github-actions bot commented Jun 4, 2024

Other changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/all.bundle.js b/packages/govuk-frontend/dist/govuk/all.bundle.js
index 267a57bfc..fbc644fbf 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.js
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.js
@@ -473,7 +473,6 @@
       this.sectionSummaryFocusClass = 'govuk-accordion__section-summary-focus';
       this.sectionContentClass = 'govuk-accordion__section-content';
       this.$sections = void 0;
-      this.browserSupportsSessionStorage = false;
       this.$showAllButton = null;
       this.$showAllIcon = null;
       this.$showAllText = null;
@@ -495,7 +494,6 @@
         });
       }
       this.$sections = $sections;
-      this.browserSupportsSessionStorage = helper.checkForSessionStorage();
       this.initControls();
       this.initSectionHeaders();
       this.updateShowAllButton(this.areAllSectionsOpen());
@@ -674,27 +672,44 @@
       this.$showAllText.textContent = expanded ? this.i18n.t('hideAllSections') : this.i18n.t('showAllSections');
       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 == null ? void 0 : $button.getAttribute('aria-controls');
+    }
     storeState($section, isExpanded) {
-      if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-        const $button = $section.querySelector(`.${this.sectionButtonClass}`);
-        if ($button) {
-          const contentId = $button.getAttribute('aria-controls');
-          if (contentId) {
-            window.sessionStorage.setItem(contentId, isExpanded.toString());
-          }
-        }
+      if (!this.config.rememberExpanded) {
+        return;
+      }
+      const id = this.getIdentifier($section);
+      if (id) {
+        try {
+          window.sessionStorage.setItem(id, isExpanded.toString());
+        } catch (exception) {}
       }
     }
     setInitialState($section) {
-      if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-        const $button = $section.querySelector(`.${this.sectionButtonClass}`);
-        if ($button) {
-          const contentId = $button.getAttribute('aria-controls');
-          const contentState = contentId ? window.sessionStorage.getItem(contentId) : null;
-          if (contentState !== null) {
-            this.setExpanded(contentState === 'true', $section);
+      if (!this.config.rememberExpanded) {
+        return;
+      }
+      const id = this.getIdentifier($section);
+      if (id) {
+        try {
+          const state = window.sessionStorage.getItem(id);
+          if (state !== null) {
+            this.setExpanded(state === 'true', $section);
           }
-        }
+        } catch (exception) {}
       }
     }
     getButtonPunctuationEl() {
@@ -704,47 +719,6 @@
       return $punctuationEl;
     }
   }
-  Accordion.moduleName = 'govuk-accordion';
-  Accordion.defaults = Object.freeze({
-    i18n: {
-      hideAllSections: 'Hide all sections',
-      hideSection: 'Hide',
-      hideSectionAriaLabel: 'Hide this section',
-      showAllSections: 'Show all sections',
-      showSection: 'Show',
-      showSectionAriaLabel: 'Show this section'
-    },
-    rememberExpanded: true
-  });
-  Accordion.schema = Object.freeze({
-    properties: {
-      i18n: {
-        type: 'object'
-      },
-      rememberExpanded: {
-        type: 'boolean'
-      }
-    }
-  });
-  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
@@ -782,6 +756,28 @@
   /**
    * @typedef {import('../../common/index.mjs').Schema} Schema
    */
+  Accordion.moduleName = 'govuk-accordion';
+  Accordion.defaults = Object.freeze({
+    i18n: {
+      hideAllSections: 'Hide all sections',
+      hideSection: 'Hide',
+      hideSectionAriaLabel: 'Hide this section',
+      showAllSections: 'Show all sections',
+      showSection: 'Show',
+      showSectionAriaLabel: 'Show this section'
+    },
+    rememberExpanded: true
+  });
+  Accordion.schema = Object.freeze({
+    properties: {
+      i18n: {
+        type: 'object'
+      },
+      rememberExpanded: {
+        type: 'boolean'
+      }
+    }
+  });
 
   const DEBOUNCE_TIMEOUT_IN_SECONDS = 1;
 
diff --git a/packages/govuk-frontend/dist/govuk/all.bundle.mjs b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
index cbc00c0b8..3d03f5f0f 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.mjs
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
@@ -467,7 +467,6 @@ class Accordion extends GOVUKFrontendComponent {
     this.sectionSummaryFocusClass = 'govuk-accordion__section-summary-focus';
     this.sectionContentClass = 'govuk-accordion__section-content';
     this.$sections = void 0;
-    this.browserSupportsSessionStorage = false;
     this.$showAllButton = null;
     this.$showAllIcon = null;
     this.$showAllText = null;
@@ -489,7 +488,6 @@ class Accordion extends GOVUKFrontendComponent {
       });
     }
     this.$sections = $sections;
-    this.browserSupportsSessionStorage = helper.checkForSessionStorage();
     this.initControls();
     this.initSectionHeaders();
     this.updateShowAllButton(this.areAllSectionsOpen());
@@ -668,27 +666,44 @@ class Accordion extends GOVUKFrontendComponent {
     this.$showAllText.textContent = expanded ? this.i18n.t('hideAllSections') : this.i18n.t('showAllSections');
     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 == null ? void 0 : $button.getAttribute('aria-controls');
+  }
   storeState($section, isExpanded) {
-    if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-      const $button = $section.querySelector(`.${this.sectionButtonClass}`);
-      if ($button) {
-        const contentId = $button.getAttribute('aria-controls');
-        if (contentId) {
-          window.sessionStorage.setItem(contentId, isExpanded.toString());
-        }
-      }
+    if (!this.config.rememberExpanded) {
+      return;
+    }
+    const id = this.getIdentifier($section);
+    if (id) {
+      try {
+        window.sessionStorage.setItem(id, isExpanded.toString());
+      } catch (exception) {}
     }
   }
   setInitialState($section) {
-    if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-      const $button = $section.querySelector(`.${this.sectionButtonClass}`);
-      if ($button) {
-        const contentId = $button.getAttribute('aria-controls');
-        const contentState = contentId ? window.sessionStorage.getItem(contentId) : null;
-        if (contentState !== null) {
-          this.setExpanded(contentState === 'true', $section);
+    if (!this.config.rememberExpanded) {
+      return;
+    }
+    const id = this.getIdentifier($section);
+    if (id) {
+      try {
+        const state = window.sessionStorage.getItem(id);
+        if (state !== null) {
+          this.setExpanded(state === 'true', $section);
         }
-      }
+      } catch (exception) {}
     }
   }
   getButtonPunctuationEl() {
@@ -698,47 +713,6 @@ class Accordion extends GOVUKFrontendComponent {
     return $punctuationEl;
   }
 }
-Accordion.moduleName = 'govuk-accordion';
-Accordion.defaults = Object.freeze({
-  i18n: {
-    hideAllSections: 'Hide all sections',
-    hideSection: 'Hide',
-    hideSectionAriaLabel: 'Hide this section',
-    showAllSections: 'Show all sections',
-    showSection: 'Show',
-    showSectionAriaLabel: 'Show this section'
-  },
-  rememberExpanded: true
-});
-Accordion.schema = Object.freeze({
-  properties: {
-    i18n: {
-      type: 'object'
-    },
-    rememberExpanded: {
-      type: 'boolean'
-    }
-  }
-});
-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
@@ -776,6 +750,28 @@ const helper = {
 /**
  * @typedef {import('../../common/index.mjs').Schema} Schema
  */
+Accordion.moduleName = 'govuk-accordion';
+Accordion.defaults = Object.freeze({
+  i18n: {
+    hideAllSections: 'Hide all sections',
+    hideSection: 'Hide',
+    hideSectionAriaLabel: 'Hide this section',
+    showAllSections: 'Show all sections',
+    showSection: 'Show',
+    showSectionAriaLabel: 'Show this section'
+  },
+  rememberExpanded: true
+});
+Accordion.schema = Object.freeze({
+  properties: {
+    i18n: {
+      type: 'object'
+    },
+    rememberExpanded: {
+      type: 'boolean'
+    }
+  }
+});
 
 const DEBOUNCE_TIMEOUT_IN_SECONDS = 1;
 
diff --git a/packages/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js b/packages/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js
index 3dcdb7217..312229a64 100644
--- a/packages/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js
+++ b/packages/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js
@@ -407,7 +407,6 @@
       this.sectionSummaryFocusClass = 'govuk-accordion__section-summary-focus';
       this.sectionContentClass = 'govuk-accordion__section-content';
       this.$sections = void 0;
-      this.browserSupportsSessionStorage = false;
       this.$showAllButton = null;
       this.$showAllIcon = null;
       this.$showAllText = null;
@@ -429,7 +428,6 @@
         });
       }
       this.$sections = $sections;
-      this.browserSupportsSessionStorage = helper.checkForSessionStorage();
       this.initControls();
       this.initSectionHeaders();
       this.updateShowAllButton(this.areAllSectionsOpen());
@@ -608,27 +606,44 @@
       this.$showAllText.textContent = expanded ? this.i18n.t('hideAllSections') : this.i18n.t('showAllSections');
       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 == null ? void 0 : $button.getAttribute('aria-controls');
+    }
     storeState($section, isExpanded) {
-      if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-        const $button = $section.querySelector(`.${this.sectionButtonClass}`);
-        if ($button) {
-          const contentId = $button.getAttribute('aria-controls');
-          if (contentId) {
-            window.sessionStorage.setItem(contentId, isExpanded.toString());
-          }
-        }
+      if (!this.config.rememberExpanded) {
+        return;
+      }
+      const id = this.getIdentifier($section);
+      if (id) {
+        try {
+          window.sessionStorage.setItem(id, isExpanded.toString());
+        } catch (exception) {}
       }
     }
     setInitialState($section) {
-      if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-        const $button = $section.querySelector(`.${this.sectionButtonClass}`);
-        if ($button) {
-          const contentId = $button.getAttribute('aria-controls');
-          const contentState = contentId ? window.sessionStorage.getItem(contentId) : null;
-          if (contentState !== null) {
-            this.setExpanded(contentState === 'true', $section);
+      if (!this.config.rememberExpanded) {
+        return;
+      }
+      const id = this.getIdentifier($section);
+      if (id) {
+        try {
+          const state = window.sessionStorage.getItem(id);
+          if (state !== null) {
+            this.setExpanded(state === 'true', $section);
           }
-        }
+        } catch (exception) {}
       }
     }
     getButtonPunctuationEl() {
@@ -638,47 +653,6 @@
       return $punctuationEl;
     }
   }
-  Accordion.moduleName = 'govuk-accordion';
-  Accordion.defaults = Object.freeze({
-    i18n: {
-      hideAllSections: 'Hide all sections',
-      hideSection: 'Hide',
-      hideSectionAriaLabel: 'Hide this section',
-      showAllSections: 'Show all sections',
-      showSection: 'Show',
-      showSectionAriaLabel: 'Show this section'
-    },
-    rememberExpanded: true
-  });
-  Accordion.schema = Object.freeze({
-    properties: {
-      i18n: {
-        type: 'object'
-      },
-      rememberExpanded: {
-        type: 'boolean'
-      }
-    }
-  });
-  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
@@ -716,6 +690,28 @@
   /**
    * @typedef {import('../../common/index.mjs').Schema} Schema
    */
+  Accordion.moduleName = 'govuk-accordion';
+  Accordion.defaults = Object.freeze({
+    i18n: {
+      hideAllSections: 'Hide all sections',
+      hideSection: 'Hide',
+      hideSectionAriaLabel: 'Hide this section',
+      showAllSections: 'Show all sections',
+      showSection: 'Show',
+      showSectionAriaLabel: 'Show this section'
+    },
+    rememberExpanded: true
+  });
+  Accordion.schema = Object.freeze({
+    properties: {
+      i18n: {
+        type: 'object'
+      },
+      rememberExpanded: {
+        type: 'boolean'
+      }
+    }
+  });
 
   exports.Accordion = Accordion;
 
diff --git a/packages/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs b/packages/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs
index c78c0e64e..de8349632 100644
--- a/packages/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs
+++ b/packages/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs
@@ -401,7 +401,6 @@ class Accordion extends GOVUKFrontendComponent {
     this.sectionSummaryFocusClass = 'govuk-accordion__section-summary-focus';
     this.sectionContentClass = 'govuk-accordion__section-content';
     this.$sections = void 0;
-    this.browserSupportsSessionStorage = false;
     this.$showAllButton = null;
     this.$showAllIcon = null;
     this.$showAllText = null;
@@ -423,7 +422,6 @@ class Accordion extends GOVUKFrontendComponent {
       });
     }
     this.$sections = $sections;
-    this.browserSupportsSessionStorage = helper.checkForSessionStorage();
     this.initControls();
     this.initSectionHeaders();
     this.updateShowAllButton(this.areAllSectionsOpen());
@@ -602,27 +600,44 @@ class Accordion extends GOVUKFrontendComponent {
     this.$showAllText.textContent = expanded ? this.i18n.t('hideAllSections') : this.i18n.t('showAllSections');
     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 == null ? void 0 : $button.getAttribute('aria-controls');
+  }
   storeState($section, isExpanded) {
-    if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-      const $button = $section.querySelector(`.${this.sectionButtonClass}`);
-      if ($button) {
-        const contentId = $button.getAttribute('aria-controls');
-        if (contentId) {
-          window.sessionStorage.setItem(contentId, isExpanded.toString());
-        }
-      }
+    if (!this.config.rememberExpanded) {
+      return;
+    }
+    const id = this.getIdentifier($section);
+    if (id) {
+      try {
+        window.sessionStorage.setItem(id, isExpanded.toString());
+      } catch (exception) {}
     }
   }
   setInitialState($section) {
-    if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-      const $button = $section.querySelector(`.${this.sectionButtonClass}`);
-      if ($button) {
-        const contentId = $button.getAttribute('aria-controls');
-        const contentState = contentId ? window.sessionStorage.getItem(contentId) : null;
-        if (contentState !== null) {
-          this.setExpanded(contentState === 'true', $section);
+    if (!this.config.rememberExpanded) {
+      return;
+    }
+    const id = this.getIdentifier($section);
+    if (id) {
+      try {
+        const state = window.sessionStorage.getItem(id);
+        if (state !== null) {
+          this.setExpanded(state === 'true', $section);
         }
-      }
+      } catch (exception) {}
     }
   }
   getButtonPunctuationEl() {
@@ -632,47 +647,6 @@ class Accordion extends GOVUKFrontendComponent {
     return $punctuationEl;
   }
 }
-Accordion.moduleName = 'govuk-accordion';
-Accordion.defaults = Object.freeze({
-  i18n: {
-    hideAllSections: 'Hide all sections',
-    hideSection: 'Hide',
-    hideSectionAriaLabel: 'Hide this section',
-    showAllSections: 'Show all sections',
-    showSection: 'Show',
-    showSectionAriaLabel: 'Show this section'
-  },
-  rememberExpanded: true
-});
-Accordion.schema = Object.freeze({
-  properties: {
-    i18n: {
-      type: 'object'
-    },
-    rememberExpanded: {
-      type: 'boolean'
-    }
-  }
-});
-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
@@ -710,6 +684,28 @@ const helper = {
 /**
  * @typedef {import('../../common/index.mjs').Schema} Schema
  */
+Accordion.moduleName = 'govuk-accordion';
+Accordion.defaults = Object.freeze({
+  i18n: {
+    hideAllSections: 'Hide all sections',
+    hideSection: 'Hide',
+    hideSectionAriaLabel: 'Hide this section',
+    showAllSections: 'Show all sections',
+    showSection: 'Show',
+    showSectionAriaLabel: 'Show this section'
+  },
+  rememberExpanded: true
+});
+Accordion.schema = Object.freeze({
+  properties: {
+    i18n: {
+      type: 'object'
+    },
+    rememberExpanded: {
+      type: 'boolean'
+    }
+  }
+});
 
 export { Accordion };
 //# sourceMappingURL=accordion.bundle.mjs.map
diff --git a/packages/govuk-frontend/dist/govuk/components/accordion/accordion.mjs b/packages/govuk-frontend/dist/govuk/components/accordion/accordion.mjs
index 86d7fc295..990abb949 100644
--- a/packages/govuk-frontend/dist/govuk/components/accordion/accordion.mjs
+++ b/packages/govuk-frontend/dist/govuk/components/accordion/accordion.mjs
@@ -48,7 +48,6 @@ class Accordion extends GOVUKFrontendComponent {
     this.sectionSummaryFocusClass = 'govuk-accordion__section-summary-focus';
     this.sectionContentClass = 'govuk-accordion__section-content';
     this.$sections = void 0;
-    this.browserSupportsSessionStorage = false;
     this.$showAllButton = null;
     this.$showAllIcon = null;
     this.$showAllText = null;
@@ -70,7 +69,6 @@ class Accordion extends GOVUKFrontendComponent {
       });
     }
     this.$sections = $sections;
-    this.browserSupportsSessionStorage = helper.checkForSessionStorage();
     this.initControls();
     this.initSectionHeaders();
     this.updateShowAllButton(this.areAllSectionsOpen());
@@ -249,27 +247,44 @@ class Accordion extends GOVUKFrontendComponent {
     this.$showAllText.textContent = expanded ? this.i18n.t('hideAllSections') : this.i18n.t('showAllSections');
     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 == null ? void 0 : $button.getAttribute('aria-controls');
+  }
   storeState($section, isExpanded) {
-    if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-      const $button = $section.querySelector(`.${this.sectionButtonClass}`);
-      if ($button) {
-        const contentId = $button.getAttribute('aria-controls');
-        if (contentId) {
-          window.sessionStorage.setItem(contentId, isExpanded.toString());
-        }
-      }
+    if (!this.config.rememberExpanded) {
+      return;
+    }
+    const id = this.getIdentifier($section);
+    if (id) {
+      try {
+        window.sessionStorage.setItem(id, isExpanded.toString());
+      } catch (exception) {}
     }
   }
   setInitialState($section) {
-    if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-      const $button = $section.querySelector(`.${this.sectionButtonClass}`);
-      if ($button) {
-        const contentId = $button.getAttribute('aria-controls');
-        const contentState = contentId ? window.sessionStorage.getItem(contentId) : null;
-        if (contentState !== null) {
-          this.setExpanded(contentState === 'true', $section);
+    if (!this.config.rememberExpanded) {
+      return;
+    }
+    const id = this.getIdentifier($section);
+    if (id) {
+      try {
+        const state = window.sessionStorage.getItem(id);
+        if (state !== null) {
+          this.setExpanded(state === 'true', $section);
         }
-      }
+      } catch (exception) {}
     }
   }
   getButtonPunctuationEl() {
@@ -279,47 +294,6 @@ class Accordion extends GOVUKFrontendComponent {
     return $punctuationEl;
   }
 }
-Accordion.moduleName = 'govuk-accordion';
-Accordion.defaults = Object.freeze({
-  i18n: {
-    hideAllSections: 'Hide all sections',
-    hideSection: 'Hide',
-    hideSectionAriaLabel: 'Hide this section',
-    showAllSections: 'Show all sections',
-    showSection: 'Show',
-    showSectionAriaLabel: 'Show this section'
-  },
-  rememberExpanded: true
-});
-Accordion.schema = Object.freeze({
-  properties: {
-    i18n: {
-      type: 'object'
-    },
-    rememberExpanded: {
-      type: 'boolean'
-    }
-  }
-});
-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
@@ -357,6 +331,28 @@ const helper = {
 /**
  * @typedef {import('../../common/index.mjs').Schema} Schema
  */
+Accordion.moduleName = 'govuk-accordion';
+Accordion.defaults = Object.freeze({
+  i18n: {
+    hideAllSections: 'Hide all sections',
+    hideSection: 'Hide',
+    hideSectionAriaLabel: 'Hide this section',
+    showAllSections: 'Show all sections',
+    showSection: 'Show',
+    showSectionAriaLabel: 'Show this section'
+  },
+  rememberExpanded: true
+});
+Accordion.schema = Object.freeze({
+  properties: {
+    i18n: {
+      type: 'object'
+    },
+    rememberExpanded: {
+      type: 'boolean'
+    }
+  }
+});
 
 export { Accordion };
 //# sourceMappingURL=accordion.mjs.map

Action run for df11d0b

Copy link
Member

@querkmachine querkmachine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me.

I have a mild recollection, somewhere in the recesses of the mind, that localStorage/sessionStorage can—in some circumstances—appear to be available APIs, but they will refuse to store or retrieve anything if you actually try to use it.

That was probably due to some sort of private browsing mode. I imagine this is why the helper function explicitly tested for this scenario.

However, I'm okay with that being removed in this situation as the fail state would be that the expanded sections don't get remembered, which feels acceptably still-functional.

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
@36degrees 36degrees force-pushed the accordion-remove-session-storage-checks branch from e1e7e26 to a9ffec4 Compare June 11, 2024 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants