govuk_publishing_components 34.10.1 → 34.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 || {}