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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-core.js +123 -10
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.js +17 -92
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-form-tracker.js +8 -2
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-link-tracker.js +12 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-schemas.js +16 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-smart-answer-results-tracker.js +57 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-specialist-link-tracker.js +2 -2
- data/app/assets/javascripts/govuk_publishing_components/analytics-ga4.js +1 -0
- data/app/assets/javascripts/govuk_publishing_components/components/layout-super-navigation-header.js +0 -22
- data/app/assets/javascripts/govuk_publishing_components/lib/trigger-event.js +1 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +42 -94
- data/app/models/govuk_publishing_components/audit_components.rb +55 -1
- data/app/views/govuk_publishing_components/audit/_components.html.erb +46 -1
- data/app/views/govuk_publishing_components/components/_breadcrumbs.html.erb +1 -1
- data/app/views/govuk_publishing_components/components/_layout_super_navigation_header.html.erb +210 -221
- data/app/views/govuk_publishing_components/components/docs/breadcrumbs.yml +1 -1
- data/app/views/govuk_publishing_components/components/docs/related_navigation.yml +20 -0
- data/app/views/govuk_publishing_components/components/related_navigation/_section.html.erb +23 -13
- data/config/locales/en.yml +1 -1
- data/lib/govuk_publishing_components/presenters/breadcrumbs.rb +6 -0
- data/lib/govuk_publishing_components/presenters/related_navigation_helper.rb +14 -9
- data/lib/govuk_publishing_components/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd36433fa99aed8ea4144f791e7e78f72ae786e1148b7826758d65e271f98e5e
|
4
|
+
data.tar.gz: ce9e9975edbf99d74771088e9dadcd610ffacc345358afc25e85640a110d4035
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
86
|
-
|
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
|
-
|
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)
|
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)
|
194
|
+
if (this.hrefIsRelative(href)) {
|
191
195
|
return this.getProtocol() + '//' + this.getHostname()
|
192
196
|
} else {
|
193
|
-
|
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
|
}
|
data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-ecommerce-tracker.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
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.
|
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
|
-
|
50
|
-
var
|
46
|
+
trackResults: function (searchResultsBlock) {
|
47
|
+
var ecommerceSchema = GOVUK.analyticsGa4.core.ecommerceHelperFunctions.populateEcommerceSchema({
|
48
|
+
element: searchResultsBlock,
|
49
|
+
resultsId: 'js-result-count'
|
50
|
+
})
|
51
51
|
|
52
|
-
|
53
|
-
GOVUK.analyticsGa4.core.sendData(
|
52
|
+
GOVUK.analyticsGa4.core.ecommerceHelperFunctions.clearEcommerceObject()
|
53
|
+
GOVUK.analyticsGa4.core.sendData(ecommerceSchema)
|
54
54
|
},
|
55
55
|
|
56
56
|
handleClick: function (event) {
|
57
|
-
|
58
|
-
|
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
|
-
|
65
|
-
|
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
|
-
|
100
|
-
|
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
|
-
|
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)
|
data/app/assets/javascripts/govuk_publishing_components/analytics-ga4/ga4-specialist-link-tracker.js
CHANGED
@@ -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
|
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
|
|
data/app/assets/javascripts/govuk_publishing_components/components/layout-super-navigation-header.js
CHANGED
@@ -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
|
}
|