govuk_frontend_toolkit 7.6.0 → 9.0.1

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/app/assets/.ruby-version +1 -1
  4. data/app/assets/CHANGELOG.md +37 -0
  5. data/app/assets/Gemfile +0 -1
  6. data/app/assets/Gruntfile.js +0 -3
  7. data/app/assets/README.md +7 -21
  8. data/app/assets/VERSION.txt +1 -1
  9. data/app/assets/docs/mixins.md +1 -1
  10. data/app/assets/javascripts/govuk/show-hide-content.js +1 -7
  11. data/app/assets/javascripts/stageprompt.js +7 -1
  12. data/app/assets/package-lock.json +2471 -0
  13. data/app/assets/spec/unit/show-hide-content.spec.js +57 -0
  14. data/app/assets/spec/unit/stageprompt.spec.js +170 -0
  15. data/app/assets/stylesheets/colours/_organisation.scss +1 -1
  16. data/govuk_frontend_toolkit.gemspec +0 -3
  17. data/publish.sh +1 -2
  18. metadata +5 -49
  19. data/Rakefile +0 -10
  20. data/app/assets/docs/analytics.md +0 -272
  21. data/app/assets/javascripts/govuk/analytics/analytics.js +0 -153
  22. data/app/assets/javascripts/govuk/analytics/download-link-tracker.js +0 -41
  23. data/app/assets/javascripts/govuk/analytics/error-tracking.js +0 -51
  24. data/app/assets/javascripts/govuk/analytics/external-link-tracker.js +0 -56
  25. data/app/assets/javascripts/govuk/analytics/google-analytics-universal-tracker.js +0 -176
  26. data/app/assets/javascripts/govuk/analytics/govuk-tracker.js +0 -134
  27. data/app/assets/javascripts/govuk/analytics/mailto-link-tracker.js +0 -38
  28. data/app/assets/javascripts/govuk/analytics/print-intent.js +0 -39
  29. data/app/assets/spec/unit/analytics/analytics.spec.js +0 -403
  30. data/app/assets/spec/unit/analytics/download-link-tracker.spec.js +0 -72
  31. data/app/assets/spec/unit/analytics/error-tracking.spec.js +0 -65
  32. data/app/assets/spec/unit/analytics/external-link-tracker.spec.js +0 -109
  33. data/app/assets/spec/unit/analytics/google-analytics-universal-tracker.spec.js +0 -187
  34. data/app/assets/spec/unit/analytics/govuk-tracker.spec.js +0 -171
  35. data/app/assets/spec/unit/analytics/mailto-link-tracker.spec.js +0 -62
@@ -1,65 +0,0 @@
1
- /* global describe it expect beforeEach afterEach spyOn */
2
-
3
- describe('GOVUK.analyticsPlugins.error', function () {
4
- 'use strict'
5
- var GOVUK = window.GOVUK
6
-
7
- GOVUK.analyticsPlugins.error({filenameMustMatch: /gov\.uk/})
8
-
9
- beforeEach(function () {
10
- GOVUK.analytics = {trackEvent: function () {}}
11
- spyOn(GOVUK.analytics, 'trackEvent')
12
- })
13
-
14
- afterEach(function () {
15
- delete GOVUK.analytics
16
- })
17
-
18
- it('sends errors to Google Analytics', function () {
19
- triggerError('https://www.gov.uk/filename.js', 2, 'Error message')
20
-
21
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
22
- 'JavaScript Error',
23
- 'Error message',
24
- { label: 'https://www.gov.uk/filename.js: 2', value: 1, nonInteraction: true })
25
- })
26
-
27
- it('tracks only errors with a matching or blank filename', function () {
28
- triggerError('http://www.gov.uk/somefile.js', 2, 'Error message')
29
- triggerError('', 2, 'In page error')
30
- triggerError('http://www.broken-external-plugin-site.com/horrible.js', 2, 'Error message')
31
-
32
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
33
- 'JavaScript Error',
34
- 'Error message',
35
- {
36
- label: 'http://www.gov.uk/somefile.js: 2',
37
- value: 1,
38
- nonInteraction: true })
39
-
40
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
41
- 'JavaScript Error',
42
- 'In page error',
43
- {
44
- label: ': 2',
45
- value: 1,
46
- nonInteraction: true })
47
-
48
- expect(GOVUK.analytics.trackEvent).not.toHaveBeenCalledWith(
49
- 'JavaScript Error',
50
- 'Error message',
51
- {
52
- label: 'http://www.broken-external-plugin-site.com/horrible.js: 2',
53
- value: 1,
54
- nonInteraction: true })
55
- })
56
-
57
- function triggerError (filename, lineno, message) {
58
- var event = document.createEvent('Event')
59
- event.initEvent('error', true, true)
60
- event.filename = filename
61
- event.lineno = lineno
62
- event.message = message
63
- window.dispatchEvent(event)
64
- }
65
- })
@@ -1,109 +0,0 @@
1
- /* global describe it expect beforeEach afterEach spyOn */
2
-
3
- var $ = window.jQuery
4
-
5
- describe('GOVUK.analyticsPlugins.externalLinkTracker', function () {
6
- 'use strict'
7
- var GOVUK = window.GOVUK
8
-
9
- var $links
10
-
11
- beforeEach(function () {
12
- $links = $(
13
- '<div class="external-links">' +
14
- '<a href="http://www.nationalarchives.gov.uk"> National Archives </a>' +
15
- '<a href="https://www.nationalarchives.gov.uk"></a>' +
16
- '<a href="https://www.nationalarchives.gov.uk/one.pdf">National Archives PDF</a>' +
17
- '<a href="https://www.nationalarchives.gov.uk/an/image/link.png"><img src="/img" /></a>' +
18
- '</div>' +
19
- '<div class="internal-links">' +
20
- '<a href="/some-path">Local link</a>' +
21
- '<a href="http://fake-hostname.com/some-path">Another local link</a>' +
22
- '</div>'
23
- )
24
-
25
- $('html').on('click', function (evt) { evt.preventDefault() })
26
- $('body').append($links)
27
- GOVUK.analytics = {
28
- trackEvent: function () {},
29
- setDimension: function () {}
30
- }
31
-
32
- spyOn(GOVUK.analyticsPlugins.externalLinkTracker, 'getHostname').and.returnValue('fake-hostname.com')
33
- })
34
-
35
- afterEach(function () {
36
- $('html').off()
37
- $('body').off()
38
- $links.remove()
39
- delete GOVUK.analytics
40
- })
41
-
42
- it('listens to click events on only external links', function () {
43
- GOVUK.analyticsPlugins.externalLinkTracker({externalLinkUploadCustomDimension: 36})
44
-
45
- spyOn(GOVUK.analytics, 'trackEvent')
46
-
47
- $('.external-links a').each(function () {
48
- $(this).trigger('click')
49
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalled()
50
- GOVUK.analytics.trackEvent.calls.reset()
51
- })
52
-
53
- $('.internal-links a').each(function () {
54
- $(this).trigger('click')
55
- expect(GOVUK.analytics.trackEvent).not.toHaveBeenCalled()
56
- GOVUK.analytics.trackEvent.calls.reset()
57
- })
58
- })
59
-
60
- it('listens to click events on elements within external links', function () {
61
- GOVUK.analyticsPlugins.externalLinkTracker({externalLinkUploadCustomDimension: 36})
62
-
63
- spyOn(GOVUK.analytics, 'trackEvent')
64
-
65
- $('.external-links a img').trigger('click')
66
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
67
- 'External Link Clicked', 'https://www.nationalarchives.gov.uk/an/image/link.png', {transport: 'beacon'})
68
- })
69
-
70
- it('tracks an external link\'s href and link text', function () {
71
- GOVUK.analyticsPlugins.externalLinkTracker({externalLinkUploadCustomDimension: 36})
72
-
73
- spyOn(GOVUK.analytics, 'trackEvent')
74
- $('.external-links a').trigger('click')
75
-
76
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
77
- 'External Link Clicked', 'http://www.nationalarchives.gov.uk', {transport: 'beacon', label: 'National Archives'})
78
-
79
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
80
- 'External Link Clicked', 'https://www.nationalarchives.gov.uk', {transport: 'beacon'})
81
-
82
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
83
- 'External Link Clicked', 'https://www.nationalarchives.gov.uk/one.pdf', {transport: 'beacon', label: 'National Archives PDF'})
84
- })
85
-
86
- it('duplicates the url info in a custom dimension to be used to join with a Google Analytics upload', function () {
87
- GOVUK.analyticsPlugins.externalLinkTracker({externalLinkUploadCustomDimension: 36})
88
-
89
- spyOn(GOVUK.analytics, 'setDimension')
90
- spyOn(GOVUK.analytics, 'trackEvent')
91
- $('.external-links a').trigger('click')
92
-
93
- expect(GOVUK.analytics.setDimension).toHaveBeenCalledWith(36, 'http://www.nationalarchives.gov.uk')
94
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
95
- 'External Link Clicked', 'http://www.nationalarchives.gov.uk', {transport: 'beacon', label: 'National Archives'})
96
- })
97
-
98
- it('does not duplicate the url info if a custom dimension is not provided', function () {
99
- GOVUK.analyticsPlugins.externalLinkTracker()
100
-
101
- spyOn(GOVUK.analytics, 'setDimension')
102
- spyOn(GOVUK.analytics, 'trackEvent')
103
- $('.external-links a').trigger('click')
104
-
105
- expect(GOVUK.analytics.setDimension).not.toHaveBeenCalled()
106
- expect(GOVUK.analytics.trackEvent).toHaveBeenCalledWith(
107
- 'External Link Clicked', 'http://www.nationalarchives.gov.uk', {transport: 'beacon', label: 'National Archives'})
108
- })
109
- })
@@ -1,187 +0,0 @@
1
- /* global describe it expect beforeEach spyOn jasmine */
2
-
3
- var $ = window.jQuery
4
-
5
- describe('GOVUK.GoogleAnalyticsUniversalTracker', function () {
6
- 'use strict'
7
- var GOVUK = window.GOVUK
8
-
9
- function addGoogleAnalyticsSpy () {
10
- window.ga = function () {}
11
- spyOn(window, 'ga')
12
- }
13
-
14
- var universal
15
- var setupArguments
16
-
17
- beforeEach(function () {
18
- addGoogleAnalyticsSpy()
19
-
20
- universal = new GOVUK.GoogleAnalyticsUniversalTracker('id', {
21
- cookieDomain: 'cookie-domain.com',
22
- siteSpeedSampleRate: 100
23
- })
24
- })
25
-
26
- it('can load the libraries needed to run universal Google Analytics', function () {
27
- delete window.ga
28
- $('[src="https://www.google-analytics.com/analytics.js"]').remove()
29
- GOVUK.GoogleAnalyticsUniversalTracker.load()
30
- expect($('script[async][src="https://www.google-analytics.com/analytics.js"]').length).toBe(1)
31
- expect(typeof window.ga).toBe('function')
32
-
33
- window.ga('send message')
34
- expect(window.ga.q[0]).toEqual(jasmine.any(Object))
35
- })
36
-
37
- describe('when created', function () {
38
- beforeEach(function () {
39
- setupArguments = window.ga.calls.allArgs()
40
- })
41
-
42
- it('configures a Google tracker using the provided profile ID and config', function () {
43
- expect(setupArguments[0]).toEqual(['create', 'id', {cookieDomain: 'cookie-domain.com', siteSpeedSampleRate: 100}])
44
- })
45
-
46
- it('anonymises the IP', function () {
47
- expect(setupArguments[1]).toEqual(['set', 'anonymizeIp', true])
48
- })
49
- })
50
-
51
- describe('when created (with legacy non-object syntax)', function () {
52
- beforeEach(function () {
53
- addGoogleAnalyticsSpy()
54
-
55
- universal = new GOVUK.GoogleAnalyticsUniversalTracker('id', 'cookie-domain.com')
56
- setupArguments = window.ga.calls.allArgs()
57
- })
58
-
59
- it('configures a Google tracker using the provided profile ID and cookie domain', function () {
60
- expect(setupArguments[0]).toEqual(['create', 'id', {cookieDomain: 'cookie-domain.com'}])
61
- })
62
- })
63
-
64
- describe('when pageviews are tracked', function () {
65
- it('sends them to Google Analytics', function () {
66
- universal.trackPageview()
67
- expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview'])
68
- })
69
-
70
- it('sends them to Google Analytics, forcing a new session', function () {
71
- universal.trackPageview(undefined, undefined, { sessionControl: 'start' })
72
- expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {sessionControl: 'start'}])
73
- })
74
-
75
- it('can track a virtual pageview', function () {
76
- universal.trackPageview('/nicholas-page')
77
- expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {page: '/nicholas-page'}])
78
- })
79
-
80
- it('can track a virtual pageview with a custom title', function () {
81
- universal.trackPageview('/nicholas-page', 'Nicholas Page')
82
- expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {page: '/nicholas-page', title: 'Nicholas Page'}])
83
- })
84
-
85
- it('can set the transport method on a pageview', function () {
86
- universal.trackPageview('/t', 'T', {transport: 'beacon'})
87
- expect(window.ga.calls.mostRecent().args).toEqual(['send', 'pageview', {page: '/t', title: 'T', transport: 'beacon'}])
88
- })
89
- })
90
-
91
- describe('when events are tracked', function () {
92
- function eventObjectFromSpy () {
93
- return window.ga.calls.mostRecent().args[1]
94
- }
95
-
96
- it('sends them to Google Analytics', function () {
97
- universal.trackEvent('category', 'action', {label: 'label'})
98
- expect(window.ga.calls.mostRecent().args).toEqual(
99
- ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action', eventLabel: 'label'}]
100
- )
101
- })
102
-
103
- it('tracks custom dimensions', function () {
104
- universal.trackEvent('category', 'action', {dimension29: 'Home'})
105
- expect(window.ga.calls.mostRecent().args).toEqual(
106
- ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action', dimension29: 'Home'}]
107
- )
108
- })
109
-
110
- it('the label is optional', function () {
111
- universal.trackEvent('category', 'action')
112
- expect(window.ga.calls.mostRecent().args).toEqual(
113
- ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action'}]
114
- )
115
- })
116
-
117
- it('only sends values if they are parseable as numbers', function () {
118
- universal.trackEvent('category', 'action', {label: 'label', value: '10'})
119
- expect(eventObjectFromSpy()['eventValue']).toEqual(10)
120
-
121
- universal.trackEvent('category', 'action', {label: 'label', value: 10})
122
- expect(eventObjectFromSpy()['eventValue']).toEqual(10)
123
-
124
- universal.trackEvent('category', 'action', {label: 'label', value: 'not a number'})
125
- expect(eventObjectFromSpy()['eventValue']).toEqual(undefined)
126
- })
127
-
128
- it('can mark an event as non interactive', function () {
129
- universal.trackEvent('category', 'action', {label: 'label', value: 0, nonInteraction: true})
130
- expect(window.ga.calls.mostRecent().args).toEqual(
131
- ['send', {
132
- hitType: 'event',
133
- eventCategory: 'category',
134
- eventAction: 'action',
135
- eventLabel: 'label',
136
- eventValue: 0,
137
- nonInteraction: 1
138
- }]
139
- )
140
- })
141
-
142
- it('sends the page if supplied', function () {
143
- universal.trackEvent('category', 'action', {page: '/path/to/page'})
144
- expect(window.ga.calls.mostRecent().args).toEqual(
145
- ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action', page: '/path/to/page'}]
146
- )
147
- })
148
-
149
- it('can set the transport method on an event', function () {
150
- universal.trackEvent('category', 'action', {transport: 'beacon'})
151
- expect(window.ga.calls.mostRecent().args).toEqual(
152
- ['send', {hitType: 'event', eventCategory: 'category', eventAction: 'action', transport: 'beacon'}]
153
- )
154
- })
155
- })
156
-
157
- describe('when social events are tracked', function () {
158
- it('sends them to Google Analytics', function () {
159
- universal.trackSocial('network', 'action', 'target')
160
- expect(window.ga.calls.mostRecent().args).toEqual(['send', {
161
- 'hitType': 'social',
162
- 'socialNetwork': 'network',
163
- 'socialAction': 'action',
164
- 'socialTarget': 'target'
165
- }])
166
- })
167
- })
168
-
169
- describe('when setting a custom dimension', function () {
170
- it('sends the dimension to Google Analytics with the specified index and value', function () {
171
- universal.setDimension(1, 'value')
172
- expect(window.ga.calls.mostRecent().args).toEqual(['set', 'dimension1', 'value'])
173
- })
174
-
175
- it('coerces the value to a string', function () {
176
- universal.setDimension(1, 10)
177
- expect(window.ga.calls.mostRecent().args).toEqual(['set', 'dimension1', '10'])
178
- })
179
- })
180
-
181
- describe('when tracking all events', function () {
182
- window.history.replaceState(null, null, '?address=an.email@digital.cabinet-office.gov.uk')
183
- it('removes any email address from the location', function () {
184
- expect(window.ga.calls.mostRecent().args[2]).toContain('address=[email]')
185
- })
186
- })
187
- })
@@ -1,171 +0,0 @@
1
- /* global describe it expect beforeEach spyOn jasmine */
2
-
3
- var $ = window.jQuery
4
-
5
- describe('GOVUK.GOVUKTracker', function () {
6
- 'use strict'
7
- var GOVUK = window.GOVUK
8
-
9
- var tracker
10
-
11
- function setupFakeGa (clientId) {
12
- window.ga = function (cb) {
13
- cb({
14
- get: function () { return clientId }
15
- })
16
- }
17
- }
18
-
19
- beforeEach(function () {
20
- tracker = new GOVUK.GOVUKTracker('http://www.example.com/a.gif')
21
- })
22
-
23
- describe('sendData', function () {
24
- it('sends the data using AJAX', function () {
25
- spyOn($, 'get')
26
-
27
- tracker.sendData({foo: 'bar'})
28
- expect($.get).toHaveBeenCalledWith('http://www.example.com/a.gif?foo=bar')
29
- })
30
- })
31
-
32
- describe('payloadParams', function () {
33
- it('adds the event type', function () {
34
- var params = tracker.payloadParams('foo', {bar: 'qux'})
35
-
36
- expect(params.eventType).toEqual('foo')
37
- expect(params.bar).toEqual('qux')
38
- })
39
-
40
- it('adds the GA Client ID', function () {
41
- tracker.gaClientId = '123456.789012'
42
- var params = tracker.payloadParams('foo')
43
-
44
- expect(params.gaClientId).toEqual('123456.789012')
45
- })
46
-
47
- it('adds the referrer', function () {
48
- var params = tracker.payloadParams('foo')
49
-
50
- // Can't stub window.referrer so just test that we got a string, not undefined
51
- expect(typeof params.referrer).toEqual('string')
52
- })
53
-
54
- it('adds performance data', function () {
55
- var params = tracker.payloadParams('foo')
56
-
57
- expect(params.navigationType).toEqual('0')
58
- expect(params.redirectCount).toEqual('0')
59
-
60
- expect(params.timing_domComplete).toEqual(window.performance.timing.domComplete.toString())
61
- })
62
-
63
- it('adds custom dimensions', function () {
64
- tracker.setDimension(1, 'foo')
65
- tracker.setDimension(10, 'bar')
66
- var params = tracker.payloadParams('foo')
67
-
68
- expect(params.dimension1).toEqual('foo')
69
- expect(params.dimension10).toEqual('bar')
70
- })
71
-
72
- it('adds screen and window measurements', function () {
73
- var params = tracker.payloadParams('foo')
74
-
75
- expect(params.screenWidth).toEqual(window.screen.width)
76
- expect(params.screenHeight).toEqual(window.screen.height)
77
- expect(params.windowWidth).toEqual(window.innerWidth)
78
- expect(params.windowHeight).toEqual(window.innerHeight)
79
- expect(params.colorDepth).toEqual(window.screen.colorDepth)
80
- })
81
- })
82
-
83
- describe('sendToTracker', function () {
84
- it('sends when the DOM is complete', function () {
85
- setupFakeGa('123456.789012')
86
-
87
- spyOn(tracker, 'sendData')
88
- tracker.sendToTracker('foo')
89
-
90
- expect(tracker.sendData).toHaveBeenCalledWith(jasmine.any(Object))
91
- })
92
-
93
- it('sets the ga Client ID', function () {
94
- setupFakeGa('123456.789012')
95
-
96
- spyOn(tracker, 'sendData')
97
- tracker.sendToTracker('foo')
98
-
99
- expect(tracker.gaClientId).toEqual('123456.789012')
100
- })
101
- })
102
-
103
- describe('tracking', function () {
104
- beforeEach(function () {
105
- spyOn(tracker, 'sendToTracker')
106
- })
107
-
108
- describe('when pageviews are tracked', function () {
109
- it('sends them to the tracker', function () {
110
- tracker.trackPageview()
111
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual(['pageview'])
112
- })
113
- })
114
-
115
- describe('when events are tracked', function () {
116
- it('sends them to the tracker', function () {
117
- tracker.trackEvent('category', 'action', {label: 'label'})
118
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual(
119
- ['event', {eventCategory: 'category', eventAction: 'action', eventLabel: 'label'}]
120
- )
121
- })
122
-
123
- it('tracks custom dimensions', function () {
124
- tracker.trackEvent('category', 'action', {dimension29: 'Home'})
125
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual(
126
- ['event', {eventCategory: 'category', eventAction: 'action', dimension29: 'Home'}]
127
- )
128
- })
129
-
130
- it('the label is optional', function () {
131
- tracker.trackEvent('category', 'action')
132
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual(
133
- ['event', {eventCategory: 'category', eventAction: 'action'}]
134
- )
135
- })
136
-
137
- it('sends the page if supplied', function () {
138
- tracker.trackEvent('category', 'action', {page: '/path/to/page'})
139
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual(
140
- ['event', {eventCategory: 'category', eventAction: 'action', page: '/path/to/page'}]
141
- )
142
- })
143
-
144
- it('tracks multiple events', function () {
145
- tracker.trackEvent('category', 'action', {label: 'foo'})
146
- tracker.trackEvent('category', 'action', {label: 'bar'})
147
-
148
- expect(tracker.sendToTracker).toHaveBeenCalledWith(
149
- 'event', {eventCategory: 'category', eventAction: 'action', eventLabel: 'foo'}
150
- )
151
- expect(tracker.sendToTracker).toHaveBeenCalledWith(
152
- 'event', {eventCategory: 'category', eventAction: 'action', eventLabel: 'bar'}
153
- )
154
- })
155
- })
156
-
157
- describe('when social events are tracked', function () {
158
- it('sends them to Google Analytics', function () {
159
- tracker.trackSocial('network', 'action', 'target')
160
- expect(tracker.sendToTracker.calls.mostRecent().args).toEqual([
161
- 'social',
162
- {
163
- 'socialNetwork': 'network',
164
- 'socialAction': 'action',
165
- 'socialTarget': 'target'
166
- }
167
- ])
168
- })
169
- })
170
- })
171
- })