govuk_publishing_components 35.22.0 → 36.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/govuk_publishing_components_manifest.js +1 -0
  3. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-auto-tracker.js +1 -5
  4. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-core.js +29 -41
  5. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-event-tracker.js +6 -10
  6. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-form-tracker.js +1 -4
  7. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-link-tracker.js +1 -5
  8. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-page-views.js +6 -17
  9. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-print-intent-tracker.js +1 -3
  10. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-schemas.js +4 -20
  11. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-scroll-tracker.js +1 -3
  12. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-specialist-link-tracker.js +1 -5
  13. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-video-tracker.js +1 -4
  14. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/pii-remover.js +22 -4
  15. data/app/assets/javascripts/govuk_publishing_components/components/cross-service-header.js +78 -0
  16. data/app/assets/stylesheets/govuk_publishing_components/_all_components.scss +1 -0
  17. data/app/assets/stylesheets/govuk_publishing_components/components/_action-link.scss +3 -79
  18. data/app/assets/stylesheets/govuk_publishing_components/components/_cross-service-header.scss +430 -0
  19. data/app/views/govuk_publishing_components/components/_action_link.html.erb +2 -19
  20. data/app/views/govuk_publishing_components/components/_cross_service_header.html.erb +19 -0
  21. data/app/views/govuk_publishing_components/components/_layout_for_public.html.erb +9 -0
  22. data/app/views/govuk_publishing_components/components/cross_service_header/_one_login_header.html.erb +97 -0
  23. data/app/views/govuk_publishing_components/components/cross_service_header/_service_header.html.erb +49 -0
  24. data/app/views/govuk_publishing_components/components/docs/action_link.yml +1 -52
  25. data/app/views/govuk_publishing_components/components/docs/cross_service_header.yml +64 -0
  26. data/lib/govuk_publishing_components/app_helpers/asset_helper.rb +1 -0
  27. data/lib/govuk_publishing_components/presenters/component_wrapper_helper.rb +1 -1
  28. data/lib/govuk_publishing_components/presenters/meta_tags.rb +21 -0
  29. data/lib/govuk_publishing_components/version.rb +1 -1
  30. metadata +8 -10
  31. data/app/assets/images/govuk_publishing_components/action-link--nhs.png +0 -0
  32. data/app/assets/images/govuk_publishing_components/action-link--nhs.svg +0 -1
  33. data/app/assets/images/govuk_publishing_components/action-link-arrow--blue.png +0 -0
  34. data/app/assets/images/govuk_publishing_components/action-link-arrow--blue.svg +0 -9
  35. data/app/assets/images/govuk_publishing_components/action-link-arrow--brexit.svg +0 -3
  36. data/app/assets/images/govuk_publishing_components/action-link-arrow--transparent.svg +0 -1
  37. data/app/assets/images/govuk_publishing_components/action-link-arrow--white.png +0 -0
  38. data/app/assets/images/govuk_publishing_components/action-link-arrow--white.svg +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b44a8215911c2a260e0b80134c14d3f974a4ee0bb91cdf7eb23dc081e61ee9d9
4
- data.tar.gz: 4262f87d3ce863db103a0f24e3936b69e2219b0794ad83d142abb115bf7fe66a
3
+ metadata.gz: 773208000d7b04127bf634415ed17bbfd977ba73ab9a45e2eca5742f19eacbc6
4
+ data.tar.gz: c2b77952558ca4fd34c22e87088721dffe9d55346cc1cd9a5ac8ee3f64ff2087
5
5
  SHA512:
6
- metadata.gz: 4deebaa45c7bb16f6acbbc0ae2b916222a6e8b3c9efb05581f3fefbf8e4b87b3ee772025b81399055e3bbedceb6162d1cd9df56b7e22f6ad1f6637523dea307c
7
- data.tar.gz: 1fef3fd8a3ab99df0359cfd7d2787ba7d0d62ee50e12e455acb64fad1c51fbb47bc657b4f3ef784767c9c2fb95967678be14d168efb9db789ce28b618118e2bc
6
+ metadata.gz: 5d2efbb677bc763e54375000098c7419ccec70d70d4ad49093e6fda016788ec22ef989d8c7a480e5e9fa00d4dba4c6ac10672bb683baa67d129a3a49da80e460
7
+ data.tar.gz: 5e34040e64f3863838db6c24a5d8e2c0f0d423d62f24f6841adb204e0071899699796c07740130b6ec06205a87cffdcfed80814a177f7eb6aa93cd7112e55e1a
@@ -30,6 +30,7 @@
30
30
  //= link govuk_publishing_components/components/_contextual-sidebar.css
31
31
  //= link govuk_publishing_components/components/_cookie-banner.css
32
32
  //= link govuk_publishing_components/components/_copy-to-clipboard.css
33
+ //= link govuk_publishing_components/components/_cross-service-header.css
33
34
  //= link govuk_publishing_components/components/_date-input.css
34
35
  //= link govuk_publishing_components/components/_details.css
35
36
  //= link govuk_publishing_components/components/_devolved-nations.css
@@ -35,12 +35,8 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
35
35
  console.error('GA4 configuration error: ' + e.message, window.location)
36
36
  return
37
37
  }
38
-
39
38
  data.text = this.PIIRemover.stripPIIWithOverride(data.text, true, true)
40
- var schemas = new window.GOVUK.analyticsGa4.Schemas()
41
- var schema = schemas.mergeProperties(data, 'event_data')
42
-
43
- window.GOVUK.analyticsGa4.core.sendData(schema)
39
+ window.GOVUK.analyticsGa4.core.applySchemaAndSendData(data, 'event_data')
44
40
  }
45
41
  }
46
42
 
@@ -35,20 +35,35 @@ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
35
35
  },
36
36
 
37
37
  sendData: function (data) {
38
- // Prevent any GA4 data being sent during Smokey tests
39
- if (this.getUserAgent() === 'Smokey Test / Ruby') {
40
- return
41
- }
42
-
43
38
  data.govuk_gem_version = this.getGemVersion()
44
39
  // set this in the console as a debugging aid
45
40
  if (window.GOVUK.analyticsGa4.showDebug) {
46
- data.event_data = this.sortEventData(data.event_data)
41
+ if (data.event_data) {
42
+ data.event_data = this.sortEventData(data.event_data)
43
+ } else if (data.page_view) {
44
+ data.page_view = this.sortEventData(data.page_view)
45
+ } else if (data.search_results) {
46
+ data.search_results = this.sortEventData(data.search_results)
47
+ }
47
48
  console.info(JSON.stringify(data, null, ' '))
48
49
  }
50
+
51
+ // Send GA4 data to a fake dataLayer if smokey_cachebust or disable_ga4 is in the query string. Used to prevent Smokey/other tests from spamming our analytics.
52
+ if (this.trackFunctions.getSearch().match(/[?&](disable_ga4|smokey_cachebust){1}/)) {
53
+ window.fakeDataLayer = window.fakeDataLayer || []
54
+ window.fakeDataLayer.push(data)
55
+ return
56
+ }
57
+
49
58
  window.dataLayer.push(data)
50
59
  },
51
60
 
61
+ applySchemaAndSendData: function (data, name) {
62
+ var schemas = new window.GOVUK.analyticsGa4.Schemas()
63
+ var schema = schemas.mergeProperties(data, name)
64
+ this.sendData(schema)
65
+ },
66
+
52
67
  getGemVersion: function () {
53
68
  return window.GOVUK.analyticsGa4.vars.gem_version || 'not found'
54
69
  },
@@ -74,6 +89,10 @@ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
74
89
  return /^(http:||https:)?(\/\/)([^\/]*)/ // eslint-disable-line no-useless-escape
75
90
  },
76
91
 
92
+ getSearch: function () {
93
+ return window.location.search
94
+ },
95
+
77
96
  findTrackingAttributes: function (clicked, trackingTrigger) {
78
97
  if (clicked.hasAttribute('[' + trackingTrigger + ']')) {
79
98
  return clicked
@@ -82,39 +101,6 @@ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
82
101
  }
83
102
  },
84
103
 
85
- // create an object to split up long URLs and get around the 100 character limit on GTM data
86
- // this gets reassembled in GA4
87
- populateLinkPathParts: function (href) {
88
- var path = ''
89
- if (this.hrefIsRelative(href) || this.isMailToLink(href)) {
90
- path = href
91
- } else {
92
- // This regex matches a protocol and domain name at the start of a string such as https://www.gov.uk, http://gov.uk, //gov.uk
93
- path = href.replace(/^(http:||https:)?(\/\/)([^\/]*)/, '') // eslint-disable-line no-useless-escape
94
- }
95
-
96
- if (path === '/' || path.length === 0) {
97
- return
98
- }
99
-
100
- return this.splitStringIntoParts(path)
101
- },
102
-
103
- splitStringIntoParts: function (string) {
104
- /*
105
- This will create an object with 5 keys that are indexes ("1", "2", etc.)
106
- The values will be each part of the string split every 100 characters, or undefined.
107
- For example: {"1": "/hello/world/etc...", "2": "/more/path/text...", "3": undefined, "4": undefined, "5": undefined}
108
- Undefined values are needed to override the persistent object in GTM so that any values from old pushes are overwritten.
109
- */
110
- var parts = string.match(/.{1,100}/g)
111
- var obj = {}
112
- for (var i = 0; i < 5; i++) {
113
- obj[(i + 1).toString()] = parts[i]
114
- }
115
- return obj
116
- },
117
-
118
104
  hrefIsRelative: function (href) {
119
105
  // Checks that a href is relative by the lack of http:, https:// or // at the start of the href.
120
106
  var domain = this.getDomainRegex().exec(href)
@@ -135,6 +121,8 @@ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
135
121
  return 'command/win click'
136
122
  } else if (event.shiftKey) {
137
123
  return 'shift click'
124
+ } else if (event.altKey) {
125
+ return 'alt/option click'
138
126
  } else {
139
127
  return 'primary click'
140
128
  }
@@ -259,8 +247,8 @@ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
259
247
  var totalLinks = 0
260
248
  for (var i = 0; i < links.length; i++) {
261
249
  var link = links[i]
262
- // Only index links that are not search results or do not have a data-ga4-do-not-index attribute
263
- if (link.getAttribute('data-ga4-ecommerce-path') || link.getAttribute('data-ga4-do-not-index') !== null) {
250
+ // Ignore links that don't have a href, have a data-ga4-do-not-index attribute on them, or are search result links.
251
+ if (!link.getAttribute('href') || link.getAttribute('data-ga4-ecommerce-path') || link.getAttribute('data-ga4-do-not-index') !== null) {
264
252
  continue
265
253
  }
266
254
  totalLinks++
@@ -43,9 +43,6 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
43
43
  var text = data.text || event.target.textContent
44
44
  data.text = window.GOVUK.analyticsGa4.core.trackFunctions.removeLinesAndExtraSpaces(text)
45
45
 
46
- var schemas = new window.GOVUK.analyticsGa4.Schemas()
47
- var schema = schemas.mergeProperties(data, 'event_data')
48
-
49
46
  /* Ensure it only tracks aria-expanded in an element with data-ga4-expandable on it. */
50
47
  if (target.closest('[data-ga4-expandable]')) {
51
48
  var ariaExpanded = this.getClosestAttribute(target, 'aria-expanded')
@@ -59,12 +56,12 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
59
56
  var detailsElement = target.closest('details')
60
57
 
61
58
  if (ariaExpanded) {
62
- schema.event_data.text = data.text || target.innerText
63
- schema.event_data.action = (ariaExpanded === 'false') ? 'opened' : 'closed'
59
+ data.text = data.text || target.innerText
60
+ data.action = (ariaExpanded === 'false') ? 'opened' : 'closed'
64
61
  } else if (detailsElement) {
65
- schema.event_data.text = data.text || detailsElement.textContent
62
+ data.text = data.text || detailsElement.textContent
66
63
  var openAttribute = detailsElement.getAttribute('open')
67
- schema.event_data.action = (openAttribute == null) ? 'opened' : 'closed'
64
+ data.action = (openAttribute == null) ? 'opened' : 'closed'
68
65
  }
69
66
 
70
67
  /* If a tab was clicked, grab the href of the clicked tab (usually an anchor # link) */
@@ -74,12 +71,11 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
74
71
  if (aTag) {
75
72
  var href = aTag.getAttribute('href')
76
73
  if (href) {
77
- schema.event_data.url = window.GOVUK.analyticsGa4.core.trackFunctions.appendPathToAnchorLinks(href)
74
+ data.url = window.GOVUK.analyticsGa4.core.trackFunctions.appendPathToAnchorLinks(href)
78
75
  }
79
76
  }
80
77
  }
81
-
82
- window.GOVUK.analyticsGa4.core.sendData(schema)
78
+ window.GOVUK.analyticsGa4.core.applySchemaAndSendData(data, 'event_data')
83
79
  }
84
80
  }
85
81
 
@@ -50,10 +50,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
50
50
  data.text = data.text.toLowerCase()
51
51
  data.text = window.GOVUK.analyticsGa4.core.trackFunctions.removeLinesAndExtraSpaces(data.text)
52
52
  }
53
-
54
- var schemas = new window.GOVUK.analyticsGa4.Schemas()
55
- var schema = schemas.mergeProperties(data, 'event_data')
56
- window.GOVUK.analyticsGa4.core.sendData(schema)
53
+ window.GOVUK.analyticsGa4.core.applySchemaAndSendData(data, 'event_data')
57
54
  }
58
55
  }
59
56
 
@@ -90,7 +90,6 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
90
90
  data.url = trackFunctions.applyRedactionIfRequired(this.PIIRemover, element, data.url)
91
91
  data.url = trackFunctions.appendPathToAnchorLinks(data.url)
92
92
  data.link_domain = trackFunctions.populateLinkDomain(data.url)
93
- data.link_path_parts = trackFunctions.populateLinkPathParts(data.url)
94
93
  data.method = trackFunctions.getClickType(event)
95
94
  data.external = trackFunctions.isExternalLink(data.url) ? 'true' : 'false'
96
95
  data.index = this.setIndex(data.index, event.target)
@@ -106,10 +105,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
106
105
  if (data.type === 'smart answer' && data.action === 'change response') {
107
106
  data.section = this.PIIRemover.stripPIIWithOverride(data.section, true, true)
108
107
  }
109
-
110
- var schemas = new window.GOVUK.analyticsGa4.Schemas()
111
- var schema = schemas.mergeProperties(data, 'event_data')
112
- window.GOVUK.analyticsGa4.core.sendData(schema)
108
+ window.GOVUK.analyticsGa4.core.applySchemaAndSendData(data, 'event_data')
113
109
  }
114
110
  }
115
111
 
@@ -36,8 +36,8 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
36
36
  taxonomy_level1: this.getMetaContent('themes'),
37
37
  taxonomy_main: this.getMetaContent('taxon-slug'),
38
38
  taxonomy_main_id: this.getMetaContent('taxon-id'),
39
- taxonomy_all: this.splitLongMetaContent('taxon-slugs'),
40
- taxonomy_all_ids: this.splitLongMetaContent('taxon-ids'),
39
+ taxonomy_all: this.getMetaContent('taxon-slugs'),
40
+ taxonomy_all_ids: this.getMetaContent('taxon-ids'),
41
41
 
42
42
  language: this.getLanguage(),
43
43
  history: this.getHistory(),
@@ -45,8 +45,8 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
45
45
  first_published_at: this.stripTimeFrom(this.getMetaContent('first-published-at')),
46
46
  updated_at: this.stripTimeFrom(this.getMetaContent('updated-at')),
47
47
  public_updated_at: this.stripTimeFrom(this.getMetaContent('public-updated-at')),
48
- publishing_government: this.getMetaContent('publishing-government'),
49
- political_status: this.getMetaContent('political-status'),
48
+ publishing_government: this.getMetaContent('publishing-government') || this.getMetaContent('ga4-publishing-government'),
49
+ political_status: this.getMetaContent('political-status') || this.getMetaContent('ga4-political-status'),
50
50
  primary_publishing_organisation: this.getMetaContent('primary-publishing-organisation'),
51
51
  organisations: this.getMetaContent('analytics:organisations'),
52
52
  world_locations: this.getMetaContent('analytics:world-locations'),
@@ -73,12 +73,8 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
73
73
  return this.PIIRemover.stripPIIWithOverride(this.stripGaParam(document.location.href), true, true)
74
74
  },
75
75
 
76
- getSearch: function () {
77
- return window.location.search
78
- },
79
-
80
76
  getSearchTerm: function () {
81
- var queryString = this.getSearch()
77
+ var queryString = window.GOVUK.analyticsGa4.core.trackFunctions.getSearch()
82
78
 
83
79
  if (!queryString) {
84
80
  return undefined
@@ -97,7 +93,7 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
97
93
  },
98
94
 
99
95
  getQueryString: function () {
100
- var queryString = this.getSearch()
96
+ var queryString = window.GOVUK.analyticsGa4.core.trackFunctions.getSearch()
101
97
  if (queryString) {
102
98
  queryString = this.stripGaParam(queryString)
103
99
  queryString = this.PIIRemover.stripPIIWithOverride(queryString, true, true)
@@ -200,13 +196,6 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
200
196
  return undefined
201
197
  },
202
198
 
203
- splitLongMetaContent: function (metatag) {
204
- var tag = this.getMetaContent(metatag)
205
- if (tag) {
206
- return window.GOVUK.analyticsGa4.core.trackFunctions.splitStringIntoParts(tag)
207
- }
208
- },
209
-
210
199
  // return only the date from given timestamps of the form
211
200
  // 2022-03-28T19:11:00.000+00:00
212
201
  stripTimeFrom: function (value) {
@@ -13,9 +13,7 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
13
13
  type: 'print page',
14
14
  method: 'browser print'
15
15
  }
16
- var schema = new window.GOVUK.analyticsGa4.Schemas()
17
- schema = schema.mergeProperties(data, 'event_data')
18
- window.GOVUK.analyticsGa4.core.sendData(schema)
16
+ window.GOVUK.analyticsGa4.core.applySchemaAndSendData(data, 'event_data')
19
17
  })
20
18
  }
21
19
  }
@@ -27,7 +27,6 @@
27
27
  external: this.undefined,
28
28
  method: this.undefined,
29
29
  link_domain: this.undefined,
30
- link_path_parts: this.undefined,
31
30
  tool_name: this.undefined,
32
31
  percent_scrolled: this.undefined,
33
32
  video_current_time: this.undefined,
@@ -53,48 +52,33 @@
53
52
  }
54
53
  }
55
54
 
56
- // merge data attributes data into the event schema
57
- // only allow it if it already exists in the schema
55
+ // merge allowed data attributes into the event schema
58
56
  Schemas.prototype.mergeProperties = function (data, eventAttribute) {
59
57
  var schema = this.eventSchema()
60
58
  schema.event = eventAttribute
61
- // exceptions should be inserted without checking for sub parameters
62
- // exceptions should only come from code, not directly from data attributes
63
- // e.g. link_path_parts is generated by JS and contains potentially non-unique
64
- // sub parameter names i.e. '1', '2'
65
- var exceptions = ['link_path_parts']
66
59
 
67
60
  for (var property in data) {
68
61
  // some passed data might be undefined, don't want it to overwrite e.g. the index sub parameters
69
62
  if (data[property] !== undefined) {
70
- if (exceptions.indexOf(property) >= 0 || !this.isAnObject(data[property])) {
71
- schema.event_data = this.addToObject(schema.event_data, property, data[property])
72
- } else {
73
- // we check for one level of nesting in the data attributes data
74
- // this check can be removed once nesting is removed from all data attributes
75
- for (var subproperty in data[property]) {
76
- schema.event_data = this.addToObject(schema.event_data, subproperty, data[property][subproperty])
77
- }
78
- }
63
+ schema.event_data = this.addToObject(schema.event_data, property, data[property])
79
64
  }
80
65
  }
81
66
  return schema
82
67
  }
83
68
 
84
- // might be easier to check if it's not a string or a number?
85
69
  Schemas.prototype.isAnObject = function (item) {
86
70
  if (typeof item === 'object' && !Array.isArray(item) && item !== null) {
87
71
  return true
88
72
  }
89
73
  }
90
74
 
91
- // given an object and a key, insert a value into that object for that key
92
- // we check for one level of nesting in the object
75
+ // given an object and a key, insert a value into object[key] if it exists
93
76
  Schemas.prototype.addToObject = function (obj, key, value) {
94
77
  if (key in obj) {
95
78
  obj[key] = value
96
79
  return obj
97
80
  } else {
81
+ // check for one level of nesting in the object
98
82
  for (var property in obj) {
99
83
  if (this.isAnObject(obj[property])) {
100
84
  if (key in obj[property]) {
@@ -123,9 +123,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
123
123
  // following will be undefined if tracking headings
124
124
  data.percent_scrolled = node.eventData.percent_scrolled
125
125
 
126
- var schemas = new window.GOVUK.analyticsGa4.Schemas()
127
- var schema = schemas.mergeProperties(data, 'event_data')
128
- window.GOVUK.analyticsGa4.core.sendData(schema)
126
+ window.GOVUK.analyticsGa4.core.applySchemaAndSendData(data, 'event_data')
129
127
  }
130
128
  }
131
129
  }
@@ -72,7 +72,6 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
72
72
  if (data.url) {
73
73
  data.url = window.GOVUK.analyticsGa4.core.trackFunctions.removeCrossDomainParams(data.url)
74
74
  data.link_domain = window.GOVUK.analyticsGa4.core.trackFunctions.populateLinkDomain(data.url)
75
- data.link_path_parts = window.GOVUK.analyticsGa4.core.trackFunctions.populateLinkPathParts(data.url)
76
75
  }
77
76
 
78
77
  data.text = window.GOVUK.analyticsGa4.core.trackFunctions.removeLinesAndExtraSpaces(element.textContent)
@@ -81,10 +80,7 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
81
80
  data.text = 'image'
82
81
  }
83
82
  data.method = window.GOVUK.analyticsGa4.core.trackFunctions.getClickType(event)
84
-
85
- var schemas = new window.GOVUK.analyticsGa4.Schemas()
86
- var schema = schemas.mergeProperties(data, 'event_data')
87
- window.GOVUK.analyticsGa4.core.sendData(schema)
83
+ window.GOVUK.analyticsGa4.core.applySchemaAndSendData(data, 'event_data')
88
84
  }
89
85
  },
90
86
 
@@ -81,10 +81,7 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
81
81
  data.video_duration = this.handlers['video-' + player.id + '-duration']
82
82
  data.video_percent = position
83
83
 
84
- var schemas = new window.GOVUK.analyticsGa4.Schemas()
85
- var schema = schemas.mergeProperties(data, 'event_data')
86
-
87
- window.GOVUK.analyticsGa4.core.sendData(schema)
84
+ window.GOVUK.analyticsGa4.core.applySchemaAndSendData(data, 'event_data')
88
85
  },
89
86
 
90
87
  cleanVideoUrl: function (url) {
@@ -4,8 +4,22 @@
4
4
  var GOVUK = global.GOVUK || {}
5
5
  var EMAIL_PATTERN = /[^\s=/?&#+]+(?:@|%40)[^\s=/?&+]+/g
6
6
  var POSTCODE_PATTERN = /\b[A-PR-UWYZ][A-HJ-Z]?[0-9][0-9A-HJKMNPR-Y]?(?:[\s+]|%20)*[0-9](?!refund)[ABD-HJLNPQ-Z]{2,3}\b/gi
7
- var DATE_PATTERN_NUMERIC = /\d{4}(-?)\d{2}(-?)\d{2}/g
8
- var DATE_PATTERN_STRING = /\d{1,2}\s(January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4}/g
7
+
8
+ // e.g. 01/01/1990 or 01-01-1990 or 1-1-1990 or 1/1/1990 or 01\01\1990 or 1\1\1990
9
+ var DATE_PATTERN_NUMERIC_1 = /\d{1,2}([-\/\\])\d{1,2}([-\/\\])\d{4}/g // eslint-disable-line no-useless-escape
10
+
11
+ // e.g. 1990/01/01 or 1990-01-01 or 1990-1-1 or 1990/1/1 or 1990\1\1 or 1990\01\01
12
+ var DATE_PATTERN_NUMERIC_2 = /\d{4}([-\/\\])\d{1,2}([-\/\\])\d{1,2}/g // eslint-disable-line no-useless-escape
13
+
14
+ // e.g. 12345678 (This originated from the UA PII Remover)
15
+ var DATE_PATTERN_NUMERIC_3 = /[0-9]{8}/g
16
+
17
+ // e.g. 1(st) (of) Jan(uary) 1990 (or 90 or '90) - where the bracketed characters are optional parts that can be matched
18
+ var DATE_PATTERN_STRING_1 = /\d{1,2}(?:st|nd|rd|th)?\s(?:of\s)?(Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:t)?(?:ember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\s(?:')?(\d{4}|\d{2})/gi
19
+
20
+ // e.g. Jan(uary) 1(st) 1990 (or 90 or '90) - where the bracketed characters are optional parts that can be matched
21
+ var DATE_PATTERN_STRING_2 = /(Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:t)?(?:ember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\s\d{1,2}?(?:st|nd|rd|th)?\s(?:')?(\d{4}|\d{2})/gi
22
+
9
23
  var ESCAPE_REGEX_PATTERN = /[|\\{}()[\]^$+*?.]/g
10
24
 
11
25
  // specific URL parameters to be redacted from accounts URLs
@@ -86,8 +100,12 @@
86
100
  stripped = this.stripQueryStringParameters(stripped)
87
101
 
88
102
  if (this.stripDatePII === true) {
89
- stripped = stripped.replace(DATE_PATTERN_NUMERIC, '[date]')
90
- stripped = stripped.replace(DATE_PATTERN_STRING, '[date]')
103
+ var DATE_REDACTION_STRING = '[date]'
104
+ stripped = stripped.replace(DATE_PATTERN_NUMERIC_1, DATE_REDACTION_STRING)
105
+ stripped = stripped.replace(DATE_PATTERN_NUMERIC_2, DATE_REDACTION_STRING)
106
+ stripped = stripped.replace(DATE_PATTERN_NUMERIC_3, DATE_REDACTION_STRING)
107
+ stripped = stripped.replace(DATE_PATTERN_STRING_1, DATE_REDACTION_STRING)
108
+ stripped = stripped.replace(DATE_PATTERN_STRING_2, DATE_REDACTION_STRING)
91
109
  }
92
110
  if (this.stripPostcodePII === true) {
93
111
  stripped = stripped.replace(POSTCODE_PATTERN, '[postcode]')
@@ -0,0 +1,78 @@
1
+ window.GOVUK = window.GOVUK || {}
2
+ window.GOVUK.Modules = window.GOVUK.Modules || {};
3
+
4
+ (function (Modules) {
5
+ /**
6
+ * A modified adaptation of the Design System header script
7
+ * To initialise the One Login header, run:
8
+ * new window.CrossServiceHeader(document.querySelector("[data-module='one-login-header']")).init();
9
+ */
10
+ function CrossServiceHeader ($module) {
11
+ this.$header = $module
12
+ this.$navigation = $module && $module.querySelectorAll('[data-one-login-header-nav]')
13
+ this.$numberOfNavs = this.$navigation && this.$navigation.length
14
+ if (this.$header) {
15
+ this.$header.classList.add('js-enabled')
16
+ }
17
+ }
18
+ /**
19
+ * Initialise header
20
+ *
21
+ * Check for the presence of the header, menu and menu button – if any are
22
+ * missing then there's nothing to do so return early.
23
+ */
24
+ CrossServiceHeader.prototype.init = function () {
25
+ if (!this.$header && !this.$numberOfNavs) {
26
+ return
27
+ }
28
+ /**
29
+ * The header can render with one or two navigation elements which collapse
30
+ * into dropdowns on the mobile variation. This initialises the dropdown
31
+ * functionality for all navs that have a menu button which has:
32
+ * 1. a class of .js-x-header-toggle
33
+ * 2. an aria-controls attribute which can be mapped to the ID of the element
34
+ * that should be hidden on mobile
35
+ */
36
+ for (var i = 0; i < this.$numberOfNavs; i++) {
37
+ var $nav = this.$navigation[i]
38
+ $nav.$menuButton = $nav.querySelector('.js-x-header-toggle')
39
+
40
+ $nav.$menu = $nav.$menuButton && $nav.querySelector(
41
+ '#' + $nav.$menuButton.getAttribute('aria-controls')
42
+ )
43
+ if (!$nav.$menuButton || !$nav.$menu) {
44
+ return
45
+ }
46
+ $nav.$menuOpenClass = $nav.$menu && $nav.$menu.dataset.openClass
47
+ $nav.$menuButtonOpenClass = $nav.$menuButton && $nav.$menuButton.dataset.openClass
48
+ $nav.$menuButtonOpenLabel = $nav.$menuButton && $nav.$menuButton.dataset.labelForShow
49
+ $nav.$menuButtonCloseLabel = $nav.$menuButton && $nav.$menuButton.dataset.labelForHide
50
+ $nav.$menuButtonOpenText = $nav.$menuButton && $nav.$menuButton.dataset.textForShow
51
+ $nav.$menuButtonCloseText = $nav.$menuButton && $nav.$menuButton.dataset.textForHide
52
+ $nav.isOpen = false
53
+
54
+ $nav.$menuButton.addEventListener('click', this.handleMenuButtonClick.bind($nav))
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Handle menu button click
60
+ *
61
+ * When the menu button is clicked, change the visibility of the menu and then
62
+ * sync the accessibility state and menu button state
63
+ */
64
+ CrossServiceHeader.prototype.handleMenuButtonClick = function () {
65
+ this.isOpen = !this.isOpen
66
+ this.$menuOpenClass && this.$menu.classList.toggle(this.$menuOpenClass, this.isOpen)
67
+ this.$menuButtonOpenClass && this.$menuButton.classList.toggle(this.$menuButtonOpenClass, this.isOpen)
68
+ this.$menuButton.setAttribute('aria-expanded', this.isOpen)
69
+ if (this.$menuButtonCloseLabel && this.$menuButtonOpenLabel) {
70
+ this.$menuButton.setAttribute('aria-label', (this.isOpen ? this.$menuButtonCloseLabel : this.$menuButtonOpenLabel))
71
+ }
72
+ if (this.$menuButtonCloseText && this.$menuButtonOpenText) {
73
+ this.$menuButton.innerHTML = this.isOpen ? this.$menuButtonCloseText : this.$menuButtonOpenText
74
+ }
75
+ }
76
+
77
+ Modules.CrossServiceHeader = CrossServiceHeader
78
+ })(window.GOVUK.Modules)
@@ -27,6 +27,7 @@ $govuk-new-link-styles: true;
27
27
  @import "components/contextual-sidebar";
28
28
  @import "components/cookie-banner";
29
29
  @import "components/copy-to-clipboard";
30
+ @import "components/cross-service-header";
30
31
  @import "components/date-input";
31
32
  @import "components/details";
32
33
  @import "components/devolved-nations";
@@ -94,31 +94,6 @@
94
94
  }
95
95
  }
96
96
 
97
- .gem-c-action-link--white-arrow {
98
- &::before {
99
- background-image: image-url("govuk_publishing_components/action-link-arrow--white.png");
100
- background-image: image-url("govuk_publishing_components/action-link-arrow--white.svg"), linear-gradient(transparent, transparent);
101
- }
102
- }
103
-
104
- .gem-c-action-link--blue-arrow {
105
- &::before {
106
- width: 36px;
107
- height: 28px;
108
- background: image-url("govuk_publishing_components/action-link-arrow--blue.png");
109
- background: image-url("govuk_publishing_components/action-link-arrow--blue.svg"), linear-gradient(transparent, transparent);
110
- background-repeat: no-repeat;
111
- background-size: 28px auto;
112
- background-position: 0 0;
113
-
114
- @include govuk-media-query($from: tablet) {
115
- width: 45px;
116
- height: 35px;
117
- background-size: 35px auto;
118
- }
119
- }
120
- }
121
-
122
97
  .gem-c-action-link--simple {
123
98
  &::before {
124
99
  width: 30px;
@@ -143,13 +118,6 @@
143
118
  }
144
119
  }
145
120
 
146
- .gem-c-action-link--dark-icon {
147
- &::before {
148
- background: image-url("govuk_publishing_components/action-link-arrow--dark.png");
149
- background: image-url("govuk_publishing_components/action-link-arrow--dark.svg"), linear-gradient(transparent, transparent);
150
- }
151
- }
152
-
153
121
  .gem-c-action-link--dark-large-icon {
154
122
  &::before {
155
123
  background: image-url("govuk_publishing_components/action-link-arrow--dark.png");
@@ -184,8 +152,7 @@
184
152
  }
185
153
  }
186
154
 
187
- .gem-c-action-link--dark-icon,
188
- .gem-c-action-link--small-icon {
155
+ .gem-c-action-link--dark-icon {
189
156
  max-width: none;
190
157
 
191
158
  @include govuk-media-query($until: tablet) {
@@ -195,57 +162,14 @@
195
162
  &::before {
196
163
  height: 30px;
197
164
  width: 35px;
165
+ background: image-url("govuk_publishing_components/action-link-arrow--dark.png");
166
+ background: image-url("govuk_publishing_components/action-link-arrow--dark.svg"), linear-gradient(transparent, transparent);
198
167
  background-repeat: no-repeat;
199
168
  background-size: 25px auto;
200
169
  background-position: 0 2px;
201
170
  }
202
171
  }
203
172
 
204
- .gem-c-action-link--transparent-icon {
205
- &::before {
206
- background-image: image-url("govuk_publishing_components/action-link-arrow--transparent.svg");
207
- }
208
- }
209
-
210
- .gem-c-action-link--brexit {
211
- max-width: none;
212
-
213
- &::before {
214
- height: 30px;
215
- width: 30px;
216
- background-image: image-url("govuk_publishing_components/action-link-arrow--brexit.svg");
217
- background-repeat: no-repeat;
218
- background-size: 18px auto;
219
- background-position: 0 2px;
220
- }
221
-
222
- @include govuk-media-query($until: tablet) {
223
- margin-bottom: govuk-spacing(2);
224
- }
225
-
226
- @include govuk-media-query($from: tablet) {
227
- margin-bottom: govuk-spacing(2);
228
-
229
- &::before {
230
- width: 35px;
231
- background-position: 0 4px;
232
- background-size: 25px auto;
233
- }
234
- }
235
- }
236
-
237
- .gem-c-action-link--nhs {
238
- &::before {
239
- width: 80px;
240
- height: 70px;
241
- background: image-url("govuk_publishing_components/action-link--nhs.png");
242
- background: image-url("govuk_publishing_components/action-link--nhs.svg"), linear-gradient(transparent, transparent);
243
- background-repeat: no-repeat;
244
- background-size: 85% auto;
245
- background-position: 0 50%;
246
- }
247
- }
248
-
249
173
  .gem-c-action-link--light-text {
250
174
  color: govuk-colour("white");
251
175