govuk_publishing_components 34.10.1 → 34.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-core.js +123 -10
  3. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.js +17 -92
  4. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-form-tracker.js +8 -2
  5. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-link-tracker.js +12 -0
  6. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-schemas.js +16 -0
  7. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-smart-answer-results-tracker.js +57 -0
  8. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-specialist-link-tracker.js +2 -2
  9. data/app/assets/javascripts/govuk_publishing_components/analytics-ga4.js +1 -0
  10. data/app/assets/javascripts/govuk_publishing_components/components/layout-super-navigation-header.js +0 -22
  11. data/app/assets/javascripts/govuk_publishing_components/lib/trigger-event.js +1 -0
  12. data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +42 -94
  13. data/app/models/govuk_publishing_components/audit_components.rb +55 -1
  14. data/app/views/govuk_publishing_components/audit/_components.html.erb +46 -1
  15. data/app/views/govuk_publishing_components/components/_breadcrumbs.html.erb +1 -1
  16. data/app/views/govuk_publishing_components/components/_layout_super_navigation_header.html.erb +210 -221
  17. data/app/views/govuk_publishing_components/components/docs/breadcrumbs.yml +1 -1
  18. data/app/views/govuk_publishing_components/components/docs/related_navigation.yml +20 -0
  19. data/app/views/govuk_publishing_components/components/related_navigation/_section.html.erb +23 -13
  20. data/config/locales/en.yml +1 -1
  21. data/lib/govuk_publishing_components/presenters/breadcrumbs.rb +6 -0
  22. data/lib/govuk_publishing_components/presenters/related_navigation_helper.rb +14 -9
  23. data/lib/govuk_publishing_components/version.rb +1 -1
  24. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 135e634f4b00ec7ed1030e313d6ee52f1202a0a6a2c83be7722d1a20dac4463b
4
- data.tar.gz: a41d77bfdef86a922c417c9d53e0c98b8d9f87bf942e38c477518b5ac6fffc28
3
+ metadata.gz: fd36433fa99aed8ea4144f791e7e78f72ae786e1148b7826758d65e271f98e5e
4
+ data.tar.gz: ce9e9975edbf99d74771088e9dadcd610ffacc345358afc25e85640a110d4035
5
5
  SHA512:
6
- metadata.gz: cf937ba2e03913a679decc84d49dbef881ee1647af4235311c39a2bcfbabdbc838c10f10f5ca2ad67fa42832bb9c0c91c614797c13faa6fd0fb109d83df40f90
7
- data.tar.gz: 3f8857da3f7227d59d765e0fdb92fea13d4abc0978af9ed07b005c2877e20be68d41f40b1450688adaa4b3f781e5d6b2303feb97928776f2644daed474735e33
6
+ metadata.gz: bbb41c9f45ecf8ae1e4f12d80f871392b08e97bf8c7074e22a2a1d265cb67d317bc1350cb1eb855270e1a48945c1e0a0b156e8e0c50eed2ed17998cb921ad640
7
+ data.tar.gz: bce8a83d09679a2e20a5bc5e05f112a207e455ed8eae2b726ad670c19c84348868a918ec82abd30119196332b6dc5a3f5443697622008eadee028f9d2ca2f974
@@ -40,6 +40,12 @@ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
40
40
  },
41
41
 
42
42
  trackFunctions: {
43
+
44
+ getDomainRegex: function () {
45
+ // 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
46
+ return /^(http:||https:)?(\/\/)([^\/]*)/ // eslint-disable-line no-useless-escape
47
+ },
48
+
43
49
  findTrackingAttributes: function (clicked, trackingTrigger) {
44
50
  if (clicked.hasAttribute('[' + trackingTrigger + ']')) {
45
51
  return clicked
@@ -82,12 +88,10 @@ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
82
88
  },
83
89
 
84
90
  hrefIsRelative: function (href) {
85
- // Checks that a link is relative, but is not a protocol relative url
86
- return href[0] === '/' && href[1] !== '/'
87
- },
91
+ // Checks that a href is relative by the lack of http:, https:// or // at the start of the href.
92
+ var domain = this.getDomainRegex().exec(href)
88
93
 
89
- hrefIsAnchor: function (href) {
90
- return href[0] === '#'
94
+ return !domain
91
95
  },
92
96
 
93
97
  isMailToLink: function (href) {
@@ -115,7 +119,7 @@ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
115
119
 
116
120
  isInternalLink: function (href) {
117
121
  var internalDomains = window.GOVUK.analyticsGa4.vars.internalDomains
118
- if (this.hrefIsRelative(href) || this.hrefIsAnchor(href)) {
122
+ if (this.hrefIsRelative(href)) {
119
123
  return true
120
124
  }
121
125
  var result = false
@@ -187,12 +191,10 @@ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
187
191
  return undefined
188
192
  }
189
193
 
190
- if (this.hrefIsRelative(href) || this.hrefIsAnchor(href)) {
194
+ if (this.hrefIsRelative(href)) {
191
195
  return this.getProtocol() + '//' + this.getHostname()
192
196
  } else {
193
- // 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
194
- var domainRegex = /^(http:||https:)?(\/\/)([^\/]*)/ // eslint-disable-line no-useless-escape
195
- var domain = domainRegex.exec(href)
197
+ var domain = this.getDomainRegex().exec(href)
196
198
  if (domain) {
197
199
  return domain[0]
198
200
  }
@@ -216,6 +218,117 @@ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
216
218
  domainsArrays.push(domainWithoutWww)
217
219
  }
218
220
  }
221
+ },
222
+
223
+ // The index and index_total properties are usually set by the application's templating engine however in instances where this isn't possible,
224
+ // we use JavaScript to calculate the index_total and append it to data-ga4-link and add an index property to each link
225
+ setIndexes: function (module) {
226
+ var links = module.querySelectorAll('a')
227
+ var totalLinks = 0
228
+ for (var i = 0; i < links.length; i++) {
229
+ var link = links[i]
230
+ // Only index links that are not search results
231
+ if (!link.getAttribute('data-ga4-ecommerce-path')) {
232
+ totalLinks++
233
+ link.setAttribute('data-ga4-index', totalLinks)
234
+ }
235
+ }
236
+
237
+ var ga4LinkData = JSON.parse(module.getAttribute('data-ga4-link'))
238
+ ga4LinkData.index_total = totalLinks
239
+ module.setAttribute('data-ga4-link', JSON.stringify(ga4LinkData))
240
+ }
241
+ },
242
+
243
+ ecommerceHelperFunctions: {
244
+ clearEcommerceObject: function () {
245
+ window.GOVUK.analyticsGa4.core.sendData({ search_results: { ecommerce: null } })
246
+ },
247
+
248
+ getIndex: function (element, startPosition) {
249
+ var index = element.getAttribute('data-ecommerce-index')
250
+
251
+ if (!index) {
252
+ return null
253
+ }
254
+
255
+ return parseInt(index) + startPosition - 1
256
+ },
257
+
258
+ getResultCount: function (element, id) {
259
+ var resultCount = element.querySelector('#' + id)
260
+
261
+ if (!resultCount) {
262
+ return null
263
+ }
264
+
265
+ // In order to extract the number of results from resultCount (which is a string at this point (e.g. '12,345 results')), we remove the comma and
266
+ // split string at the space character so it can be parsed as an integer
267
+ resultCount = resultCount.textContent.replace(',', '')
268
+ resultCount = resultCount.split(' ')[0]
269
+
270
+ return parseInt(resultCount)
271
+ },
272
+
273
+ populateEcommerceSchema: function (data) {
274
+ var element = data.element
275
+ var resultsId = data.resultsId
276
+ var isClickEvent = data.event !== undefined
277
+ var isSearchResult = element.getAttribute('data-search-query')
278
+
279
+ var ecommerceSchema = new window.GOVUK.analyticsGa4.Schemas().ecommerceSchema()
280
+ var PIIRemover = new window.GOVUK.analyticsGa4.PIIRemover()
281
+ var DEFAULT_LIST_TITLE = 'Smart answer results'
282
+
283
+ if (isSearchResult) {
284
+ // Limiting to 100 characters to avoid noise from extra long search queries and to stop the size of the payload going over 8k limit.
285
+ var searchQuery = PIIRemover.stripPII(element.getAttribute('data-search-query')).substring(0, 100).toLowerCase()
286
+ var variant = element.getAttribute('data-ecommerce-variant')
287
+ DEFAULT_LIST_TITLE = 'Site search results'
288
+ }
289
+
290
+ var items = element.querySelectorAll('[data-ga4-ecommerce-path]')
291
+ var listTitle = element.getAttribute('data-list-title') || DEFAULT_LIST_TITLE
292
+ var startPosition = parseInt(element.getAttribute('data-ecommerce-start-index'), 10)
293
+
294
+ ecommerceSchema.event = 'search_results'
295
+ ecommerceSchema.search_results.event_name = isClickEvent ? 'select_item' : 'view_item_list'
296
+ ecommerceSchema.search_results.results = window.GOVUK.analyticsGa4.core.ecommerceHelperFunctions.getResultCount(element, resultsId)
297
+ ecommerceSchema.search_results.term = searchQuery || undefined
298
+ ecommerceSchema.search_results.sort = variant || undefined
299
+
300
+ if (isClickEvent) {
301
+ var target = data.event.target
302
+ ecommerceSchema.search_results.ecommerce.items.push({
303
+ item_id: target.getAttribute('data-ga4-ecommerce-path'),
304
+ item_name: target.textContent,
305
+ item_list_name: listTitle,
306
+ index: window.GOVUK.analyticsGa4.core.ecommerceHelperFunctions.getIndex(target, startPosition)
307
+ })
308
+
309
+ ecommerceSchema.event_data = {
310
+ external: window.GOVUK.analyticsGa4.core.trackFunctions.isExternalLink(target.getAttribute('data-ga4-ecommerce-path')) ? 'true' : 'false'
311
+ }
312
+ } else {
313
+ for (var i = 0; i < items.length; i++) {
314
+ var item = items[i]
315
+ var path = item.getAttribute('data-ga4-ecommerce-path')
316
+
317
+ // If the element does not have a data-ecommerce-index attribute, we set one so that we can use it later when setting the index property
318
+ // on the ecommerce object.
319
+ if (!item.getAttribute('data-ecommerce-index')) {
320
+ item.setAttribute('data-ecommerce-index', i + 1)
321
+ }
322
+
323
+ ecommerceSchema.search_results.ecommerce.items.push({
324
+ item_id: path,
325
+ item_list_name: listTitle,
326
+ index: window.GOVUK.analyticsGa4.core.ecommerceHelperFunctions.getIndex(item, startPosition)
327
+ })
328
+ }
329
+ }
330
+
331
+ return ecommerceSchema
219
332
  }
220
333
  }
221
334
  }
@@ -1,4 +1,4 @@
1
- // = require govuk/vendor/polyfills/Element/prototype/closest.js
1
+ //= require govuk/vendor/polyfills/Element/prototype/closest.js
2
2
  ;(function (global) {
3
3
  'use strict'
4
4
 
@@ -6,9 +6,6 @@
6
6
  GOVUK.analyticsGa4 = GOVUK.analyticsGa4 || {}
7
7
 
8
8
  GOVUK.analyticsGa4.Ga4EcommerceTracker = {
9
- PIIRemover: new GOVUK.analyticsGa4.PIIRemover(),
10
- DEFAULT_LIST_TITLE: 'Site search results',
11
-
12
9
  init: function (referrer) {
13
10
  if (window.dataLayer) {
14
11
  /* The referrer parameter is only passed to the init() function as a result of an AJAX request
@@ -37,7 +34,7 @@
37
34
  }
38
35
 
39
36
  for (var i = 0; i < this.searchResultsBlocks.length; i++) {
40
- this.trackSearchResults(this.searchResultsBlocks[i])
37
+ this.trackResults(this.searchResultsBlocks[i])
41
38
 
42
39
  if (isNewPageLoad) {
43
40
  this.searchResultsBlocks[i].addEventListener('click', this.handleClick.bind(this))
@@ -46,101 +43,29 @@
46
43
  }
47
44
  },
48
45
 
49
- trackSearchResults: function (searchResultsBlock) {
50
- var schema = this.populateEcommerceSchema(searchResultsBlock, false, null)
46
+ trackResults: function (searchResultsBlock) {
47
+ var ecommerceSchema = GOVUK.analyticsGa4.core.ecommerceHelperFunctions.populateEcommerceSchema({
48
+ element: searchResultsBlock,
49
+ resultsId: 'js-result-count'
50
+ })
51
51
 
52
- this.clearPreviousEcommerceObject()
53
- GOVUK.analyticsGa4.core.sendData(schema)
52
+ GOVUK.analyticsGa4.core.ecommerceHelperFunctions.clearEcommerceObject()
53
+ GOVUK.analyticsGa4.core.sendData(ecommerceSchema)
54
54
  },
55
55
 
56
56
  handleClick: function (event) {
57
- var searchResultsBlock = event.target.closest('[data-ga4-ecommerce]')
58
- var isSearchResult = event.target.getAttribute('data-ecommerce-path')
59
-
60
- if (isSearchResult) {
61
- var searchResult = event.target
62
- var schema = this.populateEcommerceSchema(searchResultsBlock, true, searchResult)
57
+ if (event.target.getAttribute('data-ga4-ecommerce-path')) {
58
+ var searchResultsBlock = event.target.closest('[data-ga4-ecommerce]')
63
59
 
64
- this.clearPreviousEcommerceObject()
65
- GOVUK.analyticsGa4.core.sendData(schema)
66
- }
67
- },
68
-
69
- populateEcommerceSchema: function (searchResultsBlock, searchResultClicked, searchResult) {
70
- // Limiting to 100 characters to avoid noise from extra long search queries and to stop the size of the payload going over 8k limit.
71
- var searchQuery = this.PIIRemover.stripPII(searchResultsBlock.getAttribute('data-search-query')).substring(0, 100).toLowerCase()
72
- var variant = searchResultsBlock.getAttribute('data-ecommerce-variant') || undefined
73
- var ecommerceRows = searchResultsBlock.querySelectorAll('[data-ecommerce-row]')
74
- var listTitle = searchResultsBlock.getAttribute('data-list-title') || this.DEFAULT_LIST_TITLE
75
- var startPosition = parseInt(searchResultsBlock.getAttribute('data-ecommerce-start-index'), 10)
76
-
77
- var ecommerceObject = {
78
- event: 'search_results',
79
- search_results: {
80
- event_name: searchResultClicked && searchResult ? 'select_item' : 'view_item_list',
81
- term: searchQuery,
82
- sort: variant,
83
- results: this.getResultsCount(searchResultsBlock),
84
- ecommerce: {
85
- items: []
86
- }
87
- }
88
- }
89
-
90
- // Populate items array
91
- if (searchResultClicked && searchResult) {
92
- ecommerceObject.search_results.ecommerce.items.push({
93
- item_id: searchResult.getAttribute('data-ecommerce-path'),
94
- item_name: searchResult.textContent,
95
- item_list_name: listTitle,
96
- index: this.getIndex(searchResult, startPosition)
60
+ var ecommerceSchema = GOVUK.analyticsGa4.core.ecommerceHelperFunctions.populateEcommerceSchema({
61
+ element: searchResultsBlock,
62
+ resultsId: 'js-result-count',
63
+ event: event
97
64
  })
98
65
 
99
- ecommerceObject.event_data = {
100
- external: GOVUK.analyticsGa4.core.trackFunctions.isExternalLink(searchResult.getAttribute('data-ecommerce-path')) ? 'true' : 'false'
101
- }
102
- } else {
103
- for (var i = 0; i < ecommerceRows.length; i++) {
104
- var ecommerceRow = ecommerceRows[i]
105
- var path = ecommerceRow.getAttribute('data-ecommerce-path')
106
-
107
- /* If the element does not have a data-ecommerce-index attribute, we set one so that we can use it later when setting the index property
108
- on the ecommerce object. This for loop will always run on page load and so data-ecommerce-index will be available when we use it in the
109
- initial if block above that checks if a search result has been clicked. */
110
- if (!ecommerceRow.getAttribute('data-ecommerce-index')) {
111
- ecommerceRow.setAttribute('data-ecommerce-index', i + 1)
112
- }
113
-
114
- ecommerceObject.search_results.ecommerce.items.push({
115
- item_id: path,
116
- item_list_name: listTitle,
117
- index: this.getIndex(ecommerceRow, startPosition)
118
- })
119
- }
120
- }
121
-
122
- return ecommerceObject
123
- },
124
-
125
- getIndex: function (element, startPosition) {
126
- return parseInt(element.getAttribute('data-ecommerce-index')) + startPosition - 1
127
- },
128
-
129
- clearPreviousEcommerceObject: function () {
130
- GOVUK.analyticsGa4.core.sendData({ search_results: { ecommerce: null } })
131
- },
132
-
133
- getResultsCount: function (searchResultsBlock) {
134
- // This returns a string e.g. '12,345 results'. Therefore to extract the number, we need to remove the comma and split the string at the space
135
- var resultsCount = searchResultsBlock.querySelector('#js-result-count')
136
-
137
- if (!resultsCount) {
138
- return null
66
+ GOVUK.analyticsGa4.core.ecommerceHelperFunctions.clearEcommerceObject()
67
+ GOVUK.analyticsGa4.core.sendData(ecommerceSchema)
139
68
  }
140
-
141
- resultsCount = resultsCount.textContent.replace(',', '')
142
- resultsCount = resultsCount.split(' ')[0]
143
- return parseInt(resultsCount)
144
69
  }
145
70
  }
146
71
 
@@ -7,6 +7,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
7
7
  function Ga4FormTracker (module) {
8
8
  this.module = module
9
9
  this.trackingTrigger = 'data-ga4-form' // elements with this attribute get tracked
10
+ this.includeTextInputValues = this.module.hasAttribute('data-ga4-form-include-text')
10
11
  }
11
12
 
12
13
  Ga4FormTracker.prototype.init = function () {
@@ -82,8 +83,13 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
82
83
  input.answer = labelText
83
84
  } else if (inputNodename === 'SELECT' && elem.options[elem.selectedIndex].value) {
84
85
  input.answer = elem.options[elem.selectedIndex].text
85
- } else if (inputType === 'text' && elem.value) {
86
- input.answer = '[REDACTED]'
86
+ } else if ((inputType === 'text' || inputType === 'search') && elem.value) {
87
+ if (this.includeTextInputValues) {
88
+ var PIIRemover = new window.GOVUK.analyticsGa4.PIIRemover()
89
+ input.answer = PIIRemover.stripPIIWithOverride(elem.value, true, true)
90
+ } else {
91
+ input.answer = '[REDACTED]'
92
+ }
87
93
  } else if (inputType === 'radio' && elem.checked) {
88
94
  input.answer = labelText
89
95
  } else {
@@ -32,6 +32,10 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
32
32
  this.module.addEventListener('click', this.handleClick)
33
33
  this.module.addEventListener('contextmenu', this.handleClick)
34
34
  this.module.addEventListener('mousedown', this.handleMousedown)
35
+
36
+ if (this.module.hasAttribute('data-ga4-set-indexes')) {
37
+ window.GOVUK.analyticsGa4.core.trackFunctions.setIndexes(this.module)
38
+ }
35
39
  }
36
40
  }
37
41
 
@@ -56,6 +60,13 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
56
60
  }
57
61
 
58
62
  Ga4LinkTracker.prototype.trackClick = function (event) {
63
+ var element = event.target
64
+
65
+ // don't track this link if it's already being tracked by the ecommerce tracker
66
+ if (element.closest('[data-ga4-ecommerce-path]')) {
67
+ return
68
+ }
69
+
59
70
  var target = window.GOVUK.analyticsGa4.core.trackFunctions.findTrackingAttributes(event.target, this.trackingTrigger)
60
71
  if (target) {
61
72
  try {
@@ -75,6 +86,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
75
86
  data.link_path_parts = window.GOVUK.analyticsGa4.core.trackFunctions.populateLinkPathParts(data.url)
76
87
  data.method = window.GOVUK.analyticsGa4.core.trackFunctions.getClickType(event)
77
88
  data.external = window.GOVUK.analyticsGa4.core.trackFunctions.isExternalLink(data.url) ? 'true' : 'false'
89
+ data.index = event.target.getAttribute('data-ga4-index') ? parseInt(event.target.getAttribute('data-ga4-index')) : data.index || undefined
78
90
 
79
91
  var schemas = new window.GOVUK.analyticsGa4.Schemas()
80
92
  var schema = schemas.mergeProperties(data, 'event_data')
@@ -29,6 +29,22 @@
29
29
  }
30
30
  }
31
31
 
32
+ Schemas.prototype.ecommerceSchema = function () {
33
+ return {
34
+ event: this.undefined,
35
+ search_results: {
36
+ event_name: this.undefined,
37
+ term: this.undefined,
38
+ sort: this.undefined,
39
+ results: this.undefined,
40
+ ecommerce: {
41
+ items: []
42
+ }
43
+ },
44
+ event_data: this.undefined
45
+ }
46
+ }
47
+
32
48
  // get attributes from the data attribute to send to GA
33
49
  // only allow it if it already exists in the schema
34
50
  Schemas.prototype.mergeProperties = function (data, eventAttribute) {
@@ -0,0 +1,57 @@
1
+ window.GOVUK = window.GOVUK || {}
2
+ window.GOVUK.Modules = window.GOVUK.Modules || {}
3
+ window.GOVUK.analyticsGa4 = window.GOVUK.analyticsGa4 || {};
4
+
5
+ (function (Modules) {
6
+ 'use strict'
7
+
8
+ function Ga4SmartAnswerResultsTracker (module) {
9
+ this.module = module
10
+ }
11
+
12
+ Ga4SmartAnswerResultsTracker.prototype.init = function () {
13
+ var consentCookie = window.GOVUK.getConsentCookie()
14
+
15
+ if (consentCookie && consentCookie.settings) {
16
+ this.startModule()
17
+ } else {
18
+ this.startModule = this.startModule.bind(this)
19
+ window.addEventListener('cookie-consent', this.startModule)
20
+ }
21
+ }
22
+
23
+ // triggered by cookie-consent event, which happens when users consent to cookies
24
+ Ga4SmartAnswerResultsTracker.prototype.startModule = function () {
25
+ // only run this code if the dataLayer exists and an element with a data-ga4-ecommerce-path
26
+ // attribute exists as this indicates that ecommerce tracking is required
27
+ if (window.dataLayer && this.module.querySelector('[data-ga4-ecommerce-path]')) {
28
+ this.trackResults()
29
+ this.module.addEventListener('click', this.handleClick.bind(this))
30
+ }
31
+ }
32
+
33
+ Ga4SmartAnswerResultsTracker.prototype.trackResults = function () {
34
+ var ecommerceSchema = window.GOVUK.analyticsGa4.core.ecommerceHelperFunctions.populateEcommerceSchema({
35
+ element: this.module,
36
+ resultsId: 'ga4-ecommerce-result-count'
37
+ })
38
+
39
+ window.GOVUK.analyticsGa4.core.ecommerceHelperFunctions.clearEcommerceObject()
40
+ window.GOVUK.analyticsGa4.core.sendData(ecommerceSchema)
41
+ }
42
+
43
+ Ga4SmartAnswerResultsTracker.prototype.handleClick = function (event) {
44
+ if (event.target.getAttribute('data-ga4-ecommerce-path')) {
45
+ var ecommerceSchema = window.GOVUK.analyticsGa4.core.ecommerceHelperFunctions.populateEcommerceSchema({
46
+ element: this.module,
47
+ resultsId: 'ga4-ecommerce-result-count',
48
+ event: event
49
+ })
50
+
51
+ window.GOVUK.analyticsGa4.core.ecommerceHelperFunctions.clearEcommerceObject()
52
+ window.GOVUK.analyticsGa4.core.sendData(ecommerceSchema)
53
+ }
54
+ }
55
+
56
+ Modules.Ga4SmartAnswerResultsTracker = Ga4SmartAnswerResultsTracker
57
+ })(window.GOVUK.Modules)
@@ -39,8 +39,8 @@ window.GOVUK.analyticsGa4.analyticsModules = window.GOVUK.analyticsGa4.analytics
39
39
  return
40
40
  }
41
41
 
42
- // don't track this link if it's already being tracked by the other link tracker
43
- if (element.closest('[data-ga4-link]')) {
42
+ // don't track this link if it's already being tracked by the another tracker (e.g. the link tracker or ecommerce tracker)
43
+ if (element.closest('[data-ga4-link]') || element.closest('[data-ga4-ecommerce-path]')) {
44
44
  return
45
45
  }
46
46
 
@@ -9,4 +9,5 @@
9
9
  //= require ./analytics-ga4/ga4-ecommerce-tracker
10
10
  //= require ./analytics-ga4/ga4-form-tracker
11
11
  //= require ./analytics-ga4/ga4-auto-tracker
12
+ //= require ./analytics-ga4/ga4-smart-answer-results-tracker
12
13
  //= require ./analytics-ga4/init-ga4
@@ -5,9 +5,6 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
5
5
 
6
6
  (function (Modules) {
7
7
  var SETTINGS = {
8
- breakpoint: {
9
- desktop: 769
10
- },
11
8
  label: {
12
9
  hide: 'data-text-for-hide',
13
10
  show: 'data-text-for-show'
@@ -110,18 +107,6 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
110
107
  this.hiddenButtons = this.$module.querySelectorAll('button[hidden]')
111
108
  }
112
109
 
113
- SuperNavigationMegaMenu.prototype.updateStates = function () {
114
- // Check whether any of the dropdown menus are open.
115
- var $openButton = this.$module.querySelector('[aria-expanded="true"][data-toggle-desktop-group="top"]')
116
- // Gets the open dropdown menu
117
- var $openMenu = $openButton ? this.$module.querySelector('#' + $openButton.getAttribute('aria-controls')) : null
118
- // If there is an open dropdown menu, get the height of the dropdown menu.
119
- var margin = $openMenu ? $openMenu.offsetHeight : 0
120
-
121
- // Make space for the dropdown menu.
122
- this.$module.style.marginBottom = margin + 'px'
123
- }
124
-
125
110
  SuperNavigationMegaMenu.prototype.buttonHandler = function (event) {
126
111
  var $target = closestParentIncluding(event.target, 'button')
127
112
  var $targetMenu = this.$module.querySelector('#' + $target.getAttribute('aria-controls'))
@@ -139,8 +124,6 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
139
124
  }
140
125
 
141
126
  toggle($target, $targetMenu)
142
-
143
- this.$module.style.marginBottom = $targetMenu.offsetHeight + 'px'
144
127
  }
145
128
 
146
129
  SuperNavigationMegaMenu.prototype.init = function () {
@@ -180,11 +163,6 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
180
163
  // - On desktop, this means hiding the navigation button, showing the
181
164
  // second level navigation menu
182
165
  hide(this.$searchToggle, this.$searchMenu)
183
- this.updateStates()
184
-
185
- // The menu needs to be updated when the window is resized to make sure that
186
- // the space needed for the dropdown menu is correct.
187
- window.addEventListener('resize', this.updateStates.bind(this), { passive: true })
188
166
 
189
167
  this.$module.classList.add('js-module-initialised')
190
168
  }
@@ -1,3 +1,4 @@
1
+ // see https://github.com/alphagov/govuk_publishing_components/blob/main/docs/lib/trigger_event.md
1
2
  (function (root) {
2
3
  'use strict'
3
4
  window.GOVUK = window.GOVUK || {}