idsk_frontend_toolkit 7.4.2

Sign up to get free protection for your applications and to get access to all the features.
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)