govuk_publishing_components 35.11.0 → 35.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-core.js +2 -48
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-form-tracker.js +5 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-link-tracker.js +2 -2
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-schemas.js +51 -5
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-scroll-tracker.js +225 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/init-ga4.js +0 -5
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4.js +1 -0
- data/app/views/govuk_publishing_components/components/_attachment.html.erb +3 -1
- data/app/views/govuk_publishing_components/components/_tabs.html.erb +30 -14
- data/app/views/govuk_publishing_components/components/docs/tabs.yml +25 -2
- data/lib/govuk_publishing_components/version.rb +1 -1
- data/node_modules/govuk-frontend/govuk/all.js +406 -1
- data/node_modules/govuk-frontend/govuk/all.js.map +1 -1
- data/node_modules/govuk-frontend/govuk/common/govuk-frontend-version.js +1 -1
- data/node_modules/govuk-frontend/govuk/components/_all.scss +2 -1
- data/node_modules/govuk-frontend/govuk/components/back-link/_index.scss +8 -0
- data/node_modules/govuk-frontend/govuk/components/back-link/fixtures.json +9 -0
- data/node_modules/govuk-frontend/govuk/components/breadcrumbs/_index.scss +12 -0
- data/node_modules/govuk-frontend/govuk/components/breadcrumbs/fixtures.json +21 -0
- data/node_modules/govuk-frontend/govuk/components/button/_index.scss +41 -3
- data/node_modules/govuk-frontend/govuk/components/button/fixtures.json +44 -0
- data/node_modules/govuk-frontend/govuk/components/checkboxes/macro-options.json +9 -8
- data/node_modules/govuk-frontend/govuk/components/exit-this-page/README.md +15 -0
- data/node_modules/govuk-frontend/govuk/components/exit-this-page/_exit-this-page.scss +2 -0
- data/node_modules/govuk-frontend/govuk/components/exit-this-page/_index.scss +97 -0
- data/node_modules/govuk-frontend/govuk/components/exit-this-page/exit-this-page.js +2120 -0
- data/node_modules/govuk-frontend/govuk/components/exit-this-page/exit-this-page.js.map +1 -0
- data/node_modules/govuk-frontend/govuk/components/exit-this-page/fixtures.json +50 -0
- data/node_modules/govuk-frontend/govuk/components/exit-this-page/macro-options.json +62 -0
- data/node_modules/govuk-frontend/govuk/components/exit-this-page/macro.njk +3 -0
- data/node_modules/govuk-frontend/govuk/components/exit-this-page/template.njk +16 -0
- data/node_modules/govuk-frontend/govuk/components/radios/macro-options.json +9 -8
- data/node_modules/govuk-frontend/govuk/core/_govuk-frontend-version.scss +1 -1
- data/node_modules/govuk-frontend/govuk/helpers/_visually-hidden.scss +12 -0
- data/node_modules/govuk-frontend/govuk/objects/_template.scss +20 -0
- data/node_modules/govuk-frontend/govuk-esm/all.mjs +8 -0
- data/node_modules/govuk-frontend/govuk-esm/all.mjs.map +1 -1
- data/node_modules/govuk-frontend/govuk-esm/common/govuk-frontend-version.mjs +1 -1
- data/node_modules/govuk-frontend/govuk-esm/components/exit-this-page/exit-this-page.mjs +406 -0
- data/node_modules/govuk-frontend/govuk-esm/components/exit-this-page/exit-this-page.mjs.map +1 -0
- data/node_modules/govuk-frontend/govuk-prototype-kit.config.json +4 -0
- data/node_modules/govuk-frontend/package.json +4 -2
- metadata +14 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"all.mjs","sources":["../../src/govuk/all.mjs"],"sourcesContent":["import { version } from './common/govuk-frontend-version.mjs'\nimport { nodeListForEach } from './common/index.mjs'\nimport Accordion from './components/accordion/accordion.mjs'\nimport Button from './components/button/button.mjs'\nimport CharacterCount from './components/character-count/character-count.mjs'\nimport Checkboxes from './components/checkboxes/checkboxes.mjs'\nimport Details from './components/details/details.mjs'\nimport ErrorSummary from './components/error-summary/error-summary.mjs'\nimport Header from './components/header/header.mjs'\nimport NotificationBanner from './components/notification-banner/notification-banner.mjs'\nimport Radios from './components/radios/radios.mjs'\nimport SkipLink from './components/skip-link/skip-link.mjs'\nimport Tabs from './components/tabs/tabs.mjs'\n\n/**\n * Initialise all components\n *\n * Use the `data-module` attributes to find, instantiate and init all of the\n * components provided as part of GOV.UK Frontend.\n *\n * @param {Config} [config] - Config for all components\n */\nfunction initAll (config) {\n config = typeof config !== 'undefined' ? config : {}\n\n // Allow the user to initialise GOV.UK Frontend in only certain sections of the page\n // Defaults to the entire document if nothing is set.\n var $scope = config.scope instanceof HTMLElement ? config.scope : document\n\n var $accordions = $scope.querySelectorAll('[data-module=\"govuk-accordion\"]')\n nodeListForEach($accordions, function ($accordion) {\n new Accordion($accordion, config.accordion).init()\n })\n\n var $buttons = $scope.querySelectorAll('[data-module=\"govuk-button\"]')\n nodeListForEach($buttons, function ($button) {\n new Button($button, config.button).init()\n })\n\n var $characterCounts = $scope.querySelectorAll('[data-module=\"govuk-character-count\"]')\n nodeListForEach($characterCounts, function ($characterCount) {\n new CharacterCount($characterCount, config.characterCount).init()\n })\n\n var $checkboxes = $scope.querySelectorAll('[data-module=\"govuk-checkboxes\"]')\n nodeListForEach($checkboxes, function ($checkbox) {\n new Checkboxes($checkbox).init()\n })\n\n var $details = $scope.querySelectorAll('[data-module=\"govuk-details\"]')\n nodeListForEach($details, function ($detail) {\n new Details($detail).init()\n })\n\n // Find first error summary module to enhance.\n var $errorSummary = $scope.querySelector('[data-module=\"govuk-error-summary\"]')\n if ($errorSummary) {\n new ErrorSummary($errorSummary, config.errorSummary).init()\n }\n\n // Find first header module to enhance.\n var $header = $scope.querySelector('[data-module=\"govuk-header\"]')\n if ($header) {\n new Header($header).init()\n }\n\n var $notificationBanners = $scope.querySelectorAll('[data-module=\"govuk-notification-banner\"]')\n nodeListForEach($notificationBanners, function ($notificationBanner) {\n new NotificationBanner($notificationBanner, config.notificationBanner).init()\n })\n\n var $radios = $scope.querySelectorAll('[data-module=\"govuk-radios\"]')\n nodeListForEach($radios, function ($radio) {\n new Radios($radio).init()\n })\n\n // Find first skip link module to enhance.\n var $skipLink = $scope.querySelector('[data-module=\"govuk-skip-link\"]')\n if ($skipLink) {\n new SkipLink($skipLink).init()\n }\n\n var $tabs = $scope.querySelectorAll('[data-module=\"govuk-tabs\"]')\n nodeListForEach($tabs, function ($tabs) {\n new Tabs($tabs).init()\n })\n}\n\nexport {\n initAll,\n version,\n\n // Components\n Accordion,\n Button,\n Details,\n CharacterCount,\n Checkboxes,\n ErrorSummary,\n Header,\n NotificationBanner,\n Radios,\n SkipLink,\n Tabs\n}\n\n/**\n * Config for all components\n *\n * @typedef {object} Config\n * @property {Element} [scope=document] - Scope to query for components\n * @property {import('./components/accordion/accordion.mjs').AccordionConfig} [accordion] - Accordion config\n * @property {import('./components/button/button.mjs').ButtonConfig} [button] - Button config\n * @property {import('./components/character-count/character-count.mjs').CharacterCountConfig} [characterCount] - Character Count config\n * @property {import('./components/error-summary/error-summary.mjs').ErrorSummaryConfig} [errorSummary] - Error Summary config\n * @property {import('./components/notification-banner/notification-banner.mjs').NotificationBannerConfig} [notificationBanner] - Notification Banner config\n */\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"all.mjs","sources":["../../src/govuk/all.mjs"],"sourcesContent":["import { version } from './common/govuk-frontend-version.mjs'\nimport { nodeListForEach } from './common/index.mjs'\nimport Accordion from './components/accordion/accordion.mjs'\nimport Button from './components/button/button.mjs'\nimport CharacterCount from './components/character-count/character-count.mjs'\nimport Checkboxes from './components/checkboxes/checkboxes.mjs'\nimport Details from './components/details/details.mjs'\nimport ErrorSummary from './components/error-summary/error-summary.mjs'\nimport ExitThisPage from './components/exit-this-page/exit-this-page.mjs'\nimport Header from './components/header/header.mjs'\nimport NotificationBanner from './components/notification-banner/notification-banner.mjs'\nimport Radios from './components/radios/radios.mjs'\nimport SkipLink from './components/skip-link/skip-link.mjs'\nimport Tabs from './components/tabs/tabs.mjs'\n\n/**\n * Initialise all components\n *\n * Use the `data-module` attributes to find, instantiate and init all of the\n * components provided as part of GOV.UK Frontend.\n *\n * @param {Config} [config] - Config for all components\n */\nfunction initAll (config) {\n config = typeof config !== 'undefined' ? config : {}\n\n // Allow the user to initialise GOV.UK Frontend in only certain sections of the page\n // Defaults to the entire document if nothing is set.\n var $scope = config.scope instanceof HTMLElement ? config.scope : document\n\n var $accordions = $scope.querySelectorAll('[data-module=\"govuk-accordion\"]')\n nodeListForEach($accordions, function ($accordion) {\n new Accordion($accordion, config.accordion).init()\n })\n\n var $buttons = $scope.querySelectorAll('[data-module=\"govuk-button\"]')\n nodeListForEach($buttons, function ($button) {\n new Button($button, config.button).init()\n })\n\n var $characterCounts = $scope.querySelectorAll('[data-module=\"govuk-character-count\"]')\n nodeListForEach($characterCounts, function ($characterCount) {\n new CharacterCount($characterCount, config.characterCount).init()\n })\n\n var $checkboxes = $scope.querySelectorAll('[data-module=\"govuk-checkboxes\"]')\n nodeListForEach($checkboxes, function ($checkbox) {\n new Checkboxes($checkbox).init()\n })\n\n var $details = $scope.querySelectorAll('[data-module=\"govuk-details\"]')\n nodeListForEach($details, function ($detail) {\n new Details($detail).init()\n })\n\n // Find first error summary module to enhance.\n var $errorSummary = $scope.querySelector('[data-module=\"govuk-error-summary\"]')\n if ($errorSummary) {\n new ErrorSummary($errorSummary, config.errorSummary).init()\n }\n\n var $exitThisPageButtons = $scope.querySelectorAll('[data-module=\"govuk-exit-this-page\"]')\n nodeListForEach($exitThisPageButtons, function ($button) {\n new ExitThisPage($button, config.exitThisPage).init()\n })\n\n // Find first header module to enhance.\n var $header = $scope.querySelector('[data-module=\"govuk-header\"]')\n if ($header) {\n new Header($header).init()\n }\n\n var $notificationBanners = $scope.querySelectorAll('[data-module=\"govuk-notification-banner\"]')\n nodeListForEach($notificationBanners, function ($notificationBanner) {\n new NotificationBanner($notificationBanner, config.notificationBanner).init()\n })\n\n var $radios = $scope.querySelectorAll('[data-module=\"govuk-radios\"]')\n nodeListForEach($radios, function ($radio) {\n new Radios($radio).init()\n })\n\n // Find first skip link module to enhance.\n var $skipLink = $scope.querySelector('[data-module=\"govuk-skip-link\"]')\n if ($skipLink) {\n new SkipLink($skipLink).init()\n }\n\n var $tabs = $scope.querySelectorAll('[data-module=\"govuk-tabs\"]')\n nodeListForEach($tabs, function ($tabs) {\n new Tabs($tabs).init()\n })\n}\n\nexport {\n initAll,\n version,\n\n // Components\n Accordion,\n Button,\n Details,\n CharacterCount,\n Checkboxes,\n ErrorSummary,\n ExitThisPage,\n Header,\n NotificationBanner,\n Radios,\n SkipLink,\n Tabs\n}\n\n/**\n * Config for all components\n *\n * @typedef {object} Config\n * @property {Element} [scope=document] - Scope to query for components\n * @property {import('./components/accordion/accordion.mjs').AccordionConfig} [accordion] - Accordion config\n * @property {import('./components/button/button.mjs').ButtonConfig} [button] - Button config\n * @property {import('./components/character-count/character-count.mjs').CharacterCountConfig} [characterCount] - Character Count config\n * @property {import('./components/error-summary/error-summary.mjs').ErrorSummaryConfig} [errorSummary] - Error Summary config\n * @property {import('./components/exit-this-page/exit-this-page.mjs').ExitThisPageConfig} [exitThisPage] - Exit This Page config\n * @property {import('./components/notification-banner/notification-banner.mjs').NotificationBannerConfig} [notificationBanner] - Notification Banner config\n */\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import { normaliseDataset } from '../../common/normalise-dataset.mjs';
|
|
2
|
+
import { I18n } from '../../i18n.mjs';
|
|
3
|
+
import '../../vendor/polyfills/Element/prototype/classList.mjs';
|
|
4
|
+
import '../../vendor/polyfills/Event.mjs';
|
|
5
|
+
import '../../vendor/polyfills/Element/prototype/dataset.mjs';
|
|
6
|
+
import '../../vendor/polyfills/Function/prototype/bind.mjs';
|
|
7
|
+
import { nodeListForEach, mergeConfigs, extractConfigByNamespace } from '../../common/index.mjs';
|
|
8
|
+
|
|
9
|
+
/* eslint-disable es-x/no-function-prototype-bind -- Polyfill imported */
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @constant
|
|
13
|
+
* @type {ExitThisPageTranslations}
|
|
14
|
+
* @see Default value for {@link ExitThisPageConfig.i18n}
|
|
15
|
+
* @default
|
|
16
|
+
*/
|
|
17
|
+
var EXIT_THIS_PAGE_TRANSLATIONS = {
|
|
18
|
+
activated: 'Loading.',
|
|
19
|
+
timedOut: 'Exit this page expired.',
|
|
20
|
+
pressTwoMoreTimes: 'Shift, press 2 more times to exit.',
|
|
21
|
+
pressOneMoreTime: 'Shift, press 1 more time to exit.'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Exit This Page component
|
|
26
|
+
*
|
|
27
|
+
* @class
|
|
28
|
+
* @param {HTMLElement} $module - HTML element that wraps the Exit This Page button
|
|
29
|
+
* @param {ExitThisPageConfig} [config] - Exit This Page config
|
|
30
|
+
*/
|
|
31
|
+
function ExitThisPage ($module, config) {
|
|
32
|
+
/** @type {ExitThisPageConfig} */
|
|
33
|
+
var defaultConfig = {
|
|
34
|
+
i18n: EXIT_THIS_PAGE_TRANSLATIONS
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (!($module instanceof HTMLElement)) {
|
|
38
|
+
return this
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var $button = $module.querySelector('.govuk-exit-this-page__button');
|
|
42
|
+
if (!($button instanceof HTMLElement)) {
|
|
43
|
+
return this
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated Will be made private in v5.0
|
|
48
|
+
* @type {ExitThisPageConfig}
|
|
49
|
+
*/
|
|
50
|
+
this.config = mergeConfigs(
|
|
51
|
+
defaultConfig,
|
|
52
|
+
config || {},
|
|
53
|
+
normaliseDataset($module.dataset)
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
this.i18n = new I18n(extractConfigByNamespace(this.config, 'i18n'));
|
|
57
|
+
|
|
58
|
+
/** @deprecated Will be made private in v5.0 */
|
|
59
|
+
this.$module = $module;
|
|
60
|
+
|
|
61
|
+
/** @deprecated Will be made private in v5.0 */
|
|
62
|
+
this.$button = $button;
|
|
63
|
+
|
|
64
|
+
/** @deprecated Will be made private in v5.0 */
|
|
65
|
+
this.$skiplinkButton = document.querySelector('.govuk-js-exit-this-page-skiplink');
|
|
66
|
+
|
|
67
|
+
/** @deprecated Will be made private in v5.0 */
|
|
68
|
+
this.$updateSpan = null;
|
|
69
|
+
|
|
70
|
+
/** @deprecated Will be made private in v5.0 */
|
|
71
|
+
this.$indicatorContainer = null;
|
|
72
|
+
|
|
73
|
+
/** @deprecated Will be made private in v5.0 */
|
|
74
|
+
this.$overlay = null;
|
|
75
|
+
|
|
76
|
+
/** @deprecated Will be made private in v5.0 */
|
|
77
|
+
this.keypressCounter = 0;
|
|
78
|
+
|
|
79
|
+
/** @deprecated Will be made private in v5.0 */
|
|
80
|
+
this.lastKeyWasModified = false;
|
|
81
|
+
|
|
82
|
+
/** @deprecated Will be made private in v5.0 */
|
|
83
|
+
this.timeoutTime = 5000; // milliseconds
|
|
84
|
+
|
|
85
|
+
// Store the timeout events so that we can clear them to avoid user keypresses overlapping
|
|
86
|
+
// setTimeout returns an id that we can use to clear it with clearTimeout,
|
|
87
|
+
// hence the 'Id' suffix
|
|
88
|
+
|
|
89
|
+
/** @deprecated Will be made private in v5.0 */
|
|
90
|
+
this.keypressTimeoutId = null;
|
|
91
|
+
|
|
92
|
+
/** @deprecated Will be made private in v5.0 */
|
|
93
|
+
this.timeoutMessageId = null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Create the <span> we use for screen reader announcements.
|
|
98
|
+
*
|
|
99
|
+
* @deprecated Will be made private in v5.0
|
|
100
|
+
*/
|
|
101
|
+
ExitThisPage.prototype.initUpdateSpan = function () {
|
|
102
|
+
this.$updateSpan = document.createElement('span');
|
|
103
|
+
this.$updateSpan.setAttribute('role', 'status');
|
|
104
|
+
this.$updateSpan.className = 'govuk-visually-hidden';
|
|
105
|
+
|
|
106
|
+
this.$module.appendChild(this.$updateSpan);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Create button click handlers.
|
|
111
|
+
*
|
|
112
|
+
* @deprecated Will be made private in v5.0
|
|
113
|
+
*/
|
|
114
|
+
ExitThisPage.prototype.initButtonClickHandler = function () {
|
|
115
|
+
// Main EtP button
|
|
116
|
+
this.$button.addEventListener('click', this.handleClick.bind(this));
|
|
117
|
+
|
|
118
|
+
// EtP skiplink
|
|
119
|
+
if (this.$skiplinkButton) {
|
|
120
|
+
this.$skiplinkButton.addEventListener('click', this.handleClick.bind(this));
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Create the HTML for the 'three lights' indicator on the button.
|
|
126
|
+
*
|
|
127
|
+
* @deprecated Will be made private in v5.0
|
|
128
|
+
*/
|
|
129
|
+
ExitThisPage.prototype.buildIndicator = function () {
|
|
130
|
+
// Build container
|
|
131
|
+
// Putting `aria-hidden` on it as it won't contain any readable information
|
|
132
|
+
this.$indicatorContainer = document.createElement('div');
|
|
133
|
+
this.$indicatorContainer.className = 'govuk-exit-this-page__indicator';
|
|
134
|
+
this.$indicatorContainer.setAttribute('aria-hidden', 'true');
|
|
135
|
+
|
|
136
|
+
// Create three 'lights' and place them within the container
|
|
137
|
+
for (var i = 0; i < 3; i++) {
|
|
138
|
+
var $indicator = document.createElement('div');
|
|
139
|
+
$indicator.className = 'govuk-exit-this-page__indicator-light';
|
|
140
|
+
this.$indicatorContainer.appendChild($indicator);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Append it all to the module
|
|
144
|
+
this.$button.appendChild(this.$indicatorContainer);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Update whether the lights are visible and which ones are lit up depending on
|
|
149
|
+
* the value of `keypressCounter`.
|
|
150
|
+
*
|
|
151
|
+
* @deprecated Will be made private in v5.0
|
|
152
|
+
*/
|
|
153
|
+
ExitThisPage.prototype.updateIndicator = function () {
|
|
154
|
+
// Show or hide the indicator container depending on keypressCounter value
|
|
155
|
+
if (this.keypressCounter > 0) {
|
|
156
|
+
this.$indicatorContainer.classList.add('govuk-exit-this-page__indicator--visible');
|
|
157
|
+
} else {
|
|
158
|
+
this.$indicatorContainer.classList.remove('govuk-exit-this-page__indicator--visible');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Turn on only the indicators we want on
|
|
162
|
+
var $indicators = this.$indicatorContainer.querySelectorAll(
|
|
163
|
+
'.govuk-exit-this-page__indicator-light'
|
|
164
|
+
);
|
|
165
|
+
nodeListForEach($indicators, function ($indicator, index) {
|
|
166
|
+
$indicator.classList.toggle(
|
|
167
|
+
'govuk-exit-this-page__indicator-light--on',
|
|
168
|
+
index < this.keypressCounter
|
|
169
|
+
);
|
|
170
|
+
}.bind(this));
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Initiates the redirection away from the current page.
|
|
175
|
+
* Includes the loading overlay functionality, which covers the current page with a
|
|
176
|
+
* white overlay so that the contents are not visible during the loading
|
|
177
|
+
* process. This is particularly important on slow network connections.
|
|
178
|
+
*
|
|
179
|
+
* @deprecated Will be made private in v5.0
|
|
180
|
+
*/
|
|
181
|
+
ExitThisPage.prototype.exitPage = function () {
|
|
182
|
+
this.$updateSpan.innerText = '';
|
|
183
|
+
|
|
184
|
+
// Blank the page
|
|
185
|
+
// As well as creating an overlay with text, we also set the body to hidden
|
|
186
|
+
// to prevent screen reader and sequential navigation users potentially
|
|
187
|
+
// navigating through the page behind the overlay during loading
|
|
188
|
+
document.body.classList.add('govuk-exit-this-page-hide-content');
|
|
189
|
+
this.$overlay = document.createElement('div');
|
|
190
|
+
this.$overlay.className = 'govuk-exit-this-page-overlay';
|
|
191
|
+
this.$overlay.setAttribute('role', 'alert');
|
|
192
|
+
|
|
193
|
+
// we do these this way round, thus incurring a second paint, because changing
|
|
194
|
+
// the element text after adding it means that screen readers pick up the
|
|
195
|
+
// announcement more reliably.
|
|
196
|
+
document.body.appendChild(this.$overlay);
|
|
197
|
+
this.$overlay.innerText = this.i18n.t('activated');
|
|
198
|
+
|
|
199
|
+
window.location.href = this.$button.getAttribute('href');
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Pre-activation logic for when the button is clicked/activated via mouse or
|
|
204
|
+
* pointer.
|
|
205
|
+
*
|
|
206
|
+
* We do this to differentiate it from the keyboard activation event because we
|
|
207
|
+
* need to run `e.preventDefault` as the button or skiplink are both links and we
|
|
208
|
+
* want to apply some additional logic in `exitPage` before navigating.
|
|
209
|
+
*
|
|
210
|
+
* @deprecated Will be made private in v5.0
|
|
211
|
+
* @param {MouseEvent} event - mouse click event
|
|
212
|
+
*/
|
|
213
|
+
ExitThisPage.prototype.handleClick = function (event) {
|
|
214
|
+
event.preventDefault();
|
|
215
|
+
this.exitPage();
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Logic for the 'quick escape' keyboard sequence functionality (pressing the
|
|
220
|
+
* Shift key three times without interruption, within a time limit).
|
|
221
|
+
*
|
|
222
|
+
* @deprecated Will be made private in v5.0
|
|
223
|
+
* @param {KeyboardEvent} event - keyup event
|
|
224
|
+
*/
|
|
225
|
+
ExitThisPage.prototype.handleKeypress = function (event) {
|
|
226
|
+
// Detect if the 'Shift' key has been pressed. We want to only do things if it
|
|
227
|
+
// was pressed by itself and not in a combination with another key—so we keep
|
|
228
|
+
// track of whether the preceding keyup had shiftKey: true on it, and if it
|
|
229
|
+
// did, we ignore the next Shift keyup event.
|
|
230
|
+
//
|
|
231
|
+
// This works because using Shift as a modifier key (e.g. pressing Shift + A)
|
|
232
|
+
// will fire TWO keyup events, one for A (with e.shiftKey: true) and the other
|
|
233
|
+
// for Shift (with e.shiftKey: false).
|
|
234
|
+
if (
|
|
235
|
+
(event.key === 'Shift' || event.keyCode === 16 || event.which === 16) &&
|
|
236
|
+
!this.lastKeyWasModified
|
|
237
|
+
) {
|
|
238
|
+
this.keypressCounter += 1;
|
|
239
|
+
|
|
240
|
+
// Update the indicator before the below if statement can reset it back to 0
|
|
241
|
+
this.updateIndicator();
|
|
242
|
+
|
|
243
|
+
// Clear the timeout for the keypress timeout message clearing itself
|
|
244
|
+
if (this.timeoutMessageId !== null) {
|
|
245
|
+
clearTimeout(this.timeoutMessageId);
|
|
246
|
+
this.timeoutMessageId = null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (this.keypressCounter >= 3) {
|
|
250
|
+
this.keypressCounter = 0;
|
|
251
|
+
|
|
252
|
+
if (this.keypressTimeoutId !== null) {
|
|
253
|
+
clearTimeout(this.keypressTimeoutId);
|
|
254
|
+
this.keypressTimeoutId = null;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
this.exitPage();
|
|
258
|
+
} else {
|
|
259
|
+
if (this.keypressCounter === 1) {
|
|
260
|
+
this.$updateSpan.innerText = this.i18n.t('pressTwoMoreTimes');
|
|
261
|
+
} else {
|
|
262
|
+
this.$updateSpan.innerText = this.i18n.t('pressOneMoreTime');
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
this.setKeypressTimer();
|
|
267
|
+
} else if (this.keypressTimeoutId !== null) {
|
|
268
|
+
// If the user pressed any key other than 'Shift', after having pressed
|
|
269
|
+
// 'Shift' and activating the timer, stop and reset the timer.
|
|
270
|
+
this.resetKeypressTimer();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Keep track of whether the Shift modifier key was held during this keypress
|
|
274
|
+
this.lastKeyWasModified = event.shiftKey;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Starts the 'quick escape' keyboard sequence timer.
|
|
279
|
+
*
|
|
280
|
+
* This can be invoked several times. We want this to be possible so that the
|
|
281
|
+
* timer is restarted each time the shortcut key is pressed (e.g. the user has
|
|
282
|
+
* up to n seconds between each keypress, rather than n seconds to invoke the
|
|
283
|
+
* entire sequence.)
|
|
284
|
+
*
|
|
285
|
+
* @deprecated Will be made private in v5.0
|
|
286
|
+
*/
|
|
287
|
+
ExitThisPage.prototype.setKeypressTimer = function () {
|
|
288
|
+
// Clear any existing timeout. This is so only one timer is running even if
|
|
289
|
+
// there are multiple keypresses in quick succession.
|
|
290
|
+
clearTimeout(this.keypressTimeoutId);
|
|
291
|
+
|
|
292
|
+
// Set a fresh timeout
|
|
293
|
+
this.keypressTimeoutId = setTimeout(
|
|
294
|
+
this.resetKeypressTimer.bind(this),
|
|
295
|
+
this.timeoutTime
|
|
296
|
+
);
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Stops and resets the 'quick escape' keyboard sequence timer.
|
|
301
|
+
*
|
|
302
|
+
* @deprecated Will be made private in v5.0
|
|
303
|
+
*/
|
|
304
|
+
ExitThisPage.prototype.resetKeypressTimer = function () {
|
|
305
|
+
clearTimeout(this.keypressTimeoutId);
|
|
306
|
+
this.keypressTimeoutId = null;
|
|
307
|
+
|
|
308
|
+
this.keypressCounter = 0;
|
|
309
|
+
this.$updateSpan.innerText = this.i18n.t('timedOut');
|
|
310
|
+
|
|
311
|
+
this.timeoutMessageId = setTimeout(function () {
|
|
312
|
+
this.$updateSpan.innerText = '';
|
|
313
|
+
}.bind(this), this.timeoutTime);
|
|
314
|
+
|
|
315
|
+
this.updateIndicator();
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Reset the page using the EtP button
|
|
320
|
+
*
|
|
321
|
+
* We use this in situations where a user may re-enter a page using the browser
|
|
322
|
+
* back button. In these cases, the browser can choose to restore the state of
|
|
323
|
+
* the page as it was previously, including restoring the 'ghost page' overlay,
|
|
324
|
+
* the announcement span having it's role set to "alert" and the keypress
|
|
325
|
+
* indicator still active, leaving the page in an unusable state.
|
|
326
|
+
*
|
|
327
|
+
* By running this check when the page is shown, we can programatically restore
|
|
328
|
+
* the page and the component to a "default" state
|
|
329
|
+
*
|
|
330
|
+
* @deprecated Will be made private in v5.0
|
|
331
|
+
*/
|
|
332
|
+
ExitThisPage.prototype.resetPage = function () {
|
|
333
|
+
// If an overlay is set, remove it and reset the value
|
|
334
|
+
document.body.classList.remove('govuk-exit-this-page-hide-content');
|
|
335
|
+
|
|
336
|
+
if (this.$overlay) {
|
|
337
|
+
this.$overlay.remove();
|
|
338
|
+
this.$overlay = null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Ensure the announcement span's role is status, not alert and clear any text
|
|
342
|
+
this.$updateSpan.setAttribute('role', 'status');
|
|
343
|
+
this.$updateSpan.innerText = '';
|
|
344
|
+
|
|
345
|
+
// Sync the keypress indicator lights
|
|
346
|
+
this.updateIndicator();
|
|
347
|
+
|
|
348
|
+
// If the timeouts are active, clear them
|
|
349
|
+
if (this.keypressTimeoutId) {
|
|
350
|
+
clearTimeout(this.keypressTimeoutId);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (this.timeoutMessageId) {
|
|
354
|
+
clearTimeout(this.timeoutMessageId);
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Initialise component
|
|
360
|
+
*/
|
|
361
|
+
ExitThisPage.prototype.init = function () {
|
|
362
|
+
this.buildIndicator();
|
|
363
|
+
this.initUpdateSpan();
|
|
364
|
+
this.initButtonClickHandler();
|
|
365
|
+
|
|
366
|
+
// Check to see if this has already been done by a previous initialisation of ExitThisPage
|
|
367
|
+
if (!('govukFrontendExitThisPageKeypress' in document.body.dataset)) {
|
|
368
|
+
document.addEventListener('keyup', this.handleKeypress.bind(this), true);
|
|
369
|
+
document.body.dataset.govukFrontendExitThisPageKeypress = 'true';
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// When the page is restored after navigating 'back' in some browsers the
|
|
373
|
+
// blank overlay remains present, rendering the page unusable. Here, we check
|
|
374
|
+
// to see if it's present on page (re)load, and remove it if so.
|
|
375
|
+
window.addEventListener(
|
|
376
|
+
'onpageshow' in window ? 'pageshow' : 'DOMContentLoaded',
|
|
377
|
+
this.resetPage.bind(this)
|
|
378
|
+
);
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Exit this Page config
|
|
383
|
+
*
|
|
384
|
+
* @typedef {object} ExitThisPageConfig
|
|
385
|
+
* @property {ExitThisPageTranslations} [i18n = EXIT_THIS_PAGE_TRANSLATIONS] - See constant {@link EXIT_THIS_PAGE_TRANSLATIONS}
|
|
386
|
+
*/
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Exit this Page translations
|
|
390
|
+
*
|
|
391
|
+
* @typedef {object} ExitThisPageTranslations
|
|
392
|
+
*
|
|
393
|
+
* Messages used by the component programatically inserted text, including
|
|
394
|
+
* overlay text and screen reader announcements.
|
|
395
|
+
* @property {string} [activated] - Screen reader announcement for when EtP
|
|
396
|
+
* keypress functionality has been successfully activated.
|
|
397
|
+
* @property {string} [timedOut] - Screen reader announcement for when the EtP
|
|
398
|
+
* keypress functionality has timed out.
|
|
399
|
+
* @property {string} [pressTwoMoreTimes] - Screen reader announcement informing
|
|
400
|
+
* the user they must press the activation key two more times.
|
|
401
|
+
* @property {string} [pressOneMoreTime] - Screen reader announcement informing
|
|
402
|
+
* the user they must press the activation key one more time.
|
|
403
|
+
*/
|
|
404
|
+
|
|
405
|
+
export default ExitThisPage;
|
|
406
|
+
//# sourceMappingURL=components/exit-this-page/exit-this-page.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit-this-page.mjs","sources":["../../../../src/govuk/components/exit-this-page/exit-this-page.mjs"],"sourcesContent":["/* eslint-disable es-x/no-function-prototype-bind -- Polyfill imported */\n\nimport { normaliseDataset } from '../../common/normalise-dataset.mjs'\nimport { nodeListForEach, mergeConfigs, extractConfigByNamespace } from '../../common.mjs'\nimport { I18n } from '../../i18n.mjs'\nimport '../../vendor/polyfills/Element/prototype/classList.mjs'\nimport '../../vendor/polyfills/Event.mjs' // addEventListener, event.target normalization and DOMContentLoaded\nimport '../../vendor/polyfills/Element/prototype/dataset.mjs'\nimport '../../vendor/polyfills/Function/prototype/bind.mjs'\n\n/**\n * @constant\n * @type {ExitThisPageTranslations}\n * @see Default value for {@link ExitThisPageConfig.i18n}\n * @default\n */\nvar EXIT_THIS_PAGE_TRANSLATIONS = {\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 * Exit This Page component\n *\n * @class\n * @param {HTMLElement} $module - HTML element that wraps the Exit This Page button\n * @param {ExitThisPageConfig} [config] - Exit This Page config\n */\nfunction ExitThisPage ($module, config) {\n /** @type {ExitThisPageConfig} */\n var defaultConfig = {\n i18n: EXIT_THIS_PAGE_TRANSLATIONS\n }\n\n if (!($module instanceof HTMLElement)) {\n return this\n }\n\n var $button = $module.querySelector('.govuk-exit-this-page__button')\n if (!($button instanceof HTMLElement)) {\n return this\n }\n\n /**\n * @deprecated Will be made private in v5.0\n * @type {ExitThisPageConfig}\n */\n this.config = mergeConfigs(\n defaultConfig,\n config || {},\n normaliseDataset($module.dataset)\n )\n\n this.i18n = new I18n(extractConfigByNamespace(this.config, 'i18n'))\n\n /** @deprecated Will be made private in v5.0 */\n this.$module = $module\n\n /** @deprecated Will be made private in v5.0 */\n this.$button = $button\n\n /** @deprecated Will be made private in v5.0 */\n this.$skiplinkButton = document.querySelector('.govuk-js-exit-this-page-skiplink')\n\n /** @deprecated Will be made private in v5.0 */\n this.$updateSpan = null\n\n /** @deprecated Will be made private in v5.0 */\n this.$indicatorContainer = null\n\n /** @deprecated Will be made private in v5.0 */\n this.$overlay = null\n\n /** @deprecated Will be made private in v5.0 */\n this.keypressCounter = 0\n\n /** @deprecated Will be made private in v5.0 */\n this.lastKeyWasModified = false\n\n /** @deprecated Will be made private in v5.0 */\n this.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 /** @deprecated Will be made private in v5.0 */\n this.keypressTimeoutId = null\n\n /** @deprecated Will be made private in v5.0 */\n this.timeoutMessageId = null\n}\n\n/**\n * Create the <span> we use for screen reader announcements.\n *\n * @deprecated Will be made private in v5.0\n */\nExitThisPage.prototype.initUpdateSpan = function () {\n this.$updateSpan = document.createElement('span')\n this.$updateSpan.setAttribute('role', 'status')\n this.$updateSpan.className = 'govuk-visually-hidden'\n\n this.$module.appendChild(this.$updateSpan)\n}\n\n/**\n * Create button click handlers.\n *\n * @deprecated Will be made private in v5.0\n */\nExitThisPage.prototype.initButtonClickHandler = function () {\n // Main EtP button\n this.$button.addEventListener('click', this.handleClick.bind(this))\n\n // EtP skiplink\n if (this.$skiplinkButton) {\n this.$skiplinkButton.addEventListener('click', this.handleClick.bind(this))\n }\n}\n\n/**\n * Create the HTML for the 'three lights' indicator on the button.\n *\n * @deprecated Will be made private in v5.0\n */\nExitThisPage.prototype.buildIndicator = function () {\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 (var i = 0; i < 3; i++) {\n var $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 * @deprecated Will be made private in v5.0\n */\nExitThisPage.prototype.updateIndicator = function () {\n // Show or hide the indicator container depending on keypressCounter value\n if (this.keypressCounter > 0) {\n this.$indicatorContainer.classList.add('govuk-exit-this-page__indicator--visible')\n } else {\n this.$indicatorContainer.classList.remove('govuk-exit-this-page__indicator--visible')\n }\n\n // Turn on only the indicators we want on\n var $indicators = this.$indicatorContainer.querySelectorAll(\n '.govuk-exit-this-page__indicator-light'\n )\n nodeListForEach($indicators, function ($indicator, index) {\n $indicator.classList.toggle(\n 'govuk-exit-this-page__indicator-light--on',\n index < this.keypressCounter\n )\n }.bind(this))\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 * @deprecated Will be made private in v5.0\n */\nExitThisPage.prototype.exitPage = function () {\n this.$updateSpan.innerText = ''\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.innerText = this.i18n.t('activated')\n\n window.location.href = this.$button.getAttribute('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 * @deprecated Will be made private in v5.0\n * @param {MouseEvent} event - mouse click event\n */\nExitThisPage.prototype.handleClick = function (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 * @deprecated Will be made private in v5.0\n * @param {KeyboardEvent} event - keyup event\n */\nExitThisPage.prototype.handleKeypress = function (event) {\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 (\n (event.key === 'Shift' || event.keyCode === 16 || event.which === 16) &&\n !this.lastKeyWasModified\n ) {\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 !== null) {\n clearTimeout(this.timeoutMessageId)\n this.timeoutMessageId = null\n }\n\n if (this.keypressCounter >= 3) {\n this.keypressCounter = 0\n\n if (this.keypressTimeoutId !== null) {\n clearTimeout(this.keypressTimeoutId)\n this.keypressTimeoutId = null\n }\n\n this.exitPage()\n } else {\n if (this.keypressCounter === 1) {\n this.$updateSpan.innerText = this.i18n.t('pressTwoMoreTimes')\n } else {\n this.$updateSpan.innerText = this.i18n.t('pressOneMoreTime')\n }\n }\n\n this.setKeypressTimer()\n } else if (this.keypressTimeoutId !== null) {\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 * @deprecated Will be made private in v5.0\n */\nExitThisPage.prototype.setKeypressTimer = function () {\n // Clear any existing timeout. This is so only one timer is running even if\n // there are multiple keypresses in quick succession.\n clearTimeout(this.keypressTimeoutId)\n\n // Set a fresh timeout\n this.keypressTimeoutId = 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 * @deprecated Will be made private in v5.0\n */\nExitThisPage.prototype.resetKeypressTimer = function () {\n clearTimeout(this.keypressTimeoutId)\n this.keypressTimeoutId = null\n\n this.keypressCounter = 0\n this.$updateSpan.innerText = this.i18n.t('timedOut')\n\n this.timeoutMessageId = setTimeout(function () {\n this.$updateSpan.innerText = ''\n }.bind(this), 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 * @deprecated Will be made private in v5.0\n */\nExitThisPage.prototype.resetPage = function () {\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 this.$updateSpan.setAttribute('role', 'status')\n this.$updateSpan.innerText = ''\n\n // Sync the keypress indicator lights\n this.updateIndicator()\n\n // If the timeouts are active, clear them\n if (this.keypressTimeoutId) {\n clearTimeout(this.keypressTimeoutId)\n }\n\n if (this.timeoutMessageId) {\n clearTimeout(this.timeoutMessageId)\n }\n}\n\n/**\n * Initialise component\n */\nExitThisPage.prototype.init = function () {\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(\n 'onpageshow' in window ? 'pageshow' : 'DOMContentLoaded',\n this.resetPage.bind(this)\n )\n}\n\nexport default ExitThisPage\n\n/**\n * Exit this Page config\n *\n * @typedef {object} ExitThisPageConfig\n * @property {ExitThisPageTranslations} [i18n = EXIT_THIS_PAGE_TRANSLATIONS] - See constant {@link EXIT_THIS_PAGE_TRANSLATIONS}\n */\n\n/**\n * Exit this Page translations\n *\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"],"names":[],"mappings":"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"}
|
|
@@ -55,6 +55,10 @@
|
|
|
55
55
|
"importFrom": "govuk/components/error-summary/macro.njk",
|
|
56
56
|
"macroName": "govukErrorSummary"
|
|
57
57
|
},
|
|
58
|
+
{
|
|
59
|
+
"importFrom": "govuk/components/exit-this-page/macro.njk",
|
|
60
|
+
"macroName": "govukExitThisPage"
|
|
61
|
+
},
|
|
58
62
|
{
|
|
59
63
|
"importFrom": "govuk/components/fieldset/macro.njk",
|
|
60
64
|
"macroName": "govukFieldset"
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "govuk-frontend",
|
|
3
3
|
"description": "GOV.UK Frontend contains the code you need to start building a user interface for government platforms and services.",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.7.0",
|
|
5
5
|
"main": "govuk/all.js",
|
|
6
6
|
"module": "govuk-esm/all.mjs",
|
|
7
|
+
"sass": "govuk/all.scss",
|
|
7
8
|
"exports": {
|
|
8
9
|
".": {
|
|
9
10
|
"sass": "./govuk/all.scss",
|
|
@@ -11,13 +12,14 @@
|
|
|
11
12
|
"require": "./govuk/all.js"
|
|
12
13
|
},
|
|
13
14
|
"./govuk/": "./govuk/",
|
|
15
|
+
"./govuk/*": "./govuk/*",
|
|
14
16
|
"./govuk-esm/": "./govuk-esm/",
|
|
17
|
+
"./govuk-esm/*": "./govuk-esm/*",
|
|
15
18
|
"./package.json": "./package.json"
|
|
16
19
|
},
|
|
17
20
|
"sideEffects": [
|
|
18
21
|
"govuk-esm/vendor/**"
|
|
19
22
|
],
|
|
20
|
-
"sass": "govuk/all.scss",
|
|
21
23
|
"engines": {
|
|
22
24
|
"node": ">= 4.2.0"
|
|
23
25
|
},
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: govuk_publishing_components
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 35.
|
|
4
|
+
version: 35.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GOV.UK Dev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-07-
|
|
11
|
+
date: 2023-07-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: govuk_app_config
|
|
@@ -448,6 +448,7 @@ files:
|
|
|
448
448
|
- app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-link-tracker.js
|
|
449
449
|
- app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.js
|
|
450
450
|
- app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-schemas.js
|
|
451
|
+
- app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-scroll-tracker.js
|
|
451
452
|
- app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-smart-answer-results-tracker.js
|
|
452
453
|
- app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-specialist-link-tracker.js
|
|
453
454
|
- app/assets/javascripts/govuk_publishing_components/analytics-ga4/init-ga4.js
|
|
@@ -1010,6 +1011,8 @@ files:
|
|
|
1010
1011
|
- node_modules/govuk-frontend/govuk-esm/components/details/details.mjs.map
|
|
1011
1012
|
- node_modules/govuk-frontend/govuk-esm/components/error-summary/error-summary.mjs
|
|
1012
1013
|
- node_modules/govuk-frontend/govuk-esm/components/error-summary/error-summary.mjs.map
|
|
1014
|
+
- node_modules/govuk-frontend/govuk-esm/components/exit-this-page/exit-this-page.mjs
|
|
1015
|
+
- node_modules/govuk-frontend/govuk-esm/components/exit-this-page/exit-this-page.mjs.map
|
|
1013
1016
|
- node_modules/govuk-frontend/govuk-esm/components/header/header.mjs
|
|
1014
1017
|
- node_modules/govuk-frontend/govuk-esm/components/header/header.mjs.map
|
|
1015
1018
|
- node_modules/govuk-frontend/govuk-esm/components/notification-banner/notification-banner.mjs
|
|
@@ -1175,6 +1178,15 @@ files:
|
|
|
1175
1178
|
- node_modules/govuk-frontend/govuk/components/error-summary/macro-options.json
|
|
1176
1179
|
- node_modules/govuk-frontend/govuk/components/error-summary/macro.njk
|
|
1177
1180
|
- node_modules/govuk-frontend/govuk/components/error-summary/template.njk
|
|
1181
|
+
- node_modules/govuk-frontend/govuk/components/exit-this-page/README.md
|
|
1182
|
+
- node_modules/govuk-frontend/govuk/components/exit-this-page/_exit-this-page.scss
|
|
1183
|
+
- node_modules/govuk-frontend/govuk/components/exit-this-page/_index.scss
|
|
1184
|
+
- node_modules/govuk-frontend/govuk/components/exit-this-page/exit-this-page.js
|
|
1185
|
+
- node_modules/govuk-frontend/govuk/components/exit-this-page/exit-this-page.js.map
|
|
1186
|
+
- node_modules/govuk-frontend/govuk/components/exit-this-page/fixtures.json
|
|
1187
|
+
- node_modules/govuk-frontend/govuk/components/exit-this-page/macro-options.json
|
|
1188
|
+
- node_modules/govuk-frontend/govuk/components/exit-this-page/macro.njk
|
|
1189
|
+
- node_modules/govuk-frontend/govuk/components/exit-this-page/template.njk
|
|
1178
1190
|
- node_modules/govuk-frontend/govuk/components/fieldset/README.md
|
|
1179
1191
|
- node_modules/govuk-frontend/govuk/components/fieldset/_fieldset.scss
|
|
1180
1192
|
- node_modules/govuk-frontend/govuk/components/fieldset/_index.scss
|