{"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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"}