govuk_publishing_components 30.7.0 → 30.7.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 932b483ebc824de1a71b97e465fe66919e6adc1d95e95948e0fefa71cc094fe4
4
- data.tar.gz: 22584814d289f173d79f6ea9f9bf9e2d7368daa59b681772cb6a45ebaf381a24
3
+ metadata.gz: 3c7f16760ab4f91b2f86e6dda6f9066d33f3e1dc305170a0a7aca313df2fbf63
4
+ data.tar.gz: 7484fc85aad02f15bdb4de512979855520517a7cff39b6f8c7365be85666f176
5
5
  SHA512:
6
- metadata.gz: 21a4d08ff321e2ef0e112e44a98ff1cd7da84991a5b650fc0e881355baee7162da644c2cc2b96e774951b5d64482ee293861b28cb1ebc7bdd0ee39ecdef1a30c
7
- data.tar.gz: b2b47fe59365c766b0511d609830aa082a1892f0ce939e7ddc6fc8da659ba2edd338ed363e5d802322e866cde20ca49c4ee06f9a847cfe44a42c6f31d9b7bb7e
6
+ metadata.gz: 19878d148ec4971e70494e929eb372e1c83411ca86e14435afba05929feb01d793c3300152150f11fe94370ae98997b30c2759a1b5c84dff4e81d7013446631a
7
+ data.tar.gz: 9e29ae1795f429a733a63da7da96382318a9a590e767086222e47802c075a0a6b510d511e57205a95d63a0528e03b6458d9e4266ca092e617134b71d8db58387
@@ -6,14 +6,44 @@ window.GOVUK.analyticsGA4 = window.GOVUK.analyticsGA4 || {};
6
6
 
7
7
  var core = {
8
8
  load: function () {
9
- /* eslint-disable */
10
- (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
11
- new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
12
- j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
13
- 'https://www.googletagmanager.com/gtm.js?id='+i+dl+ '&gtm_auth=' + window.GOVUK.analyticsGA4.vars.auth + '&gtm_preview=' + window.GOVUK.analyticsGA4.vars.preview + '&gtm_cookies_win=x';f.parentNode.insertBefore(j,f);
14
- })(window,document,'script','dataLayer',window.GOVUK.analyticsGA4.vars.id);
15
- window.dataLayer.push({ 'gtm.blocklist' : ['customPixels', 'customScripts', 'html', 'nonGoogleScripts'] })
16
- /* eslint-enable */
9
+ if (window.GOVUK.analyticsGA4.vars.gtag_id) {
10
+ // initialise gtag
11
+ window.dataLayer = window.dataLayer || []
12
+ function gtag() { dataLayer.push(arguments) }
13
+ gtag('js', new Date())
14
+ gtag('config', window.GOVUK.analyticsGA4.vars.gtag_id)
15
+
16
+ var firstScript = document.getElementsByTagName('script')[0]
17
+ var newScript = document.createElement('script')
18
+ var dl = 'dataLayer' != 'dataLayer' ? '&l=' + 'dataLayer' : ''
19
+
20
+ newScript.async = true
21
+ newScript.src = '//www.googletagmanager.com/gtag/js?id=' + window.GOVUK.analyticsGA4.vars.gtag_id + dl
22
+ firstScript.parentNode.insertBefore(newScript, firstScript)
23
+ } else {
24
+ // initialise GTM
25
+ window.dataLayer = window.dataLayer || []
26
+ window.dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' })
27
+
28
+ var firstScript = document.getElementsByTagName('script')[0]
29
+ var newScript = document.createElement('script')
30
+ var dl = 'dataLayer' != 'dataLayer' ? '&l=' + 'dataLayer' : ''
31
+
32
+ var auth = window.GOVUK.analyticsGA4.vars.auth || ''
33
+ var preview = window.GOVUK.analyticsGA4.vars.preview || ''
34
+ if (auth) {
35
+ auth = '&gtm_auth=' + auth
36
+ }
37
+ if (preview) {
38
+ preview = '&gtm_preview=' + preview + '&gtm_cookies_win=x'
39
+ }
40
+
41
+ newScript.async = true
42
+ this.googleSrc = 'https://www.googletagmanager.com/gtm.js?id=' + window.GOVUK.analyticsGA4.vars.id + dl + auth + preview
43
+ newScript.src = this.googleSrc
44
+ firstScript.parentNode.insertBefore(newScript, firstScript)
45
+ window.dataLayer.push({ 'gtm.blocklist' : ['customPixels', 'customScripts', 'html', 'nonGoogleScripts'] })
46
+ }
17
47
  },
18
48
 
19
49
  sendData: function (data) {
@@ -7,15 +7,23 @@ window.GOVUK.analyticsGA4.analyticsModules = window.GOVUK.analyticsGA4.analytics
7
7
  'use strict'
8
8
 
9
9
  var Ga4LinkTracker = {
10
- init: function () {
10
+ init: function (config) {
11
11
  if (window.dataLayer) {
12
- this.internalLinksDomain = 'www.gov.uk/'
13
- this.internalLinksDomainWithoutWww = 'gov.uk/'
12
+ config = config || {}
13
+ this.internalDomains = config.internalDomains || []
14
+ this.internalDomains.push(this.getHostname())
15
+ this.appendDomainsWithoutWWW(this.internalDomains)
16
+ this.internalDownloadPaths = config.internalDownloadPaths || ['/government/uploads/']
17
+ this.dedicatedDownloadDomains = config.dedicatedDownloadDomains || ['assets.publishing.service.gov.uk']
18
+ this.appendDomainsWithoutWWW(this.dedicatedDownloadDomains)
14
19
  this.handleClick = this.handleClick.bind(this)
15
20
  this.handleMousedown = this.handleMousedown.bind(this)
16
- document.querySelector('body').addEventListener('click', this.handleClick)
17
- document.querySelector('body').addEventListener('contextmenu', this.handleClick)
18
- document.querySelector('body').addEventListener('mousedown', this.handleMousedown)
21
+
22
+ if (!config.disableListeners) {
23
+ document.querySelector('body').addEventListener('click', this.handleClick)
24
+ document.querySelector('body').addEventListener('contextmenu', this.handleClick)
25
+ document.querySelector('body').addEventListener('mousedown', this.handleMousedown)
26
+ }
19
27
  }
20
28
  },
21
29
 
@@ -43,25 +51,52 @@ window.GOVUK.analyticsGA4.analyticsModules = window.GOVUK.analyticsGA4.analytics
43
51
  return
44
52
  }
45
53
 
46
- if (this.isMailToLink(href)) {
54
+ var linkAttributes = element.getAttribute('data-ga4-link')
55
+ if (linkAttributes) {
56
+ linkAttributes = JSON.parse(linkAttributes)
57
+ clickData = window.GOVUK.extendObject(clickData, linkAttributes)
58
+
59
+ /* Since external links can't be determined in the template, we use populated-via-js as a signal
60
+ for our JavaScript to determine this value. */
61
+ if (clickData.external === 'populated-via-js' && clickData.url) {
62
+ clickData.external = this.isExternalLink(clickData.url) ? 'true' : 'false'
63
+ }
64
+
65
+ if (clickData.link_method === 'populated-via-js') {
66
+ clickData.link_method = this.getClickType(event)
67
+ }
68
+
69
+ if (clickData.index) {
70
+ clickData.index = parseInt(linkAttributes.index)
71
+ }
72
+
73
+ if (clickData.index_total) {
74
+ clickData.index_total = parseInt(linkAttributes.index_total)
75
+ }
76
+ } else if (this.isMailToLink(href)) {
47
77
  clickData.event_name = 'navigation'
48
78
  clickData.type = 'email'
49
79
  clickData.external = 'true'
80
+ clickData.url = href
81
+ clickData.text = element.textContent.trim()
82
+ clickData.link_method = this.getClickType(event)
50
83
  } else if (this.isDownloadLink(href)) {
51
84
  clickData.event_name = 'file_download'
52
85
  clickData.type = this.isPreviewLink(href) ? 'preview' : 'generic download'
53
- clickData.external = 'true'
86
+ clickData.external = this.isExternalLink(href) ? 'true' : 'false'
87
+ clickData.url = href
88
+ clickData.text = element.textContent.trim()
89
+ clickData.link_method = this.getClickType(event)
54
90
  } else if (this.isExternalLink(href)) {
55
91
  clickData.event_name = 'navigation'
56
92
  clickData.type = 'generic link'
57
93
  clickData.external = 'true'
58
- }
59
-
60
- if (Object.keys(clickData).length > 0) {
61
- clickData.text = element.textContent.trim()
62
94
  clickData.url = href
95
+ clickData.text = element.textContent.trim()
63
96
  clickData.link_method = this.getClickType(event)
97
+ }
64
98
 
99
+ if (Object.keys(clickData).length > 0) {
65
100
  var schema = new window.GOVUK.analyticsGA4.Schemas().eventSchema()
66
101
  schema.event = 'event_data'
67
102
 
@@ -77,6 +112,17 @@ window.GOVUK.analyticsGA4.analyticsModules = window.GOVUK.analyticsGA4.analytics
77
112
  }
78
113
  },
79
114
 
115
+ appendDomainsWithoutWWW: function (domainsArrays) {
116
+ // Add domains with www. removed, in case site hrefs are marked up without www. included.
117
+ for (var i = 0; i < domainsArrays.length; i++) {
118
+ var domain = domainsArrays[i]
119
+ if (this.stringStartsWith(domain, 'www.')) {
120
+ var domainWithoutWww = domain.replace('www.', '')
121
+ domainsArrays.push(domainWithoutWww)
122
+ }
123
+ }
124
+ },
125
+
80
126
  getClickType: function (event) {
81
127
  switch (event.type) {
82
128
  case 'click':
@@ -84,6 +130,8 @@ window.GOVUK.analyticsGA4.analyticsModules = window.GOVUK.analyticsGA4.analytics
84
130
  return 'ctrl click'
85
131
  } else if (event.metaKey) {
86
132
  return 'command/win click'
133
+ } else if (event.shiftKey) {
134
+ return 'shift click'
87
135
  } else {
88
136
  return 'primary click'
89
137
  }
@@ -106,29 +154,36 @@ window.GOVUK.analyticsGA4.analyticsModules = window.GOVUK.analyticsGA4.analytics
106
154
  },
107
155
 
108
156
  isDownloadLink: function (href) {
109
- var assetsDomain = 'assets.publishing.service.gov.uk/'
110
- var uploadsPath = '/government/uploads/'
111
-
112
- if (this.hrefPointsToDomain(href, assetsDomain)) {
157
+ if (this.isInternalLink(href) && this.hrefPointsToDownloadPath(href)) {
113
158
  return true
114
159
  }
115
160
 
116
- var isInternalLink = this.hrefPointsToDomain(href, this.internalLinksDomain) || this.hrefPointsToDomain(href, this.internalLinksDomainWithoutWww)
117
- if (isInternalLink && href.indexOf(uploadsPath) !== -1) {
118
- return true
161
+ var result = false
162
+ for (var i = 0; i < this.dedicatedDownloadDomains.length; i++) {
163
+ var downloadDomain = this.dedicatedDownloadDomains[i]
164
+ if (this.hrefPointsToDomain(href, downloadDomain)) {
165
+ result = true
166
+ }
119
167
  }
168
+ return result
169
+ },
120
170
 
121
- // Checks relative links to the uploadsPath
122
- if (this.stringStartsWith(href, uploadsPath)) {
171
+ isInternalLink: function (href) {
172
+ if (this.hrefIsRelative(href) || this.hrefIsAnchor(href)) {
123
173
  return true
124
174
  }
175
+ var result = false
176
+ for (var i = 0; i < this.internalDomains.length; i++) {
177
+ var internalDomain = this.internalDomains[i]
178
+ if (this.hrefPointsToDomain(href, internalDomain)) {
179
+ result = true
180
+ }
181
+ }
182
+ return result
125
183
  },
126
184
 
127
185
  isExternalLink: function (href) {
128
- var isInternalLink = this.hrefPointsToDomain(href, this.internalLinksDomain) || this.hrefPointsToDomain(href, this.internalLinksDomainWithoutWww)
129
- if (!isInternalLink && !this.hrefIsRelative(href) && !this.hrefIsAnchor(href)) {
130
- return true
131
- }
186
+ return !this.isInternalLink(href)
132
187
  },
133
188
 
134
189
  isPreviewLink: function (href) {
@@ -144,6 +199,19 @@ window.GOVUK.analyticsGA4.analyticsModules = window.GOVUK.analyticsGA4.analytics
144
199
  },
145
200
 
146
201
  hrefPointsToDomain: function (href, domain) {
202
+ /* Add a trailing slash to prevent an edge case such
203
+ as the href www.gov.uk.domain.co.uk being detected as an internal link,
204
+ if we were checking for 'www.gov.uk' instead of 'www.gov.uk/' */
205
+ if (domain.substring(domain.length) !== '/') {
206
+ domain = domain + '/'
207
+ }
208
+
209
+ /* If the href doesn't end in a slash, we add one.
210
+ This fixes an edge case where the <a href> is exactly `https://www.gov.uk`
211
+ but these checks would only look for `https://www.gov.uk/` */
212
+ if (href.substring(href.length) !== '/') {
213
+ href = href + '/'
214
+ }
147
215
  var httpDomain = 'http://' + domain
148
216
  var httpsDomain = 'https://' + domain
149
217
  var schemaRelativeDomain = '//' + domain
@@ -153,6 +221,17 @@ window.GOVUK.analyticsGA4.analyticsModules = window.GOVUK.analyticsGA4.analytics
153
221
  this.stringStartsWith(href, schemaRelativeDomain)
154
222
  },
155
223
 
224
+ hrefPointsToDownloadPath: function (href) {
225
+ var result = false
226
+ for (var i = 0; i < this.internalDownloadPaths.length; i++) {
227
+ var internalDownloadPath = this.internalDownloadPaths[i]
228
+ if (href.indexOf(internalDownloadPath) !== -1) {
229
+ result = true
230
+ }
231
+ }
232
+ return result
233
+ },
234
+
156
235
  stringStartsWith: function (string, stringToFind) {
157
236
  return string.substring(0, stringToFind.length) === stringToFind
158
237
  },
@@ -164,6 +243,10 @@ window.GOVUK.analyticsGA4.analyticsModules = window.GOVUK.analyticsGA4.analytics
164
243
 
165
244
  hrefIsAnchor: function (href) {
166
245
  return href[0] === '#'
246
+ },
247
+
248
+ getHostname: function () {
249
+ return window.location.hostname
167
250
  }
168
251
  }
169
252
 
@@ -30,7 +30,10 @@
30
30
  _gid: 'usage',
31
31
  _gat: 'usage',
32
32
  'JS-Detection': 'usage',
33
- TLSversion: 'usage'
33
+ TLSversion: 'usage',
34
+ _ga_VBLT2V3FZR: 'usage', // gtag cookie used to persist the session state, integration
35
+ _ga_P1DGM6TVYF: 'usage', // staging
36
+ _ga_S5RQ7FTGVR: 'usage' // production
34
37
  }
35
38
 
36
39
  /*
@@ -2,6 +2,7 @@
2
2
  links ||= []
3
3
  title ||= false
4
4
  track_as_sharing ||= false
5
+ track_as_follow ||= false
5
6
  stacked ||= false
6
7
  columns ||= false
7
8
 
@@ -23,7 +24,7 @@
23
24
  <% end %>
24
25
 
25
26
  <ul class="gem-c-share-links__list">
26
- <% links.each do |link| %>
27
+ <% links.each_with_index do |link, index| %>
27
28
  <% link_text = capture do %>
28
29
  <span class="govuk-visually-hidden">
29
30
  <% if link[:hidden_text] %>
@@ -42,6 +43,26 @@
42
43
  'socialNetwork': link[:icon],
43
44
  'socialTarget': link[:href]
44
45
  }
46
+ ga4_link_data = {
47
+ 'event_name': 'share',
48
+ 'type': 'share this page',
49
+ 'index': index + 1,
50
+ 'index_total': links.length,
51
+ 'text': link[:icon],
52
+ 'link_method': 'populated-via-js'
53
+ }
54
+ end
55
+ if track_as_follow
56
+ ga4_link_data = {
57
+ 'event_name': 'navigation',
58
+ 'type': 'follow us',
59
+ 'index': index + 1,
60
+ 'index_total': links.length,
61
+ 'text': link[:text],
62
+ 'external': 'populated-via-js',
63
+ 'url': link[:href],
64
+ 'link_method': 'populated-via-js'
65
+ }
45
66
  end
46
67
  %>
47
68
  <%= link_to link[:href],
@@ -50,7 +71,8 @@
50
71
  data: {
51
72
  'track-category': 'social media',
52
73
  'track-action': link[:icon],
53
- 'track-options': track_options
74
+ 'track-options': track_options,
75
+ 'ga4-link': ga4_link_data
54
76
  },
55
77
  class: "govuk-link govuk-link--no-underline gem-c-share-links__link #{brand_helper.color_class}" do %>
56
78
  <span class="gem-c-share-links__link-icon">
@@ -45,7 +45,7 @@ examples:
45
45
  context:
46
46
  right_to_left: true
47
47
  track_as_sharing_links:
48
- description: Where the component is used to allow users to share content on social media, tracking can be added that uses [Social Interactions](https://developers.google.com/analytics/devguides/collection/analyticsjs/social-interactions). If this option is not included, it is assumed the component is simply linking to social media pages and the extra options are omitted from the tracking call.
48
+ description: Where the component is used to allow users to share content on social media, tracking can be added that uses [Social Interactions](https://developers.google.com/analytics/devguides/collection/analyticsjs/social-interactions) in UA. If this option is not included, it is assumed the component is simply linking to social media pages and the extra options are omitted from the tracking call in UA. In GA4, when this is set to true, a JSON is added to a data-attribute called data-ga4-link, which is detected by ga4-link-tracker.js and pushed to the dataLayer.
49
49
  data:
50
50
  track_as_sharing: true
51
51
  links: [
@@ -53,7 +53,28 @@ examples:
53
53
  href: 'share',
54
54
  text: 'Share on Facebook',
55
55
  icon: 'facebook'
56
- }
56
+ },
57
+ {
58
+ href: 'share',
59
+ text: 'Share on Twitter',
60
+ icon: 'twitter'
61
+ },
62
+ ]
63
+ track_as_follow_links:
64
+ description: Where the component is used to allow users to follow us on social media, tracking can be added. When this is set to true, a JSON is added to a data-attribute called data-ga4-link, which is detected by ga4-link-tracker.js and pushed to the dataLayer.
65
+ data:
66
+ track_as_follow: true
67
+ links: [
68
+ {
69
+ href: 'follow',
70
+ text: 'Follow us on Facebook',
71
+ icon: 'facebook'
72
+ },
73
+ {
74
+ href: 'follow',
75
+ text: 'Follow us on Twitter',
76
+ icon: 'twitter'
77
+ },
57
78
  ]
58
79
  with_title:
59
80
  data:
@@ -1,3 +1,3 @@
1
1
  module GovukPublishingComponents
2
- VERSION = "30.7.0".freeze
2
+ VERSION = "30.7.2".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk_publishing_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 30.7.0
4
+ version: 30.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-20 00:00:00.000000000 Z
11
+ date: 2022-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: govuk_app_config