govuk_publishing_components 37.6.0 → 37.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b5059f8b24e5d099520ca6f53061525153ddf6e7e31a5d4d1401516cb3856fc4
4
- data.tar.gz: 6565eeaa1b13939dbb5295327aa5d9862bd568b8af022d803419d22bc6890f5b
3
+ metadata.gz: 057a27088f3e56f3de0b207bf272737059e084e11f7ad5d60c9c64f51b36f36c
4
+ data.tar.gz: 2e7c53dbecff6dcb761c8b181be7c22a051d1e67738f96d6386cc24b08e4a850
5
5
  SHA512:
6
- metadata.gz: 828d20c4426cad1bce861a0f4eef8f9aa46947fa0f381ca54f8408ef9675d828b3d9c7be18d513bf5c9f4b9c34197cb30cefa030f33134cac24ae1cdead608ab
7
- data.tar.gz: 53515ff838f233ab6b5bf5d3db5fe4d78e4c360faf4368cdfff7d9ef1ebbcebb8959637728348c74acd2e7003b94c4fa127c9dfe83c0a0b608263bcfdb17ce1f
6
+ metadata.gz: 853e1a7952502815cc9cf864feedb258266b06f402c37d8622ce3e2a8550b160bfc676e60221b5e6a0332adca201bc7a8b651d3cee2ff451f9ade26c61a74304
7
+ data.tar.gz: 54df263cbc3fe4b0a4bf2b7f8e3207e5d0292fb6dd79fddfe87cdcea0b844d0c5b4a73527de5ef7d747991e505af18b25228c8644d6c973a5431fb993707a3f7
@@ -50,7 +50,7 @@
50
50
  padding-left: $contents-spacing;
51
51
  padding-right: $contents-spacing;
52
52
 
53
- &::before {
53
+ & span::before {
54
54
  content: "—";
55
55
  position: absolute;
56
56
  left: 0;
@@ -41,6 +41,7 @@
41
41
  <% index_link = 1 unless disable_ga4 %>
42
42
  <% contents.each.with_index(1) do |contents_item, position| %>
43
43
  <li class="<%= cl_helper.list_item_classes(contents_item, false) %>" <%= "aria-current=true" if contents_item[:active] %>>
44
+ <span aria-hidden="true"></span>
44
45
  <% link_text = format_numbers ? cl_helper.wrap_numbers_with_spans(contents_item[:text]) : contents_item[:text]
45
46
  unless disable_ga4
46
47
  ga4_data[:event_name] = cl_helper.get_ga4_event_name(contents_item[:href]) if contents_item[:href]
@@ -64,6 +65,7 @@
64
65
  <ol class="gem-c-contents-list__nested-list">
65
66
  <% contents_item[:items].each.with_index(1) do |nested_contents_item, nested_position| %>
66
67
  <li class="<%= cl_helper.list_item_classes(nested_contents_item, true) %>" <%= "aria-current=true" if nested_contents_item[:active] %>>
68
+ <span aria-hidden="true"></span>
67
69
  <%
68
70
  unless disable_ga4
69
71
  ga4_data[:event_name] = cl_helper.get_ga4_event_name(nested_contents_item[:href]) if nested_contents_item[:href]
@@ -18,6 +18,7 @@ accessibility_criteria: |
18
18
  - convey the content structure
19
19
  - indicate the current page when contents span different pages, and not link to itself
20
20
  - include an aria-label to contextualise the list
21
+ - ensure dashes before each list item are hidden from screen readers
21
22
 
22
23
  Links with formatted numbers must separate the number and text with a space for correct screen reader pronunciation. This changes pronunciation from "1 dot Item" to "1 Item".
23
24
  shared_accessibility_criteria:
@@ -1,3 +1,3 @@
1
1
  module GovukPublishingComponents
2
- VERSION = "37.6.0".freeze
2
+ VERSION = "37.6.1".freeze
3
3
  end
@@ -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;