govuk_publishing_components 37.5.1 → 37.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/analytics/analytics.js +10 -5
  3. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-core.js +5 -0
  4. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-scroll-tracker.js +1 -1
  5. data/app/assets/javascripts/govuk_publishing_components/components/cookie-banner.js +35 -8
  6. data/app/assets/javascripts/govuk_publishing_components/domain-config.js +73 -0
  7. data/app/assets/javascripts/govuk_publishing_components/lib/cookie-settings.js +40 -19
  8. data/app/assets/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement.js +1 -1
  9. data/app/assets/javascripts/govuk_publishing_components/lib/single-consent-functions.js +59 -0
  10. data/app/assets/javascripts/govuk_publishing_components/load-analytics.js +9 -75
  11. data/app/assets/stylesheets/govuk_publishing_components/components/_contents-list.scss +1 -1
  12. data/app/assets/stylesheets/govuk_publishing_components/components/_search.scss +8 -15
  13. data/app/controllers/govuk_publishing_components/audit_controller.rb +0 -1
  14. data/app/models/govuk_publishing_components/audit_comparer.rb +0 -1
  15. data/app/views/govuk_publishing_components/components/_contents_list.html.erb +2 -0
  16. data/app/views/govuk_publishing_components/components/docs/contents_list.yml +1 -0
  17. data/config/locales/en.yml +2 -2
  18. data/lib/govuk_publishing_components/version.rb +1 -1
  19. data/node_modules/axe-core/LICENSE-3RD-PARTY.txt +66 -0
  20. data/node_modules/axe-core/README.md +4 -2
  21. data/node_modules/axe-core/axe.d.ts +21 -8
  22. data/node_modules/axe-core/axe.js +13 -11
  23. data/node_modules/axe-core/axe.min.js +3 -3
  24. data/node_modules/axe-core/package.json +3 -2
  25. data/node_modules/axe-core/sri-history.json +4 -0
  26. data/node_modules/govuk-single-consent/README.md +157 -0
  27. data/node_modules/govuk-single-consent/dist/singleconsent.cjs.js +419 -0
  28. data/node_modules/govuk-single-consent/dist/singleconsent.esm.js +417 -0
  29. data/node_modules/govuk-single-consent/dist/singleconsent.iife.js +431 -0
  30. data/node_modules/govuk-single-consent/dist/singleconsent.iife.min.js +1 -0
  31. data/node_modules/govuk-single-consent/package.json +56 -0
  32. metadata +11 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "axe-core",
3
3
  "description": "Accessibility engine for automated Web UI testing",
4
- "version": "4.8.3",
4
+ "version": "4.8.4",
5
5
  "license": "MPL-2.0",
6
6
  "engines": {
7
7
  "node": ">=4"
@@ -55,7 +55,8 @@
55
55
  "axe.min.js",
56
56
  "axe.d.ts",
57
57
  "sri-history.json",
58
- "locales/"
58
+ "locales/",
59
+ "LICENSE-3RD-PARTY.txt"
59
60
  ],
60
61
  "standard-version": {
61
62
  "scripts": {
@@ -366,5 +366,9 @@
366
366
  "4.8.3": {
367
367
  "axe.js": "sha256-YWpAAdIo7fwKmLq8nJx1f6pwt7HAXwWm15RSGJKbxhw=",
368
368
  "axe.min.js": "sha256-/mct+I/4SJnZ30Ce+j9T7ll9zPwzbJVrjdKpbKIP+NA="
369
+ },
370
+ "4.8.4": {
371
+ "axe.js": "sha256-RRn+EjX3fX893zHeLzMQebvK4/HR3yZpVFNxsV3Pbm0=",
372
+ "axe.min.js": "sha256-HXl1GEx0+LwVB27fLmwgdXCmeTM2beVwwFosWvFzLmo="
369
373
  }
370
374
  }
@@ -0,0 +1,157 @@
1
+ # Single Consent client
2
+
3
+ The Single Consent client is a small Javascript which can be embedded in a
4
+ website to enable easily sharing a user's consent or rejection of cookies across
5
+ different websites.
6
+
7
+ See the [Single Consent service README](../README.md).
8
+
9
+ ## Quick start
10
+
11
+ See the [CommonJS example](https://github.com/alphagov/consent-api/blob/main/client/examples/commonJS-usage/index.js).
12
+
13
+ Contact data-tools-team@digital.cabinet-office.gov.uk to get the URL of the API endpoint.
14
+
15
+ The library provides the following static methods for finding out which types of
16
+ cookies a user has consented to.
17
+
18
+ - `hasConsentedToEssential`
19
+ - `hasConsentedToUsage`
20
+ - `hasConsentedToCampaigns`
21
+ - `hasConsentedToSetting`
22
+
23
+ The method `GovSingleConsent.getConsents()` provides the current state of the
24
+ user's consents to all types of cookies.
25
+
26
+ ### 1. Install with npm
27
+
28
+ In order to set first-party cookies, the client Javascript must be served with
29
+ your application.
30
+
31
+ We recommend installing the Single Consent client using
32
+ [node package manager (npm)](https://www.npmjs.com/).
33
+
34
+ ```sh
35
+ npm i govuk-single-consent
36
+ ```
37
+
38
+ https://www.npmjs.com/package/govuk-single-consent
39
+
40
+ ### 2. Including the Javascript client
41
+
42
+ The javascript client can be included in different ways. Choose one below.
43
+
44
+ #### CommonJS
45
+
46
+ See the [example](https://github.com/alphagov/consent-api/blob/main/client/examples/commonJS-usage/index.js).
47
+
48
+ #### Typescript
49
+
50
+ See the [example](https://github.com/alphagov/consent-api/blob/main/client/examples/typescript-usage/index.ts).
51
+
52
+ #### HTML script tag (IIFE)
53
+
54
+ The javascript client makes available the object `window.GovSingleConsent` for
55
+ interacting with the API. It needs to be loaded on any page that could be an
56
+ entry point to your web application, that allows modifying cookie consent, or
57
+ provides a link to another domain with which you want to share cookie consent
58
+ status. It is probably easiest to add the script to a base template used for all
59
+ pages.
60
+
61
+ On the same pages, you need to load your javascript for interacting with the
62
+ `window.GovSingleConsent` object.
63
+
64
+ See the following examples.
65
+
66
+ - [Cookie banner script](https://github.com/alphagov/consent-api/blob/main/client/example/cookie-banner.js)
67
+ - [Cooke page script](https://github.com/alphagov/consent-api/blob/main/client/example/cookies-page.js)
68
+
69
+ It is common practice to add Javascript tags just before the end `</body>` tag,
70
+ eg:
71
+
72
+ ```html
73
+ ...
74
+
75
+ <script src="{path_to_client_js}/singleconsent.js"></script>
76
+ <script src="{path_to_cookie_banner_script}.js"></script>
77
+ <script src="{path_to_cookies_page_script}.js"></script>
78
+ </body>
79
+ </html>
80
+ ```
81
+
82
+ ### 3. Passing the base URL to the constructor
83
+
84
+ You can either pass an environment string, or a custom base URL.
85
+
86
+ If using an environment string, its value should be either `staging` or `production`.
87
+
88
+ e.g
89
+
90
+ ```javascript
91
+ const dummyCallback = () => {}
92
+
93
+ // With an environemnt string to the staging environment
94
+ new GovSingleConsent(dummyCallback, 'staging')
95
+
96
+ // With an environemnt string to the production environment
97
+ new GovSingleConsent(dummyCallback, 'production')
98
+
99
+ // With a custom base URL
100
+ new GovSingleConsent(dummyCallback, 'http://some-development-url.com')
101
+ ```
102
+
103
+ ### 4. Share the user's consent to cookies via the API
104
+
105
+ When the user interacts with your cookie banner or cookie settings page to
106
+ consent to or reject cookies you can update the central database by invoking the
107
+ following function:
108
+
109
+ ```typescript
110
+ exampleCookieConsentStatusObject: Consents = {
111
+ essential: true,
112
+ settings: false,
113
+ usage: true,
114
+ campaigns: false,
115
+ }
116
+
117
+ singleConsentObject.setConsents(exampleCookieConsentStatusObject)
118
+ ```
119
+
120
+ ## Content Security Policy
121
+
122
+ If your website is served with a
123
+ [`Content-Security-Policy` HTTP header or `<meta>` element](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), you
124
+ may need to modify it to allow the client to access the Single Consent service.
125
+ The value of the header or meta element should contain the following:
126
+
127
+ ```
128
+ connect-src 'self' https://consent-api-nw.a.run.app/api/v1/consent [... other site URLs separated by spaces];
129
+ ```
130
+
131
+ ## What the library does
132
+
133
+ The library manages all read/write operations with a cookie that stores the
134
+ state of a user's consent.
135
+
136
+ ### Callback
137
+
138
+ Websites using the Consent API must provide a callback function. This will be
139
+ invoked each time the consent has been updated. It will be called with three
140
+ parameters:
141
+
142
+ - `consents` An object describing the new consent state.
143
+ - `consentsPreferencesSet` Boolean, the cookie banner must be displayed if this
144
+ value is `false`.
145
+ - `error` An object describing any error, otherwise `null`. If there is an
146
+ error, then the `consents` object will say that the consents have been
147
+ revoked.
148
+
149
+ The structure of the consent data object is currently based on the
150
+ [GOV.UK `cookies_policy` cookie](https://www.gov.uk/help/cookies). If your
151
+ website cookies do not fall into any of the four categories listed, please
152
+ contact us.
153
+
154
+ ## Getting updates
155
+
156
+ To be notified when there's a new release, you can watch the
157
+ [consent-api Github repository](https://github.com/alphagov/consent-api).
@@ -0,0 +1,419 @@
1
+ 'use strict';
2
+
3
+ const DEFAULT_TIMEOUT = 10000;
4
+ function request(url, options, onSuccess, onError) {
5
+ try {
6
+ var req = new XMLHttpRequest();
7
+ var isTimeout = false;
8
+ options = options || {};
9
+ req.onreadystatechange = function () {
10
+ if (req.readyState === req.DONE) {
11
+ if (req.status >= 200 && req.status < 400) {
12
+ let jsonResponse;
13
+ try {
14
+ jsonResponse = JSON.parse(req.responseText);
15
+ onSuccess(jsonResponse);
16
+ }
17
+ catch (error) {
18
+ return onError(error);
19
+ }
20
+ }
21
+ else if (req.status === 0 && req.timeout > 0) {
22
+ // Possible timeout, waiting for ontimeout event
23
+ // Timeout will throw a status = 0 request
24
+ // onreadystatechange preempts ontimeout
25
+ // And we can't know for sure at this stage if it's a timeout
26
+ setTimeout(function () {
27
+ if (isTimeout) {
28
+ return;
29
+ }
30
+ return onError(new Error('Request to ' + url + ' failed with status: ' + req.status));
31
+ }, 500);
32
+ }
33
+ else {
34
+ return onError(new Error('Request to ' + url + ' failed with status: ' + req.status));
35
+ }
36
+ }
37
+ };
38
+ req.open(options.method || 'GET', url, true);
39
+ if (options.timeout) {
40
+ req.timeout = options.timeout;
41
+ }
42
+ else {
43
+ req.timeout = DEFAULT_TIMEOUT;
44
+ }
45
+ req.ontimeout = function () {
46
+ isTimeout = true;
47
+ return onError(new Error('Request to ' + url + ' timed out'));
48
+ };
49
+ var headers = options.headers || {};
50
+ for (var name in headers) {
51
+ req.setRequestHeader(name, headers[name]);
52
+ }
53
+ req.send(options.body || null);
54
+ }
55
+ catch (error) {
56
+ return onError(error);
57
+ }
58
+ }
59
+ function addUrlParameter(url, name, value) {
60
+ url = parseUrl(url);
61
+ var newParam = name.concat('=', value);
62
+ var modified = false;
63
+ findByKey(name, url.params, function (index) {
64
+ url.params[index] = newParam;
65
+ modified = true;
66
+ });
67
+ if (!modified) {
68
+ url.params.push(newParam);
69
+ }
70
+ return buildUrl(url);
71
+ }
72
+ function removeUrlParameter(url, name) {
73
+ url = parseUrl(url);
74
+ findByKey(name, url.params, function (index) {
75
+ url.params.splice(index--, 1);
76
+ });
77
+ return buildUrl(url);
78
+ }
79
+ function parseUrl(url) {
80
+ var parts = url.split('?');
81
+ return {
82
+ address: parts[0],
83
+ params: (parts[1] || '').split('&').filter(Boolean),
84
+ };
85
+ }
86
+ function buildUrl(parts) {
87
+ return [parts.address, parts.params.join('&')].join('?').replace(/\??$/, '');
88
+ }
89
+ function findByKey(key, keyvals, callback) {
90
+ key += '=';
91
+ for (var index = 0; keyvals.length > index; index++) {
92
+ if (keyvals[index].trim().slice(0, key.length) === key) {
93
+ var value = keyvals[index].trim().slice(key.length);
94
+ if (callback) {
95
+ callback(index, value);
96
+ }
97
+ else {
98
+ return value;
99
+ }
100
+ }
101
+ }
102
+ }
103
+ function isCrossOrigin(link) {
104
+ return (link.protocol !== window.location.protocol ||
105
+ link.hostname !== window.location.hostname ||
106
+ (link.port || '80') !== (window.location.port || '80'));
107
+ }
108
+ function getOriginFromLink(link) {
109
+ var origin = link.protocol.concat('//', link.hostname);
110
+ if (link.port && link.port !== '80' && link.port !== '443') {
111
+ origin = origin.concat(':', link.port);
112
+ }
113
+ return origin;
114
+ }
115
+ function isBrowser() {
116
+ return typeof module === 'undefined';
117
+ }
118
+ function setCookie({ name, value, lifetime }) {
119
+ // const encodedValue = encodeURIComponent(value)
120
+ const encodedValue = value;
121
+ document.cookie = name
122
+ .concat('=', encodedValue)
123
+ .concat('; path=/', '; max-age='.concat(lifetime.toString()), document.location.protocol === 'https:' ? '; Secure' : '');
124
+ }
125
+ function getCookie(name, defaultValue) {
126
+ name += '=';
127
+ const cookies = document.cookie.split(';');
128
+ let cookie = null;
129
+ for (let i = 0; i < cookies.length; i++) {
130
+ let currentCookie = cookies[i].trim();
131
+ if (currentCookie.indexOf(name) === 0) {
132
+ cookie = currentCookie;
133
+ break;
134
+ }
135
+ }
136
+ if (cookie) {
137
+ return decodeURIComponent(cookie.trim().slice(name.length));
138
+ }
139
+ return defaultValue || null;
140
+ }
141
+ function validateConsentObject(response) {
142
+ try {
143
+ if (typeof response !== 'object' || response === null) {
144
+ return false;
145
+ }
146
+ var expectedKeys = ['essential', 'settings', 'usage', 'campaigns'];
147
+ var allKeysPresent = true;
148
+ var responseKeysCount = 0;
149
+ for (var i = 0; i < expectedKeys.length; i++) {
150
+ if (!(expectedKeys[i] in response)) {
151
+ allKeysPresent = false;
152
+ break;
153
+ }
154
+ }
155
+ var allValuesBoolean = true;
156
+ for (var key in response) {
157
+ if (response.hasOwnProperty(key)) {
158
+ responseKeysCount++;
159
+ if (typeof response[key] !== 'boolean') {
160
+ allValuesBoolean = false;
161
+ break;
162
+ }
163
+ }
164
+ }
165
+ var correctNumberOfKeys = responseKeysCount === expectedKeys.length;
166
+ }
167
+ catch (err) {
168
+ return false;
169
+ }
170
+ return allKeysPresent && allValuesBoolean && correctNumberOfKeys;
171
+ }
172
+
173
+ const COOKIE_DAYS = 365;
174
+ class GovConsentConfig {
175
+ constructor(baseUrl) {
176
+ this.uidFromCookie = findByKey(GovConsentConfig.UID_KEY, document.cookie.split(';'));
177
+ this.uidFromUrl = findByKey(GovConsentConfig.UID_KEY, parseUrl(location.href).params);
178
+ this.baseUrl = baseUrl;
179
+ }
180
+ }
181
+ GovConsentConfig.UID_KEY = 'gov_singleconsent_uid';
182
+ GovConsentConfig.CONSENTS_COOKIE_NAME = 'cookies_policy';
183
+ GovConsentConfig.PREFERENCES_SET_COOKIE_NAME = 'cookies_preferences_set';
184
+ GovConsentConfig.COOKIE_LIFETIME = COOKIE_DAYS * 24 * 60 * 60;
185
+
186
+ class ApiV1 {
187
+ constructor(baseUrl) {
188
+ this.version = 'v1';
189
+ this.baseUrl = baseUrl;
190
+ }
191
+ buildUrl(endpoint, pathParam) {
192
+ let url = `${this.baseUrl}/api/${this.version}${endpoint}`;
193
+ if (pathParam) {
194
+ url += `/${pathParam}`;
195
+ }
196
+ return url;
197
+ }
198
+ origins() {
199
+ return this.buildUrl(ApiV1.Routes.origins);
200
+ }
201
+ consents(id) {
202
+ return this.buildUrl(ApiV1.Routes.consents, id || '');
203
+ }
204
+ }
205
+ ApiV1.Routes = {
206
+ origins: '/origins',
207
+ consents: '/consent',
208
+ };
209
+
210
+ class GovSingleConsent {
211
+ constructor(consentsUpdateCallback, baseUrlOrEnv) {
212
+ /**
213
+ Initialises _GovConsent object by performing the following:
214
+ 1. Removes 'uid' from URL.
215
+ 2. Sets 'uid' attribute from cookie or URL.
216
+ 3. Fetches consent status from API if 'uid' exists.
217
+ 4. Notifies event listeners with API response.
218
+
219
+ @arg baseUrl: string - the domain of where the single consent API is. Required.
220
+ @arg consentsUpdateCallback: function(consents, consentsPreferencesSet, error) - callback when the consents are updated
221
+ "consents": this is the consents object. It has the following properties: "essential", "usage", "campaigns", "settings". Each property is a boolean.
222
+ "consentsPreferencesSet": true if the consents have been set for this user and this domain. Typically, only display the cookie banner if this is true.
223
+ "error": if an error occurred, this is the error object. Otherwise, this is null.
224
+ */
225
+ this.cachedConsentsCookie = null;
226
+ this.validateConstructorArguments(baseUrlOrEnv, consentsUpdateCallback);
227
+ const baseUrl = this.resolveBaseUrl(baseUrlOrEnv);
228
+ this._consentsUpdateCallback = consentsUpdateCallback;
229
+ this.config = new GovConsentConfig(baseUrl);
230
+ this.urls = new ApiV1(this.config.baseUrl);
231
+ window.cachedConsentsCookie = null;
232
+ this.hideUIDParameter();
233
+ this.initialiseUIDandConsents();
234
+ }
235
+ validateConstructorArguments(baseUrlOrEnv, consentsUpdateCallback) {
236
+ if (!baseUrlOrEnv) {
237
+ throw new Error('Argument baseUrl is required');
238
+ }
239
+ if (typeof baseUrlOrEnv !== 'string') {
240
+ throw new Error('Argument baseUrl must be a string');
241
+ }
242
+ if (!consentsUpdateCallback) {
243
+ throw new Error('Argument consentsUpdateCallback is required');
244
+ }
245
+ if (typeof consentsUpdateCallback !== 'function') {
246
+ throw new Error('Argument consentsUpdateCallback must be a function');
247
+ }
248
+ }
249
+ resolveBaseUrl(baseUrlOrEnv) {
250
+ if (baseUrlOrEnv === 'staging') {
251
+ return 'https://gds-single-consent-staging.app';
252
+ }
253
+ else if (baseUrlOrEnv === 'production') {
254
+ return 'https://gds-single-consent.app';
255
+ }
256
+ // If not "staging" or "production", assume it's a custom URL
257
+ return baseUrlOrEnv;
258
+ }
259
+ initialiseUIDandConsents() {
260
+ const currentUID = this.getCurrentUID();
261
+ if (this.isNewUID(currentUID)) {
262
+ this.handleNewUID(currentUID);
263
+ }
264
+ if (this.uid) {
265
+ this.fetchAndUpdateConsents();
266
+ }
267
+ else {
268
+ this._consentsUpdateCallback(null, false, null);
269
+ }
270
+ }
271
+ handleNewUID(newUID) {
272
+ this.uid = newUID;
273
+ this.updateLinksEventHandlers(newUID);
274
+ this.setUIDCookie(newUID);
275
+ }
276
+ isNewUID(currentUID) {
277
+ return currentUID && currentUID !== this.uid;
278
+ }
279
+ fetchAndUpdateConsents() {
280
+ const consentsUrl = this.urls.consents(this.uid);
281
+ request(consentsUrl, { timeout: 1000 }, (jsonResponse) => {
282
+ if (!validateConsentObject(jsonResponse.status)) {
283
+ const error = new Error('Invalid consents object returned from the API: ' + JSON.stringify(jsonResponse));
284
+ return this.defaultToRejectAllConsents(error);
285
+ }
286
+ const consents = jsonResponse.status;
287
+ this.updateBrowserConsents(consents);
288
+ this._consentsUpdateCallback(consents, GovSingleConsent.isConsentPreferencesSet(), null);
289
+ }, (error) => this.defaultToRejectAllConsents(error));
290
+ }
291
+ getCurrentUID() {
292
+ // Get the current uid from URL or from the cookie if it exists
293
+ return this.config.uidFromUrl || this.config.uidFromCookie;
294
+ }
295
+ setConsents(consents) {
296
+ if (!consents) {
297
+ throw new Error('consents is required in GovSingleConsent.setConsents()');
298
+ }
299
+ const successCallback = (response) => {
300
+ if (!response.uid) {
301
+ throw new Error('No UID returned from the API');
302
+ }
303
+ if (this.isNewUID(response.uid)) {
304
+ this.handleNewUID(response.uid);
305
+ }
306
+ this.updateBrowserConsents(consents);
307
+ this._consentsUpdateCallback(consents, GovSingleConsent.isConsentPreferencesSet(), null);
308
+ };
309
+ const url = this.urls.consents(this.uid);
310
+ request(url, {
311
+ method: 'POST',
312
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
313
+ body: 'status='.concat(JSON.stringify(consents)),
314
+ }, successCallback, (error) => this.defaultToRejectAllConsents(error));
315
+ }
316
+ defaultToRejectAllConsents(error) {
317
+ this.updateBrowserConsents(GovSingleConsent.REJECT_ALL);
318
+ this._consentsUpdateCallback(GovSingleConsent.REJECT_ALL, GovSingleConsent.isConsentPreferencesSet(), error);
319
+ }
320
+ static getConsents() {
321
+ if (window.cachedConsentsCookie) {
322
+ return window.cachedConsentsCookie;
323
+ }
324
+ const cookieValue = getCookie(GovConsentConfig.CONSENTS_COOKIE_NAME, null);
325
+ if (cookieValue) {
326
+ return JSON.parse(cookieValue);
327
+ }
328
+ return null;
329
+ }
330
+ static hasConsentedToEssential() {
331
+ const consents = GovSingleConsent.getConsents();
332
+ return consents === null || consents === void 0 ? void 0 : consents.essential;
333
+ }
334
+ static hasConsentedToUsage() {
335
+ const consents = GovSingleConsent.getConsents();
336
+ return consents === null || consents === void 0 ? void 0 : consents.usage;
337
+ }
338
+ static hasConsentedToCampaigns() {
339
+ const consents = GovSingleConsent.getConsents();
340
+ return consents === null || consents === void 0 ? void 0 : consents.campaigns;
341
+ }
342
+ static hasConsentedToSettings() {
343
+ const consents = GovSingleConsent.getConsents();
344
+ return consents === null || consents === void 0 ? void 0 : consents.settings;
345
+ }
346
+ static isConsentPreferencesSet() {
347
+ const value = getCookie(GovConsentConfig.PREFERENCES_SET_COOKIE_NAME, null);
348
+ return value === 'true';
349
+ }
350
+ updateLinksEventHandlers(currentUID) {
351
+ request(this.urls.origins(), {},
352
+ // Update links with UID
353
+ (origins) => this.addUIDtoCrossOriginLinks(origins, currentUID), (error) => {
354
+ throw error;
355
+ });
356
+ }
357
+ addUIDtoCrossOriginLinks(origins, uid) {
358
+ /**
359
+ * Adds uid URL parameter to consent sharing links.
360
+ * Only links with known origins are updated.
361
+ */
362
+ const links = document.querySelectorAll('a[href]');
363
+ Array.prototype.forEach.call(links, (link) => {
364
+ if (isCrossOrigin(link) &&
365
+ origins.indexOf(getOriginFromLink(link)) >= 0) {
366
+ link.addEventListener('click', (event) => {
367
+ event.target.href = addUrlParameter(event.target.href, GovConsentConfig.UID_KEY, uid);
368
+ });
369
+ }
370
+ });
371
+ }
372
+ setUIDCookie(uid) {
373
+ setCookie({
374
+ name: GovConsentConfig.UID_KEY,
375
+ value: uid,
376
+ lifetime: GovConsentConfig.COOKIE_LIFETIME,
377
+ });
378
+ }
379
+ updateBrowserConsents(consents) {
380
+ this.setConsentsCookie(consents);
381
+ this.setPreferencesSetCookie(true);
382
+ window.cachedConsentsCookie = consents;
383
+ }
384
+ setConsentsCookie(consents) {
385
+ setCookie({
386
+ name: GovConsentConfig.CONSENTS_COOKIE_NAME,
387
+ value: JSON.stringify(consents),
388
+ lifetime: GovConsentConfig.COOKIE_LIFETIME,
389
+ });
390
+ }
391
+ setPreferencesSetCookie(value) {
392
+ setCookie({
393
+ name: GovConsentConfig.PREFERENCES_SET_COOKIE_NAME,
394
+ value: value.toString(),
395
+ lifetime: GovConsentConfig.COOKIE_LIFETIME,
396
+ });
397
+ }
398
+ hideUIDParameter() {
399
+ history.replaceState(null, null, removeUrlParameter(location.href, GovConsentConfig.UID_KEY));
400
+ }
401
+ }
402
+ GovSingleConsent.ACCEPT_ALL = {
403
+ essential: true,
404
+ usage: true,
405
+ campaigns: true,
406
+ settings: true,
407
+ };
408
+ GovSingleConsent.REJECT_ALL = {
409
+ essential: true,
410
+ usage: false,
411
+ campaigns: false,
412
+ settings: false,
413
+ };
414
+
415
+ if (isBrowser()) {
416
+ window.GovSingleConsent = GovSingleConsent;
417
+ }
418
+
419
+ exports.GovSingleConsent = GovSingleConsent;