govuk-frontend
Version:
GOV.UK Frontend contains the code you need to start building a user interface for government platforms and services.
1 lines • 21.7 kB
Source Map (JSON)
{"version":3,"file":"exit-this-page.mjs","sources":["../../../../src/govuk/components/exit-this-page/exit-this-page.mjs"],"sourcesContent":["import { ConfigurableComponent } from '../../common/configuration.mjs'\nimport { ElementError } from '../../errors/index.mjs'\nimport { I18n } from '../../i18n.mjs'\n\n/**\n * Exit this page component\n *\n * @preserve\n * @augments ConfigurableComponent<ExitThisPageConfig>\n */\nexport class ExitThisPage extends ConfigurableComponent {\n /** @private */\n i18n\n\n /** @private */\n $button\n\n /**\n * @private\n * @type {HTMLAnchorElement | null}\n */\n $skiplinkButton = null\n\n /**\n * @private\n * @type {HTMLElement | null}\n */\n $updateSpan = null\n\n /**\n * @private\n * @type {HTMLElement | null}\n */\n $indicatorContainer = null\n\n /**\n * @private\n * @type {HTMLElement | null}\n */\n $overlay = null\n\n /** @private */\n keypressCounter = 0\n\n /** @private */\n lastKeyWasModified = false\n\n /** @private */\n timeoutTime = 5000 // milliseconds\n\n // Store the timeout events so that we can clear them to avoid user keypresses overlapping\n // setTimeout returns an id that we can use to clear it with clearTimeout,\n // hence the 'Id' suffix\n\n /**\n * @private\n * @type {number | null}\n */\n keypressTimeoutId = null\n\n /**\n * @private\n * @type {number | null}\n */\n timeoutMessageId = null\n\n /**\n * @param {Element | null} $root - HTML element that wraps the Exit This Page button\n * @param {ExitThisPageConfig} [config] - Exit This Page config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $button = this.$root.querySelector('.govuk-exit-this-page__button')\n if (!($button instanceof HTMLAnchorElement)) {\n throw new ElementError({\n component: ExitThisPage,\n element: $button,\n expectedType: 'HTMLAnchorElement',\n identifier: 'Button (`.govuk-exit-this-page__button`)'\n })\n }\n\n this.i18n = new I18n(this.config.i18n)\n this.$button = $button\n\n const $skiplinkButton = document.querySelector(\n '.govuk-js-exit-this-page-skiplink'\n )\n if ($skiplinkButton instanceof HTMLAnchorElement) {\n this.$skiplinkButton = $skiplinkButton\n }\n\n this.buildIndicator()\n this.initUpdateSpan()\n this.initButtonClickHandler()\n\n // Check to see if this has already been done by a previous initialisation of ExitThisPage\n if (!('govukFrontendExitThisPageKeypress' in document.body.dataset)) {\n document.addEventListener('keyup', this.handleKeypress.bind(this), true)\n document.body.dataset.govukFrontendExitThisPageKeypress = 'true'\n }\n\n // When the page is restored after navigating 'back' in some browsers the\n // blank overlay remains present, rendering the page unusable. Here, we check\n // to see if it's present on page (re)load, and remove it if so.\n window.addEventListener('pageshow', this.resetPage.bind(this))\n }\n\n /**\n * Create the <span> we use for screen reader announcements.\n *\n * @private\n */\n initUpdateSpan() {\n this.$updateSpan = document.createElement('span')\n this.$updateSpan.setAttribute('role', 'status')\n this.$updateSpan.className = 'govuk-visually-hidden'\n\n this.$root.appendChild(this.$updateSpan)\n }\n\n /**\n * Create button click handlers.\n *\n * @private\n */\n initButtonClickHandler() {\n // Main EtP button\n this.$button.addEventListener('click', this.handleClick.bind(this))\n\n // EtP secondary link\n if (this.$skiplinkButton) {\n this.$skiplinkButton.addEventListener(\n 'click',\n this.handleClick.bind(this)\n )\n }\n }\n\n /**\n * Create the HTML for the 'three lights' indicator on the button.\n *\n * @private\n */\n buildIndicator() {\n // Build container\n // Putting `aria-hidden` on it as it won't contain any readable information\n this.$indicatorContainer = document.createElement('div')\n this.$indicatorContainer.className = 'govuk-exit-this-page__indicator'\n this.$indicatorContainer.setAttribute('aria-hidden', 'true')\n\n // Create three 'lights' and place them within the container\n for (let i = 0; i < 3; i++) {\n const $indicator = document.createElement('div')\n $indicator.className = 'govuk-exit-this-page__indicator-light'\n this.$indicatorContainer.appendChild($indicator)\n }\n\n // Append it all to the module\n this.$button.appendChild(this.$indicatorContainer)\n }\n\n /**\n * Update whether the lights are visible and which ones are lit up depending on\n * the value of `keypressCounter`.\n *\n * @private\n */\n updateIndicator() {\n if (!this.$indicatorContainer) {\n return\n }\n\n // Show or hide the indicator container depending on keypressCounter value\n this.$indicatorContainer.classList.toggle(\n 'govuk-exit-this-page__indicator--visible',\n this.keypressCounter > 0\n )\n\n // Turn on only the indicators we want on\n const $indicators = this.$indicatorContainer.querySelectorAll(\n '.govuk-exit-this-page__indicator-light'\n )\n $indicators.forEach(($indicator, index) => {\n $indicator.classList.toggle(\n 'govuk-exit-this-page__indicator-light--on',\n index < this.keypressCounter\n )\n })\n }\n\n /**\n * Initiates the redirection away from the current page.\n * Includes the loading overlay functionality, which covers the current page with a\n * white overlay so that the contents are not visible during the loading\n * process. This is particularly important on slow network connections.\n *\n * @private\n */\n exitPage() {\n if (!this.$updateSpan) {\n return\n }\n\n this.$updateSpan.textContent = ''\n\n // Blank the page\n // As well as creating an overlay with text, we also set the body to hidden\n // to prevent screen reader and sequential navigation users potentially\n // navigating through the page behind the overlay during loading\n document.body.classList.add('govuk-exit-this-page-hide-content')\n this.$overlay = document.createElement('div')\n this.$overlay.className = 'govuk-exit-this-page-overlay'\n this.$overlay.setAttribute('role', 'alert')\n\n // we do these this way round, thus incurring a second paint, because changing\n // the element text after adding it means that screen readers pick up the\n // announcement more reliably.\n document.body.appendChild(this.$overlay)\n this.$overlay.textContent = this.i18n.t('activated')\n\n window.location.href = this.$button.href\n }\n\n /**\n * Pre-activation logic for when the button is clicked/activated via mouse or\n * pointer.\n *\n * We do this to differentiate it from the keyboard activation event because we\n * need to run `e.preventDefault` as the button or skiplink are both links and we\n * want to apply some additional logic in `exitPage` before navigating.\n *\n * @private\n * @param {MouseEvent} event - mouse click event\n */\n handleClick(event) {\n event.preventDefault()\n this.exitPage()\n }\n\n /**\n * Logic for the 'quick escape' keyboard sequence functionality (pressing the\n * Shift key three times without interruption, within a time limit).\n *\n * @private\n * @param {KeyboardEvent} event - keyup event\n */\n handleKeypress(event) {\n if (!this.$updateSpan) {\n return\n }\n\n // Detect if the 'Shift' key has been pressed. We want to only do things if it\n // was pressed by itself and not in a combination with another key—so we keep\n // track of whether the preceding keyup had shiftKey: true on it, and if it\n // did, we ignore the next Shift keyup event.\n //\n // This works because using Shift as a modifier key (e.g. pressing Shift + A)\n // will fire TWO keyup events, one for A (with e.shiftKey: true) and the other\n // for Shift (with e.shiftKey: false).\n if (event.key === 'Shift' && !this.lastKeyWasModified) {\n this.keypressCounter += 1\n\n // Update the indicator before the below if statement can reset it back to 0\n this.updateIndicator()\n\n // Clear the timeout for the keypress timeout message clearing itself\n if (this.timeoutMessageId) {\n window.clearTimeout(this.timeoutMessageId)\n this.timeoutMessageId = null\n }\n\n if (this.keypressCounter >= 3) {\n this.keypressCounter = 0\n\n if (this.keypressTimeoutId) {\n window.clearTimeout(this.keypressTimeoutId)\n this.keypressTimeoutId = null\n }\n\n this.exitPage()\n } else {\n if (this.keypressCounter === 1) {\n this.$updateSpan.textContent = this.i18n.t('pressTwoMoreTimes')\n } else {\n this.$updateSpan.textContent = this.i18n.t('pressOneMoreTime')\n }\n }\n\n this.setKeypressTimer()\n } else if (this.keypressTimeoutId) {\n // If the user pressed any key other than 'Shift', after having pressed\n // 'Shift' and activating the timer, stop and reset the timer.\n this.resetKeypressTimer()\n }\n\n // Keep track of whether the Shift modifier key was held during this keypress\n this.lastKeyWasModified = event.shiftKey\n }\n\n /**\n * Starts the 'quick escape' keyboard sequence timer.\n *\n * This can be invoked several times. We want this to be possible so that the\n * timer is restarted each time the shortcut key is pressed (e.g. the user has\n * up to n seconds between each keypress, rather than n seconds to invoke the\n * entire sequence.)\n *\n * @private\n */\n setKeypressTimer() {\n // Clear any existing timeout. This is so only one timer is running even if\n // there are multiple keypresses in quick succession.\n if (this.keypressTimeoutId) {\n window.clearTimeout(this.keypressTimeoutId)\n }\n\n // Set a fresh timeout\n this.keypressTimeoutId = window.setTimeout(\n this.resetKeypressTimer.bind(this),\n this.timeoutTime\n )\n }\n\n /**\n * Stops and resets the 'quick escape' keyboard sequence timer.\n *\n * @private\n */\n resetKeypressTimer() {\n if (!this.$updateSpan) {\n return\n }\n\n if (this.keypressTimeoutId) {\n window.clearTimeout(this.keypressTimeoutId)\n this.keypressTimeoutId = null\n }\n\n const $updateSpan = this.$updateSpan\n\n this.keypressCounter = 0\n $updateSpan.textContent = this.i18n.t('timedOut')\n\n this.timeoutMessageId = window.setTimeout(() => {\n $updateSpan.textContent = ''\n }, this.timeoutTime)\n\n this.updateIndicator()\n }\n\n /**\n * Reset the page using the EtP button\n *\n * We use this in situations where a user may re-enter a page using the browser\n * back button. In these cases, the browser can choose to restore the state of\n * the page as it was previously, including restoring the 'ghost page' overlay,\n * the announcement span having it's role set to \"alert\" and the keypress\n * indicator still active, leaving the page in an unusable state.\n *\n * By running this check when the page is shown, we can programatically restore\n * the page and the component to a \"default\" state\n *\n * @private\n */\n resetPage() {\n // If an overlay is set, remove it and reset the value\n document.body.classList.remove('govuk-exit-this-page-hide-content')\n\n if (this.$overlay) {\n this.$overlay.remove()\n this.$overlay = null\n }\n\n // Ensure the announcement span's role is status, not alert and clear any text\n if (this.$updateSpan) {\n this.$updateSpan.setAttribute('role', 'status')\n this.$updateSpan.textContent = ''\n }\n\n // Sync the keypress indicator lights\n this.updateIndicator()\n\n // If the timeouts are active, clear them\n if (this.keypressTimeoutId) {\n window.clearTimeout(this.keypressTimeoutId)\n }\n\n if (this.timeoutMessageId) {\n window.clearTimeout(this.timeoutMessageId)\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'govuk-exit-this-page'\n\n /**\n * Exit this page default config\n *\n * @see {@link ExitThisPageConfig}\n * @constant\n * @type {ExitThisPageConfig}\n */\n static defaults = Object.freeze({\n i18n: {\n activated: 'Loading.',\n timedOut: 'Exit this page expired.',\n pressTwoMoreTimes: 'Shift, press 2 more times to exit.',\n pressOneMoreTime: 'Shift, press 1 more time to exit.'\n }\n })\n\n /**\n * Exit this page config schema\n *\n * @constant\n * @satisfies {Schema<ExitThisPageConfig>}\n */\n static schema = Object.freeze({\n properties: {\n i18n: { type: 'object' }\n }\n })\n}\n\n/**\n * Exit this Page config\n *\n * @see {@link ExitThisPage.defaults}\n * @typedef {object} ExitThisPageConfig\n * @property {ExitThisPageTranslations} [i18n=ExitThisPage.defaults.i18n] - Exit this page translations\n */\n\n/**\n * Exit this Page translations\n *\n * @see {@link ExitThisPage.defaults.i18n}\n * @typedef {object} ExitThisPageTranslations\n *\n * Messages used by the component programatically inserted text, including\n * overlay text and screen reader announcements.\n * @property {string} [activated] - Screen reader announcement for when EtP\n * keypress functionality has been successfully activated.\n * @property {string} [timedOut] - Screen reader announcement for when the EtP\n * keypress functionality has timed out.\n * @property {string} [pressTwoMoreTimes] - Screen reader announcement informing\n * the user they must press the activation key two more times.\n * @property {string} [pressOneMoreTime] - Screen reader announcement informing\n * the user they must press the activation key one more time.\n */\n\n/**\n * @import { Schema } from '../../common/configuration.mjs'\n */\n"],"names":["ExitThisPage","ConfigurableComponent","constructor","$root","config","i18n","$button","$skiplinkButton","$updateSpan","$indicatorContainer","$overlay","keypressCounter","lastKeyWasModified","timeoutTime","keypressTimeoutId","timeoutMessageId","querySelector","HTMLAnchorElement","ElementError","component","element","expectedType","identifier","I18n","document","buildIndicator","initUpdateSpan","initButtonClickHandler","body","dataset","addEventListener","handleKeypress","bind","govukFrontendExitThisPageKeypress","window","resetPage","createElement","setAttribute","className","appendChild","handleClick","i","$indicator","updateIndicator","classList","toggle","$indicators","querySelectorAll","forEach","index","exitPage","textContent","add","t","location","href","event","preventDefault","key","clearTimeout","setKeypressTimer","resetKeypressTimer","shiftKey","setTimeout","remove","moduleName","defaults","Object","freeze","activated","timedOut","pressTwoMoreTimes","pressOneMoreTime","schema","properties","type"],"mappings":"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"}