idsk_frontend_toolkit 7.4.2

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 (227) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.gitmodules +3 -0
  4. data/.ruby-version +1 -0
  5. data/.travis/govuk_frontend_toolkit_gem_push.enc +0 -0
  6. data/.travis/govuk_frontend_toolkit_gem_push.pub +1 -0
  7. data/.travis.yml +23 -0
  8. data/CONTRIBUTING.md +13 -0
  9. data/Gemfile +3 -0
  10. data/LICENCE +20 -0
  11. data/README.md +61 -0
  12. data/Rakefile +10 -0
  13. data/app/assets/.gitignore +5 -0
  14. data/app/assets/.ruby-version +1 -0
  15. data/app/assets/.travis/README.md +23 -0
  16. data/app/assets/.travis/govuk_frontend_toolkit_push.enc +0 -0
  17. data/app/assets/.travis/govuk_frontend_toolkit_push.pub +1 -0
  18. data/app/assets/.travis.yml +18 -0
  19. data/app/assets/CHANGELOG.md +381 -0
  20. data/app/assets/CONTRIBUTING.md +23 -0
  21. data/app/assets/Gemfile +4 -0
  22. data/app/assets/Gemfile.lock +48 -0
  23. data/app/assets/Gruntfile.js +68 -0
  24. data/app/assets/LICENCE +20 -0
  25. data/app/assets/README.md +170 -0
  26. data/app/assets/VERSION.txt +1 -0
  27. data/app/assets/create-release.sh +38 -0
  28. data/app/assets/docs/analytics.md +270 -0
  29. data/app/assets/docs/functions.md +62 -0
  30. data/app/assets/docs/javascript.md +337 -0
  31. data/app/assets/docs/mixins.md +617 -0
  32. data/app/assets/images/accordion-arrow-2x.png +0 -0
  33. data/app/assets/images/accordion-arrow.png +0 -0
  34. data/app/assets/images/arrow-sprite.png +0 -0
  35. data/app/assets/images/crests/bis_crest_13px.png +0 -0
  36. data/app/assets/images/crests/bis_crest_13px_x2.png +0 -0
  37. data/app/assets/images/crests/bis_crest_18px.png +0 -0
  38. data/app/assets/images/crests/bis_crest_18px_x2.png +0 -0
  39. data/app/assets/images/crests/bis_crest_27px.png +0 -0
  40. data/app/assets/images/crests/bis_crest_27px_x2.png +0 -0
  41. data/app/assets/images/crests/coastguard_13px.png +0 -0
  42. data/app/assets/images/crests/coastguard_13px_x2.png +0 -0
  43. data/app/assets/images/crests/coastguard_18px.png +0 -0
  44. data/app/assets/images/crests/coastguard_18px_x2.png +0 -0
  45. data/app/assets/images/crests/coastguard_27px.png +0 -0
  46. data/app/assets/images/crests/coastguard_27px_x2.png +0 -0
  47. data/app/assets/images/crests/dit_crest_13px.png +0 -0
  48. data/app/assets/images/crests/dit_crest_13px_x2.png +0 -0
  49. data/app/assets/images/crests/dit_crest_18px.png +0 -0
  50. data/app/assets/images/crests/dit_crest_18px_x2.png +0 -0
  51. data/app/assets/images/crests/dit_crest_27px.png +0 -0
  52. data/app/assets/images/crests/dit_crest_27px_x2.png +0 -0
  53. data/app/assets/images/crests/hmrc_crest_13px.png +0 -0
  54. data/app/assets/images/crests/hmrc_crest_13px_x2.png +0 -0
  55. data/app/assets/images/crests/hmrc_crest_18px.png +0 -0
  56. data/app/assets/images/crests/hmrc_crest_18px_x2.png +0 -0
  57. data/app/assets/images/crests/hmrc_crest_27px.png +0 -0
  58. data/app/assets/images/crests/hmrc_crest_27px_x2.png +0 -0
  59. data/app/assets/images/crests/ho_crest_13px.png +0 -0
  60. data/app/assets/images/crests/ho_crest_13px_x2.png +0 -0
  61. data/app/assets/images/crests/ho_crest_18px.png +0 -0
  62. data/app/assets/images/crests/ho_crest_18px_x2.png +0 -0
  63. data/app/assets/images/crests/ho_crest_27px.png +0 -0
  64. data/app/assets/images/crests/ho_crest_27px_x2.png +0 -0
  65. data/app/assets/images/crests/mod_crest_13px.png +0 -0
  66. data/app/assets/images/crests/mod_crest_13px_x2.png +0 -0
  67. data/app/assets/images/crests/mod_crest_18px.png +0 -0
  68. data/app/assets/images/crests/mod_crest_18px_x2.png +0 -0
  69. data/app/assets/images/crests/mod_crest_27px.png +0 -0
  70. data/app/assets/images/crests/mod_crest_27px_x2.png +0 -0
  71. data/app/assets/images/crests/org_crest_13px.png +0 -0
  72. data/app/assets/images/crests/org_crest_13px_x2.png +0 -0
  73. data/app/assets/images/crests/org_crest_18px.png +0 -0
  74. data/app/assets/images/crests/org_crest_18px_x2.png +0 -0
  75. data/app/assets/images/crests/org_crest_27px.png +0 -0
  76. data/app/assets/images/crests/org_crest_27px_x2.png +0 -0
  77. data/app/assets/images/crests/portcullis_13px.png +0 -0
  78. data/app/assets/images/crests/portcullis_13px_x2.png +0 -0
  79. data/app/assets/images/crests/portcullis_18px.png +0 -0
  80. data/app/assets/images/crests/portcullis_18px_x2.png +0 -0
  81. data/app/assets/images/crests/portcullis_27px.png +0 -0
  82. data/app/assets/images/crests/portcullis_27px_x2.png +0 -0
  83. data/app/assets/images/crests/so_crest_13px.png +0 -0
  84. data/app/assets/images/crests/so_crest_13px_x2.png +0 -0
  85. data/app/assets/images/crests/so_crest_18px.png +0 -0
  86. data/app/assets/images/crests/so_crest_18px_x2.png +0 -0
  87. data/app/assets/images/crests/so_crest_27px.png +0 -0
  88. data/app/assets/images/crests/so_crest_27px_x2.png +0 -0
  89. data/app/assets/images/crests/ukaea_crest_13px.png +0 -0
  90. data/app/assets/images/crests/ukaea_crest_13px_x2.png +0 -0
  91. data/app/assets/images/crests/ukaea_crest_18px.png +0 -0
  92. data/app/assets/images/crests/ukaea_crest_18px_x2.png +0 -0
  93. data/app/assets/images/crests/ukaea_crest_27px.png +0 -0
  94. data/app/assets/images/crests/ukaea_crest_27px_x2.png +0 -0
  95. data/app/assets/images/crests/ukho_13px.png +0 -0
  96. data/app/assets/images/crests/ukho_13px_x2.png +0 -0
  97. data/app/assets/images/crests/ukho_18px.png +0 -0
  98. data/app/assets/images/crests/ukho_18px_x2.png +0 -0
  99. data/app/assets/images/crests/ukho_27px.png +0 -0
  100. data/app/assets/images/crests/ukho_27px_x2.png +0 -0
  101. data/app/assets/images/crests/wales_crest_13px.png +0 -0
  102. data/app/assets/images/crests/wales_crest_13px_x2.png +0 -0
  103. data/app/assets/images/crests/wales_crest_18px.png +0 -0
  104. data/app/assets/images/crests/wales_crest_18px_x2.png +0 -0
  105. data/app/assets/images/crests/wales_crest_27px.png +0 -0
  106. data/app/assets/images/crests/wales_crest_27px_x2.png +0 -0
  107. data/app/assets/images/icon-arrow-left.png +0 -0
  108. data/app/assets/images/icon-calendar-2x.png +0 -0
  109. data/app/assets/images/icon-calendar.png +0 -0
  110. data/app/assets/images/icon-file-download-2x.png +0 -0
  111. data/app/assets/images/icon-file-download.png +0 -0
  112. data/app/assets/images/icon-important-2x.png +0 -0
  113. data/app/assets/images/icon-important.png +0 -0
  114. data/app/assets/images/icon-information-2x.png +0 -0
  115. data/app/assets/images/icon-information.png +0 -0
  116. data/app/assets/images/icon-locator-2x.png +0 -0
  117. data/app/assets/images/icon-locator.png +0 -0
  118. data/app/assets/images/icon-pointer-2x.png +0 -0
  119. data/app/assets/images/icon-pointer-black-2x.png +0 -0
  120. data/app/assets/images/icon-pointer-black.png +0 -0
  121. data/app/assets/images/icon-pointer-indexed.png +0 -0
  122. data/app/assets/images/icon-pointer.png +0 -0
  123. data/app/assets/images/icon-search-2x.png +0 -0
  124. data/app/assets/images/icon-search.png +0 -0
  125. data/app/assets/images/icon-steps/icon-step-1-2x.png +0 -0
  126. data/app/assets/images/icon-steps/icon-step-1.png +0 -0
  127. data/app/assets/images/icon-steps/icon-step-10-2x.png +0 -0
  128. data/app/assets/images/icon-steps/icon-step-10.png +0 -0
  129. data/app/assets/images/icon-steps/icon-step-11-2x.png +0 -0
  130. data/app/assets/images/icon-steps/icon-step-11.png +0 -0
  131. data/app/assets/images/icon-steps/icon-step-12-2x.png +0 -0
  132. data/app/assets/images/icon-steps/icon-step-12.png +0 -0
  133. data/app/assets/images/icon-steps/icon-step-13-2x.png +0 -0
  134. data/app/assets/images/icon-steps/icon-step-13.png +0 -0
  135. data/app/assets/images/icon-steps/icon-step-14-2x.png +0 -0
  136. data/app/assets/images/icon-steps/icon-step-14.png +0 -0
  137. data/app/assets/images/icon-steps/icon-step-2-2x.png +0 -0
  138. data/app/assets/images/icon-steps/icon-step-2.png +0 -0
  139. data/app/assets/images/icon-steps/icon-step-3-2x.png +0 -0
  140. data/app/assets/images/icon-steps/icon-step-3.png +0 -0
  141. data/app/assets/images/icon-steps/icon-step-4-2x.png +0 -0
  142. data/app/assets/images/icon-steps/icon-step-4.png +0 -0
  143. data/app/assets/images/icon-steps/icon-step-5-2x.png +0 -0
  144. data/app/assets/images/icon-steps/icon-step-5.png +0 -0
  145. data/app/assets/images/icon-steps/icon-step-6-2x.png +0 -0
  146. data/app/assets/images/icon-steps/icon-step-6.png +0 -0
  147. data/app/assets/images/icon-steps/icon-step-7-2x.png +0 -0
  148. data/app/assets/images/icon-steps/icon-step-7.png +0 -0
  149. data/app/assets/images/icon-steps/icon-step-8-2x.png +0 -0
  150. data/app/assets/images/icon-steps/icon-step-8.png +0 -0
  151. data/app/assets/images/icon-steps/icon-step-9-2x.png +0 -0
  152. data/app/assets/images/icon-steps/icon-step-9.png +0 -0
  153. data/app/assets/images/player-icon-forward.png +0 -0
  154. data/app/assets/images/player-icon-pause.png +0 -0
  155. data/app/assets/images/player-icon-play.png +0 -0
  156. data/app/assets/images/player-icon-rewind.png +0 -0
  157. data/app/assets/images/player-icon-volume.png +0 -0
  158. data/app/assets/images/separator-2x.png +0 -0
  159. data/app/assets/images/separator.png +0 -0
  160. data/app/assets/javascripts/govuk/analytics/analytics.js +143 -0
  161. data/app/assets/javascripts/govuk/analytics/download-link-tracker.js +41 -0
  162. data/app/assets/javascripts/govuk/analytics/error-tracking.js +51 -0
  163. data/app/assets/javascripts/govuk/analytics/external-link-tracker.js +56 -0
  164. data/app/assets/javascripts/govuk/analytics/google-analytics-universal-tracker.js +166 -0
  165. data/app/assets/javascripts/govuk/analytics/govuk-tracker.js +134 -0
  166. data/app/assets/javascripts/govuk/analytics/mailto-link-tracker.js +38 -0
  167. data/app/assets/javascripts/govuk/analytics/print-intent.js +39 -0
  168. data/app/assets/javascripts/govuk/details.polyfill.js +240 -0
  169. data/app/assets/javascripts/govuk/modules/auto-track-event.js +30 -0
  170. data/app/assets/javascripts/govuk/modules.js +61 -0
  171. data/app/assets/javascripts/govuk/primary-links.js +57 -0
  172. data/app/assets/javascripts/govuk/selection-buttons.js +116 -0
  173. data/app/assets/javascripts/govuk/shim-links-with-button-role.js +34 -0
  174. data/app/assets/javascripts/govuk/show-hide-content.js +172 -0
  175. data/app/assets/javascripts/govuk/stick-at-top-when-scrolling.js +128 -0
  176. data/app/assets/javascripts/govuk/stop-scrolling-at-footer.js +139 -0
  177. data/app/assets/javascripts/govuk_toolkit.js +1 -0
  178. data/app/assets/javascripts/stageprompt.js +69 -0
  179. data/app/assets/javascripts/vendor/jquery/jquery.player.min.js +25 -0
  180. data/app/assets/javascripts/vendor/polyfills/bind.js +40 -0
  181. data/app/assets/package.json +25 -0
  182. data/app/assets/spec/manifest.js +41 -0
  183. data/app/assets/spec/stylesheets/_colour_contrast_spec.scss +12 -0
  184. data/app/assets/spec/support/LocalTestRunner.html +21 -0
  185. data/app/assets/spec/support/console-runner.js +102 -0
  186. data/app/assets/spec/support/load.js +47 -0
  187. data/app/assets/spec/support/run_jasmine_test.js +62 -0
  188. data/app/assets/spec/unit/analytics/analytics.spec.js +315 -0
  189. data/app/assets/spec/unit/analytics/download-link-tracker.spec.js +72 -0
  190. data/app/assets/spec/unit/analytics/error-tracking.spec.js +65 -0
  191. data/app/assets/spec/unit/analytics/external-link-tracker.spec.js +109 -0
  192. data/app/assets/spec/unit/analytics/google-analytics-universal-tracker.spec.js +180 -0
  193. data/app/assets/spec/unit/analytics/govuk-tracker.spec.js +171 -0
  194. data/app/assets/spec/unit/analytics/mailto-link-tracker.spec.js +62 -0
  195. data/app/assets/spec/unit/details.polyfill.spec.js +91 -0
  196. data/app/assets/spec/unit/modules/auto-track-event.spec.js +54 -0
  197. data/app/assets/spec/unit/modules.spec.js +93 -0
  198. data/app/assets/spec/unit/primary-links.spec.js +55 -0
  199. data/app/assets/spec/unit/selection-button.spec.js +761 -0
  200. data/app/assets/spec/unit/shim-links-with-button-role.spec.js +41 -0
  201. data/app/assets/spec/unit/show-hide-content.spec.js +306 -0
  202. data/app/assets/spec/unit/stick-at-top-when-scrolling.spec.js +137 -0
  203. data/app/assets/stylesheets/.gitkeep +0 -0
  204. data/app/assets/stylesheets/_colours.scss +2 -0
  205. data/app/assets/stylesheets/_conditionals.scss +81 -0
  206. data/app/assets/stylesheets/_css3.scss +90 -0
  207. data/app/assets/stylesheets/_device-pixels.scss +10 -0
  208. data/app/assets/stylesheets/_font_stack.scss +25 -0
  209. data/app/assets/stylesheets/_grid_layout.scss +136 -0
  210. data/app/assets/stylesheets/_helpers.scss +16 -0
  211. data/app/assets/stylesheets/_measurements.scss +14 -0
  212. data/app/assets/stylesheets/_shims.scss +55 -0
  213. data/app/assets/stylesheets/_typography.scss +249 -0
  214. data/app/assets/stylesheets/_url-helpers.scss +16 -0
  215. data/app/assets/stylesheets/colours/_organisation.scss +104 -0
  216. data/app/assets/stylesheets/colours/_palette.scss +77 -0
  217. data/app/assets/stylesheets/design-patterns/_alpha-beta.scss +67 -0
  218. data/app/assets/stylesheets/design-patterns/_breadcrumbs.scss +53 -0
  219. data/app/assets/stylesheets/design-patterns/_buttons.scss +145 -0
  220. data/app/assets/stylesheets/design-patterns/_media-player.scss +264 -0
  221. data/app/assets/trigger.sh +24 -0
  222. data/idsk_frontend_toolkit.gemspec +49 -0
  223. data/lib/idsk_frontend_toolkit/engine.rb +4 -0
  224. data/lib/idsk_frontend_toolkit/version.rb +5 -0
  225. data/lib/idsk_frontend_toolkit.rb +4 -0
  226. data/publish.sh +30 -0
  227. metadata +314 -0
@@ -0,0 +1,166 @@
1
+ ;(function (global) {
2
+ 'use strict'
3
+
4
+ var $ = global.jQuery
5
+ var GOVUK = global.GOVUK || {}
6
+
7
+ var GoogleAnalyticsUniversalTracker = function (trackingId, fieldsObject) {
8
+ function configureProfile () {
9
+ // https://developers.google.com/analytics/devguides/collection/analyticsjs/command-queue-reference#create
10
+ sendToGa('create', trackingId, fieldsObject)
11
+ }
12
+
13
+ function anonymizeIp () {
14
+ // https://developers.google.com/analytics/devguides/collection/analyticsjs/advanced#anonymizeip
15
+ sendToGa('set', 'anonymizeIp', true)
16
+ }
17
+
18
+ function disableAdTracking () {
19
+ // https://support.google.com/analytics/answer/2444872?hl=en
20
+ sendToGa('set', 'displayFeaturesTask', null)
21
+ }
22
+
23
+ // Support legacy cookieDomain param
24
+ if (typeof fieldsObject === 'string') {
25
+ fieldsObject = { cookieDomain: fieldsObject }
26
+ }
27
+
28
+ configureProfile()
29
+ anonymizeIp()
30
+ disableAdTracking()
31
+ }
32
+
33
+ GoogleAnalyticsUniversalTracker.load = function () {
34
+ /* eslint-disable */
35
+ (function (i, s, o, g, r, a, m) { i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
36
+ (i[r].q = i[r].q || []).push(arguments) }, i[r].l = 1 * new Date(); a = s.createElement(o),
37
+ m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
38
+ })(global, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga')
39
+ /* eslint-enable */
40
+ }
41
+
42
+ // https://developers.google.com/analytics/devguides/collection/analyticsjs/pages
43
+ GoogleAnalyticsUniversalTracker.prototype.trackPageview = function (path, title, options) {
44
+ var pageviewObject
45
+
46
+ if (typeof path === 'string') {
47
+ pageviewObject = { page: path }
48
+ }
49
+
50
+ if (typeof title === 'string') {
51
+ pageviewObject = pageviewObject || {}
52
+ pageviewObject.title = title
53
+ }
54
+
55
+ // Set an options object for the pageview (e.g. transport, sessionControl)
56
+ // https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#transport
57
+ if (typeof options === 'object') {
58
+ pageviewObject = $.extend(pageviewObject || {}, options)
59
+ }
60
+
61
+ if (!$.isEmptyObject(pageviewObject)) {
62
+ sendToGa('send', 'pageview', pageviewObject)
63
+ } else {
64
+ sendToGa('send', 'pageview')
65
+ }
66
+ }
67
+
68
+ // https://developers.google.com/analytics/devguides/collection/analyticsjs/events
69
+ GoogleAnalyticsUniversalTracker.prototype.trackEvent = function (category, action, options) {
70
+ options = options || {}
71
+ var value
72
+ var evt = {
73
+ hitType: 'event',
74
+ eventCategory: category,
75
+ eventAction: action
76
+ }
77
+
78
+ // Label is optional
79
+ if (typeof options.label === 'string') {
80
+ evt.eventLabel = options.label
81
+ delete options.label
82
+ }
83
+
84
+ // Value is optional, but when used must be an
85
+ // integer, otherwise the event will be invalid
86
+ // and not logged
87
+ if (options.value || options.value === 0) {
88
+ value = parseInt(options.value, 10)
89
+ if (typeof value === 'number' && !isNaN(value)) {
90
+ options.eventValue = value
91
+ }
92
+ delete options.value
93
+ }
94
+
95
+ // Prevents an event from affecting bounce rate
96
+ // https://developers.google.com/analytics/devguides/collection/analyticsjs/events#implementation
97
+ if (options.nonInteraction) {
98
+ options.nonInteraction = 1
99
+ }
100
+
101
+ if (typeof options === 'object') {
102
+ $.extend(evt, options)
103
+ }
104
+
105
+ sendToGa('send', evt)
106
+ }
107
+
108
+ /*
109
+ https://developers.google.com/analytics/devguides/collection/analyticsjs/social-interactions
110
+ network – The network on which the action occurs (e.g. Facebook, Twitter)
111
+ action – The type of action that happens (e.g. Like, Send, Tweet)
112
+ target – Specifies the target of a social interaction.
113
+ This value is typically a URL but can be any text.
114
+ */
115
+ GoogleAnalyticsUniversalTracker.prototype.trackSocial = function (network, action, target, options) {
116
+ var trackingOptions = {
117
+ 'hitType': 'social',
118
+ 'socialNetwork': network,
119
+ 'socialAction': action,
120
+ 'socialTarget': target
121
+ }
122
+
123
+ $.extend(trackingOptions, options)
124
+
125
+ sendToGa('send', trackingOptions)
126
+ }
127
+
128
+ /*
129
+ https://developers.google.com/analytics/devguides/collection/analyticsjs/cross-domain
130
+ trackerId - the UA account code to track the domain against
131
+ name - name for the tracker
132
+ domain - the domain to track
133
+ */
134
+ GoogleAnalyticsUniversalTracker.prototype.addLinkedTrackerDomain = function (trackerId, name, domain) {
135
+ sendToGa('create',
136
+ trackerId,
137
+ 'auto',
138
+ {'name': name})
139
+ // Load the plugin.
140
+ sendToGa('require', 'linker')
141
+ sendToGa(name + '.require', 'linker')
142
+
143
+ // Define which domains to autoLink.
144
+ sendToGa('linker:autoLink', [domain])
145
+ sendToGa(name + '.linker:autoLink', [domain])
146
+
147
+ sendToGa(name + '.set', 'anonymizeIp', true)
148
+ sendToGa(name + '.set', 'displayFeaturesTask', null)
149
+ sendToGa(name + '.send', 'pageview')
150
+ }
151
+
152
+ // https://developers.google.com/analytics/devguides/collection/analyticsjs/custom-dims-mets
153
+ GoogleAnalyticsUniversalTracker.prototype.setDimension = function (index, value) {
154
+ sendToGa('set', 'dimension' + index, String(value))
155
+ }
156
+
157
+ function sendToGa () {
158
+ if (typeof global.ga === 'function') {
159
+ global.ga.apply(global, arguments)
160
+ }
161
+ }
162
+
163
+ GOVUK.GoogleAnalyticsUniversalTracker = GoogleAnalyticsUniversalTracker
164
+
165
+ global.GOVUK = GOVUK
166
+ })(window)
@@ -0,0 +1,134 @@
1
+ ;(function (global) {
2
+ 'use strict'
3
+
4
+ var $ = global.jQuery
5
+ var GOVUK = global.GOVUK || {}
6
+
7
+ var GOVUKTracker = function (gifUrl) {
8
+ this.gifUrl = gifUrl
9
+ this.dimensions = []
10
+ }
11
+
12
+ GOVUKTracker.load = function () {}
13
+
14
+ GOVUKTracker.prototype.trackPageview = function (path, title, options) {
15
+ var pageviewObject
16
+
17
+ if (typeof path === 'string') {
18
+ pageviewObject = { page: path }
19
+ }
20
+
21
+ if (typeof title === 'string') {
22
+ pageviewObject = pageviewObject || {}
23
+ pageviewObject.title = title
24
+ }
25
+
26
+ // Set an options object for the pageview (e.g. transport, sessionControl)
27
+ // https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#transport
28
+ if (typeof options === 'object') {
29
+ pageviewObject = $.extend(pageviewObject || {}, options)
30
+ }
31
+
32
+ if (!$.isEmptyObject(pageviewObject)) {
33
+ this.sendToTracker('pageview', pageviewObject)
34
+ } else {
35
+ this.sendToTracker('pageview')
36
+ }
37
+ }
38
+
39
+ // https://developers.google.com/analytics/devguides/collection/analyticsjs/events
40
+ GOVUKTracker.prototype.trackEvent = function (category, action, options) {
41
+ options = options || {}
42
+ var evt = {
43
+ eventCategory: category,
44
+ eventAction: action
45
+ }
46
+
47
+ if (options.label) {
48
+ evt.eventLabel = options.label
49
+ delete options.label
50
+ }
51
+
52
+ if (options.value) {
53
+ evt.eventValue = options.value.toString()
54
+ delete options.value
55
+ }
56
+
57
+ if (typeof options === 'object') {
58
+ $.extend(evt, options)
59
+ }
60
+
61
+ this.sendToTracker('event', evt)
62
+ }
63
+
64
+ GOVUKTracker.prototype.trackSocial = function (network, action, target, options) {
65
+ var trackingOptions = {
66
+ 'socialNetwork': network,
67
+ 'socialAction': action,
68
+ 'socialTarget': target
69
+ }
70
+
71
+ $.extend(trackingOptions, options)
72
+
73
+ this.sendToTracker('social', trackingOptions)
74
+ }
75
+
76
+ GOVUKTracker.prototype.addLinkedTrackerDomain = function () { /* noop */ }
77
+
78
+ GOVUKTracker.prototype.setDimension = function (index, value) {
79
+ this.dimensions['dimension' + index] = value
80
+ }
81
+
82
+ GOVUKTracker.prototype.payloadParams = function (type, payload) {
83
+ var data = $.extend({},
84
+ payload,
85
+ this.dimensions,
86
+ {
87
+ eventType: type,
88
+ referrer: global.document.referrer,
89
+ gaClientId: this.gaClientId,
90
+ windowWidth: global.innerWidth,
91
+ windowHeight: global.innerHeight,
92
+ screenWidth: global.screen.width,
93
+ screenHeight: global.screen.height,
94
+ colorDepth: global.screen.colorDepth
95
+ }
96
+ )
97
+
98
+ if (global.performance) {
99
+ data.navigationType = global.performance.navigation.type.toString()
100
+ data.redirectCount = global.performance.navigation.redirectCount.toString()
101
+
102
+ for (var k in global.performance.timing) {
103
+ var v = global.performance.timing[k]
104
+ if (typeof v === 'string' || typeof v === 'number') {
105
+ data['timing_' + k] = v.toString()
106
+ }
107
+ }
108
+ }
109
+
110
+ return data
111
+ }
112
+
113
+ GOVUKTracker.prototype.sendData = function (params) {
114
+ var url = this.gifUrl + '?' + $.param(params)
115
+ $.get(url)
116
+ }
117
+
118
+ GOVUKTracker.prototype.sendToTracker = function (type, payload) {
119
+ $(global.document).ready(function () {
120
+ if (global.ga) {
121
+ global.ga(function (tracker) {
122
+ this.gaClientId = tracker.get('clientId')
123
+ this.sendData(this.payloadParams(type, payload))
124
+ }.bind(this))
125
+ } else {
126
+ this.sendData(this.payloadParams(type, payload))
127
+ }
128
+ }.bind(this))
129
+ }
130
+
131
+ GOVUK.GOVUKTracker = GOVUKTracker
132
+
133
+ global.GOVUK = GOVUK
134
+ })(window)
@@ -0,0 +1,38 @@
1
+ ;(function (global) {
2
+ 'use strict'
3
+
4
+ var $ = global.jQuery
5
+ var GOVUK = global.GOVUK || {}
6
+
7
+ GOVUK.analyticsPlugins = GOVUK.analyticsPlugins || {}
8
+ GOVUK.analyticsPlugins.mailtoLinkTracker = function () {
9
+ var mailtoLinkSelector = 'a[href^="mailto:"]'
10
+
11
+ $('body').on('click', mailtoLinkSelector, trackClickEvent)
12
+
13
+ function trackClickEvent (evt) {
14
+ var $link = getLinkFromEvent(evt)
15
+ var options = { transport: 'beacon' }
16
+ var href = $link.attr('href')
17
+ var linkText = $.trim($link.text())
18
+
19
+ if (linkText) {
20
+ options.label = linkText
21
+ }
22
+
23
+ GOVUK.analytics.trackEvent('Mailto Link Clicked', href, options)
24
+ }
25
+
26
+ function getLinkFromEvent (evt) {
27
+ var $target = $(evt.target)
28
+
29
+ if (!$target.is('a')) {
30
+ $target = $target.parents('a')
31
+ }
32
+
33
+ return $target
34
+ }
35
+ }
36
+
37
+ global.GOVUK = GOVUK
38
+ })(window)
@@ -0,0 +1,39 @@
1
+ // Extension to monitor attempts to print pages.
2
+ ;(function (global) {
3
+ 'use strict'
4
+
5
+ var GOVUK = global.GOVUK || {}
6
+
7
+ GOVUK.analyticsPlugins = GOVUK.analyticsPlugins || {}
8
+
9
+ GOVUK.analyticsPlugins.printIntent = function () {
10
+ var printAttempt = function () {
11
+ GOVUK.analytics.trackEvent('Print Intent', document.location.pathname)
12
+ GOVUK.analytics.trackPageview('/print' + document.location.pathname)
13
+ }
14
+
15
+ // Most browsers
16
+ if (global.matchMedia) {
17
+ var mediaQueryList = global.matchMedia('print')
18
+ var mqlListenerCount = 0
19
+ mediaQueryList.addListener(function (mql) {
20
+ if (!mql.matches && mqlListenerCount === 0) {
21
+ printAttempt()
22
+ mqlListenerCount++
23
+ // If we try and print again within 3 seconds, don't log it
24
+ setTimeout(function () {
25
+ mqlListenerCount = 0
26
+ // printing will be tracked again now
27
+ }, 3000)
28
+ }
29
+ })
30
+ }
31
+
32
+ // IE < 10
33
+ if (global.onafterprint) {
34
+ global.onafterprint = printAttempt
35
+ }
36
+ }
37
+
38
+ global.GOVUK = GOVUK
39
+ })(window)
@@ -0,0 +1,240 @@
1
+ // <details> polyfill
2
+ // http://caniuse.com/#feat=details
3
+
4
+ // FF Support for HTML5's <details> and <summary>
5
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=591737
6
+
7
+ // http://www.sitepoint.com/fixing-the-details-element/
8
+
9
+ ;(function (global) {
10
+ 'use strict'
11
+
12
+ var GOVUK = global.GOVUK || {}
13
+
14
+ GOVUK.details = {
15
+ NATIVE_DETAILS: typeof document.createElement('details').open === 'boolean',
16
+ KEY_ENTER: 13,
17
+ KEY_SPACE: 32,
18
+
19
+ // Create a started flag so we can prevent the initialisation
20
+ // function firing from both DOMContentLoaded and window.onload
21
+ started: false,
22
+
23
+ // Add event construct for modern browsers or IE
24
+ // which fires the callback with a pre-converted target reference
25
+ addEvent: function (node, type, callback) {
26
+ if (node.addEventListener) {
27
+ node.addEventListener(type, function (e) {
28
+ callback(e, e.target)
29
+ }, false)
30
+ } else if (node.attachEvent) {
31
+ node.attachEvent('on' + type, function (e) {
32
+ callback(e, e.srcElement)
33
+ })
34
+ }
35
+ },
36
+
37
+ removeEvent: function (node, type) {
38
+ if (node.removeEventListener) {
39
+ node.removeEventListener(type, function (e) {
40
+ }, false)
41
+ } else if (node.detachEvent) {
42
+ node.detachEvent('on' + type, function (e) {
43
+ })
44
+ }
45
+ },
46
+
47
+ // Cross-browser character code / key pressed
48
+ charCode: function (e) {
49
+ return (typeof e.which === 'number') ? e.which : e.keyCode
50
+ },
51
+
52
+ // Cross-browser preventing default action
53
+ preventDefault: function (e) {
54
+ if (e.preventDefault) {
55
+ e.preventDefault()
56
+ } else {
57
+ e.returnValue = false
58
+ }
59
+ },
60
+
61
+ // Handle cross-modal click events
62
+ addClickEvent: function (node, callback) {
63
+ GOVUK.details.addEvent(node, 'keypress', function (e, target) {
64
+ // When the key gets pressed - check if it is enter or space
65
+ if (GOVUK.details.charCode(e) === GOVUK.details.KEY_ENTER || GOVUK.details.charCode(e) === GOVUK.details.KEY_SPACE) {
66
+ if (target.nodeName.toLowerCase() === 'summary') {
67
+ // Prevent space from scrolling the page
68
+ // and enter from submitting a form
69
+ GOVUK.details.preventDefault(e)
70
+ // Click to let the click event do all the necessary action
71
+ if (target.click) {
72
+ target.click()
73
+ } else {
74
+ // except Safari 5.1 and under don't support .click() here
75
+ callback(e, target)
76
+ }
77
+ }
78
+ }
79
+ })
80
+
81
+ // Prevent keyup to prevent clicking twice in Firefox when using space key
82
+ GOVUK.details.addEvent(node, 'keyup', function (e, target) {
83
+ if (GOVUK.details.charCode(e) === GOVUK.details.KEY_SPACE) {
84
+ if (target.nodeName === 'SUMMARY') {
85
+ GOVUK.details.preventDefault(e)
86
+ }
87
+ }
88
+ })
89
+
90
+ GOVUK.details.addEvent(node, 'click', function (e, target) {
91
+ callback(e, target)
92
+ })
93
+ },
94
+
95
+ // Get the nearest ancestor element of a node that matches a given tag name
96
+ getAncestor: function (node, match) {
97
+ do {
98
+ if (!node || node.nodeName.toLowerCase() === match) {
99
+ break
100
+ }
101
+ node = node.parentNode
102
+ } while (node)
103
+
104
+ return node
105
+ },
106
+
107
+ // Initialisation function
108
+ addDetailsPolyfill: function (list, container) {
109
+ container = container || document.body
110
+ // If this has already happened, just return
111
+ // else set the flag so it doesn't happen again
112
+ if (GOVUK.details.started) {
113
+ return
114
+ }
115
+ GOVUK.details.started = true
116
+ // Get the collection of details elements, but if that's empty
117
+ // then we don't need to bother with the rest of the scripting
118
+ if ((list = container.getElementsByTagName('details')).length === 0) {
119
+ return
120
+ }
121
+ // else iterate through them to apply their initial state
122
+ var n = list.length
123
+ var i = 0
124
+ for (i; i < n; i++) {
125
+ var details = list[i]
126
+
127
+ // Save shortcuts to the inner summary and content elements
128
+ details.__summary = details.getElementsByTagName('summary').item(0)
129
+ details.__content = details.getElementsByTagName('div').item(0)
130
+
131
+ if (!details.__summary || !details.__content) {
132
+ return
133
+ }
134
+ // If the content doesn't have an ID, assign it one now
135
+ // which we'll need for the summary's aria-controls assignment
136
+ if (!details.__content.id) {
137
+ details.__content.id = 'details-content-' + i
138
+ }
139
+
140
+ // Add ARIA role="group" to details
141
+ details.setAttribute('role', 'group')
142
+
143
+ // Add role=button to summary
144
+ details.__summary.setAttribute('role', 'button')
145
+
146
+ // Add aria-controls
147
+ details.__summary.setAttribute('aria-controls', details.__content.id)
148
+
149
+ // Set tabIndex so the summary is keyboard accessible for non-native elements
150
+ // http://www.saliences.com/browserBugs/tabIndex.html
151
+ if (!GOVUK.details.NATIVE_DETAILS) {
152
+ details.__summary.tabIndex = 0
153
+ }
154
+
155
+ // Detect initial open state
156
+ var openAttr = details.getAttribute('open') !== null
157
+ if (openAttr === true) {
158
+ details.__summary.setAttribute('aria-expanded', 'true')
159
+ details.__content.setAttribute('aria-hidden', 'false')
160
+ } else {
161
+ details.__summary.setAttribute('aria-expanded', 'false')
162
+ details.__content.setAttribute('aria-hidden', 'true')
163
+ if (!GOVUK.details.NATIVE_DETAILS) {
164
+ details.__content.style.display = 'none'
165
+ }
166
+ }
167
+
168
+ // Create a circular reference from the summary back to its
169
+ // parent details element, for convenience in the click handler
170
+ details.__summary.__details = details
171
+
172
+ // If this is not a native implementation, create an arrow
173
+ // inside the summary
174
+ if (!GOVUK.details.NATIVE_DETAILS) {
175
+ var twisty = document.createElement('i')
176
+
177
+ if (openAttr === true) {
178
+ twisty.className = 'arrow arrow-open'
179
+ twisty.appendChild(document.createTextNode('\u25bc'))
180
+ } else {
181
+ twisty.className = 'arrow arrow-closed'
182
+ twisty.appendChild(document.createTextNode('\u25ba'))
183
+ }
184
+
185
+ details.__summary.__twisty = details.__summary.insertBefore(twisty, details.__summary.firstChild)
186
+ details.__summary.__twisty.setAttribute('aria-hidden', 'true')
187
+ }
188
+ }
189
+
190
+ // Bind a click event to handle summary elements
191
+ GOVUK.details.addClickEvent(container, function (e, summary) {
192
+ if (!(summary = GOVUK.details.getAncestor(summary, 'summary'))) {
193
+ return true
194
+ }
195
+ return GOVUK.details.statechange(summary)
196
+ })
197
+ },
198
+
199
+ // Define a statechange function that updates aria-expanded and style.display
200
+ // Also update the arrow position
201
+ statechange: function (summary) {
202
+ var expanded = summary.__details.__summary.getAttribute('aria-expanded') === 'true'
203
+ var hidden = summary.__details.__content.getAttribute('aria-hidden') === 'true'
204
+
205
+ summary.__details.__summary.setAttribute('aria-expanded', (expanded ? 'false' : 'true'))
206
+ summary.__details.__content.setAttribute('aria-hidden', (hidden ? 'false' : 'true'))
207
+
208
+ if (!GOVUK.details.NATIVE_DETAILS) {
209
+ summary.__details.__content.style.display = (expanded ? 'none' : '')
210
+
211
+ var hasOpenAttr = summary.__details.getAttribute('open') !== null
212
+ if (!hasOpenAttr) {
213
+ summary.__details.setAttribute('open', 'open')
214
+ } else {
215
+ summary.__details.removeAttribute('open')
216
+ }
217
+ }
218
+
219
+ if (summary.__twisty) {
220
+ summary.__twisty.firstChild.nodeValue = (expanded ? '\u25ba' : '\u25bc')
221
+ summary.__twisty.setAttribute('class', (expanded ? 'arrow arrow-closed' : 'arrow arrow-open'))
222
+ }
223
+
224
+ return true
225
+ },
226
+
227
+ destroy: function (node) {
228
+ GOVUK.details.removeEvent(node, 'click')
229
+ },
230
+
231
+ // Bind two load events for modern and older browsers
232
+ // If the first one fires it will set a flag to block the second one
233
+ // but if it's not supported then the second one will fire
234
+ init: function ($container) {
235
+ GOVUK.details.addEvent(document, 'DOMContentLoaded', GOVUK.details.addDetailsPolyfill)
236
+ GOVUK.details.addEvent(window, 'load', GOVUK.details.addDetailsPolyfill)
237
+ }
238
+ }
239
+ global.GOVUK = GOVUK
240
+ })(window)
@@ -0,0 +1,30 @@
1
+ ;(function (global) {
2
+ 'use strict'
3
+
4
+ var GOVUK = global.GOVUK || {}
5
+ GOVUK.Modules = GOVUK.Modules || {}
6
+
7
+ GOVUK.Modules.AutoTrackEvent = function () {
8
+ this.start = function (element) {
9
+ var options = { nonInteraction: 1 } // automatic events shouldn't affect bounce rate
10
+ var category = element.data('track-category')
11
+ var action = element.data('track-action')
12
+ var label = element.data('track-label')
13
+ var value = element.data('track-value')
14
+
15
+ if (typeof label === 'string') {
16
+ options.label = label
17
+ }
18
+
19
+ if (value || value === 0) {
20
+ options.value = value
21
+ }
22
+
23
+ if (GOVUK.analytics && GOVUK.analytics.trackEvent) {
24
+ GOVUK.analytics.trackEvent(category, action, options)
25
+ }
26
+ }
27
+ }
28
+
29
+ global.GOVUK = GOVUK
30
+ })(window)