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,61 @@
1
+ ;(function (global) {
2
+ 'use strict'
3
+
4
+ var $ = global.jQuery
5
+ var GOVUK = global.GOVUK || {}
6
+ GOVUK.Modules = GOVUK.Modules || {}
7
+
8
+ GOVUK.modules = {
9
+ find: function (container) {
10
+ container = container || $('body')
11
+
12
+ var modules
13
+ var moduleSelector = '[data-module]'
14
+
15
+ modules = container.find(moduleSelector)
16
+
17
+ // Container could be a module too
18
+ if (container.is(moduleSelector)) {
19
+ modules = modules.add(container)
20
+ }
21
+
22
+ return modules
23
+ },
24
+
25
+ start: function (container) {
26
+ var modules = this.find(container)
27
+
28
+ for (var i = 0, l = modules.length; i < l; i++) {
29
+ var module
30
+ var element = $(modules[i])
31
+ var type = camelCaseAndCapitalise(element.data('module'))
32
+ var started = element.data('module-started')
33
+
34
+ if (typeof GOVUK.Modules[type] === 'function' && !started) {
35
+ module = new GOVUK.Modules[type]()
36
+ module.start(element)
37
+ element.data('module-started', true)
38
+ }
39
+ }
40
+
41
+ // eg selectable-table to SelectableTable
42
+ function camelCaseAndCapitalise (string) {
43
+ return capitaliseFirstLetter(camelCase(string))
44
+ }
45
+
46
+ // http://stackoverflow.com/questions/6660977/convert-hyphens-to-camel-case-camelcase
47
+ function camelCase (string) {
48
+ return string.replace(/-([a-z])/g, function (g) {
49
+ return g.charAt(1).toUpperCase()
50
+ })
51
+ }
52
+
53
+ // http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript
54
+ function capitaliseFirstLetter (string) {
55
+ return string.charAt(0).toUpperCase() + string.slice(1)
56
+ }
57
+ }
58
+ }
59
+
60
+ global.GOVUK = GOVUK
61
+ })(window)
@@ -0,0 +1,57 @@
1
+ ;(function (global) {
2
+ 'use strict'
3
+
4
+ var $ = global.jQuery
5
+ var GOVUK = global.GOVUK || {}
6
+
7
+ // Only show the first {n} items in a list, documentation is in the README.md
8
+ var PrimaryList = function (el, selector) {
9
+ this.$el = $(el)
10
+ this.$extraLinks = this.$el.find('li:not(' + selector + ')')
11
+ // only hide more than one extra link
12
+ if (this.$extraLinks.length > 1) {
13
+ this.addToggleLink()
14
+ this.hideExtraLinks()
15
+ }
16
+ }
17
+
18
+ PrimaryList.prototype = {
19
+ toggleText: function () {
20
+ if (this.$extraLinks.length > 1) {
21
+ return '+' + this.$extraLinks.length + ' others'
22
+ } else {
23
+ return '+' + this.$extraLinks.length + ' other'
24
+ }
25
+ },
26
+ addToggleLink: function () {
27
+ this.$toggleLink = $('<a href="#">' + this.toggleText() + '</a>')
28
+ this.$toggleLink.click($.proxy(this.toggleLinks, this))
29
+ this.$toggleLink.insertAfter(this.$el)
30
+ },
31
+ toggleLinks: function (e) {
32
+ e.preventDefault()
33
+ this.$toggleLink.remove()
34
+ this.showExtraLinks()
35
+ },
36
+ hideExtraLinks: function () {
37
+ this.$extraLinks.addClass('visuallyhidden')
38
+ $(window).trigger('govuk.pageSizeChanged')
39
+ },
40
+ showExtraLinks: function () {
41
+ this.$extraLinks.removeClass('visuallyhidden')
42
+ $(window).trigger('govuk.pageSizeChanged')
43
+ }
44
+ }
45
+
46
+ GOVUK.PrimaryList = PrimaryList
47
+
48
+ GOVUK.primaryLinks = {
49
+ init: function (selector) {
50
+ $(selector).parent().each(function (i, el) {
51
+ new GOVUK.PrimaryList(el, selector) // eslint-disable-line no-new
52
+ })
53
+ }
54
+ }
55
+
56
+ global.GOVUK = GOVUK
57
+ })(window)
@@ -0,0 +1,116 @@
1
+ // NOTICE
2
+ // IF you are using GOV.UK Elements 3.0,0 or above then you do not need to use
3
+ // this script anymore as it uses a pure CSS solution.
4
+
5
+ ;(function (global) {
6
+ 'use strict'
7
+
8
+ var $ = global.jQuery
9
+ var GOVUK = global.GOVUK || {}
10
+
11
+ var SelectionButtons = function (elmsOrSelector, opts) {
12
+ this.selectedClass = 'selected'
13
+ this.focusedClass = 'focused'
14
+ this.radioClass = 'selection-button-radio'
15
+ this.checkboxClass = 'selection-button-checkbox'
16
+ if (opts !== undefined) {
17
+ $.each(opts, function (optionName, optionObj) {
18
+ this[optionName] = optionObj
19
+ }.bind(this))
20
+ }
21
+ if (typeof elmsOrSelector === 'string') {
22
+ this.selector = elmsOrSelector
23
+ this.setInitialState($(this.selector))
24
+ } else if (elmsOrSelector !== undefined) {
25
+ this.$elms = elmsOrSelector
26
+ this.setInitialState(this.$elms)
27
+ }
28
+ this.addEvents()
29
+ }
30
+ SelectionButtons.prototype.addEvents = function () {
31
+ if (typeof this.$elms !== 'undefined') {
32
+ this.addElementLevelEvents()
33
+ } else {
34
+ this.addDocumentLevelEvents()
35
+ }
36
+ }
37
+ SelectionButtons.prototype.setInitialState = function ($elms) {
38
+ $elms.each(function (idx, elm) {
39
+ var $elm = $(elm)
40
+
41
+ var labelClass = $elm.attr('type') === 'radio' ? this.radioClass : this.checkboxClass
42
+ $elm.parent('label').addClass(labelClass)
43
+ if ($elm.is(':checked')) {
44
+ this.markSelected($elm)
45
+ }
46
+ }.bind(this))
47
+ }
48
+ SelectionButtons.prototype.markFocused = function ($elm, state) {
49
+ if (state === 'focused') {
50
+ $elm.parent('label').addClass(this.focusedClass)
51
+ } else {
52
+ $elm.parent('label').removeClass(this.focusedClass)
53
+ }
54
+ }
55
+ SelectionButtons.prototype.markSelected = function ($elm) {
56
+ var radioName
57
+
58
+ if ($elm.attr('type') === 'radio') {
59
+ radioName = $elm.attr('name')
60
+ $($elm[0].form).find('input[name="' + radioName + '"]')
61
+ .parent('label')
62
+ .removeClass(this.selectedClass)
63
+ $elm.parent('label').addClass(this.selectedClass)
64
+ } else { // checkbox
65
+ if ($elm.is(':checked')) {
66
+ $elm.parent('label').addClass(this.selectedClass)
67
+ } else {
68
+ $elm.parent('label').removeClass(this.selectedClass)
69
+ }
70
+ }
71
+ }
72
+ SelectionButtons.prototype.addElementLevelEvents = function () {
73
+ this.clickHandler = this.getClickHandler()
74
+ this.focusHandler = this.getFocusHandler({ 'level': 'element' })
75
+
76
+ this.$elms
77
+ .on('click', this.clickHandler)
78
+ .on('focus blur', this.focusHandler)
79
+ }
80
+ SelectionButtons.prototype.addDocumentLevelEvents = function () {
81
+ this.clickHandler = this.getClickHandler()
82
+ this.focusHandler = this.getFocusHandler({ 'level': 'document' })
83
+
84
+ $(document)
85
+ .on('click', this.selector, this.clickHandler)
86
+ .on('focus blur', this.selector, this.focusHandler)
87
+ }
88
+ SelectionButtons.prototype.getClickHandler = function () {
89
+ return function (e) {
90
+ this.markSelected($(e.target))
91
+ }.bind(this)
92
+ }
93
+ SelectionButtons.prototype.getFocusHandler = function (opts) {
94
+ var focusEvent = (opts.level === 'document') ? 'focusin' : 'focus'
95
+
96
+ return function (e) {
97
+ var state = (e.type === focusEvent) ? 'focused' : 'blurred'
98
+
99
+ this.markFocused($(e.target), state)
100
+ }.bind(this)
101
+ }
102
+ SelectionButtons.prototype.destroy = function () {
103
+ if (typeof this.selector !== 'undefined') {
104
+ $(document)
105
+ .off('click', this.selector, this.clickHandler)
106
+ .off('focus blur', this.selector, this.focusHandler)
107
+ } else {
108
+ this.$elms
109
+ .off('click', this.clickHandler)
110
+ .off('focus blur', this.focusHandler)
111
+ }
112
+ }
113
+
114
+ GOVUK.SelectionButtons = SelectionButtons
115
+ global.GOVUK = GOVUK
116
+ })(window)
@@ -0,0 +1,34 @@
1
+ // javascript 'shim' to trigger the click event of element(s)
2
+ // when the space key is pressed.
3
+ //
4
+ // Created since some Assistive Technologies (for example some Screenreaders)
5
+ // Will tell a user to press space on a 'button', so this functionality needs to be shimmed
6
+ // See https://github.com/alphagov/govuk_elements/pull/272#issuecomment-233028270
7
+ //
8
+ // Usage instructions:
9
+ // GOVUK.shimLinksWithButtonRole.init();
10
+ ;(function (global) {
11
+ 'use strict'
12
+
13
+ var $ = global.jQuery
14
+ var GOVUK = global.GOVUK || {}
15
+
16
+ GOVUK.shimLinksWithButtonRole = {
17
+
18
+ init: function init () {
19
+ // listen to 'document' for keydown event on the any elements that should be buttons.
20
+ $(document).on('keydown', '[role="button"]', function (event) {
21
+ // if the keyCode (which) is 32 it's a space, let's simulate a click.
22
+ if (event.which === 32) {
23
+ event.preventDefault()
24
+ // trigger the target's click event
25
+ event.target.click()
26
+ }
27
+ })
28
+ }
29
+
30
+ }
31
+
32
+ // hand back to global
33
+ global.GOVUK = GOVUK
34
+ })(window)
@@ -0,0 +1,172 @@
1
+ ;(function (global) {
2
+ 'use strict'
3
+
4
+ var $ = global.jQuery
5
+ var GOVUK = global.GOVUK || {}
6
+
7
+ function ShowHideContent () {
8
+ var self = this
9
+
10
+ // Radio and Checkbox selectors
11
+ var selectors = {
12
+ namespace: 'ShowHideContent',
13
+ radio: '[data-target] > input[type="radio"]',
14
+ checkbox: '[data-target] > input[type="checkbox"]'
15
+ }
16
+
17
+ // Escape name attribute for use in DOM selector
18
+ function escapeElementName (str) {
19
+ var result = str.replace('[', '\\[').replace(']', '\\]')
20
+ return result
21
+ }
22
+
23
+ // Adds ARIA attributes to control + associated content
24
+ function initToggledContent () {
25
+ var $control = $(this)
26
+ var $content = getToggledContent($control)
27
+
28
+ // Set aria-controls and defaults
29
+ if ($content.length) {
30
+ $control.attr('aria-controls', $content.attr('id'))
31
+ $control.attr('aria-expanded', 'false')
32
+ $content.attr('aria-hidden', 'true')
33
+ }
34
+ }
35
+
36
+ // Return toggled content for control
37
+ function getToggledContent ($control) {
38
+ var id = $control.attr('aria-controls')
39
+
40
+ // ARIA attributes aren't set before init
41
+ if (!id) {
42
+ id = $control.closest('[data-target]').data('target')
43
+ }
44
+
45
+ // Find show/hide content by id
46
+ return $('#' + id)
47
+ }
48
+
49
+ // Show toggled content for control
50
+ function showToggledContent ($control, $content) {
51
+ // Show content
52
+ if ($content.hasClass('js-hidden')) {
53
+ $content.removeClass('js-hidden')
54
+ $content.attr('aria-hidden', 'false')
55
+
56
+ // If the controlling input, update aria-expanded
57
+ if ($control.attr('aria-controls')) {
58
+ $control.attr('aria-expanded', 'true')
59
+ }
60
+ }
61
+ }
62
+
63
+ // Hide toggled content for control
64
+ function hideToggledContent ($control, $content) {
65
+ $content = $content || getToggledContent($control)
66
+
67
+ // Hide content
68
+ if (!$content.hasClass('js-hidden')) {
69
+ $content.addClass('js-hidden')
70
+ $content.attr('aria-hidden', 'true')
71
+
72
+ // If the controlling input, update aria-expanded
73
+ if ($control.attr('aria-controls')) {
74
+ $control.attr('aria-expanded', 'false')
75
+ }
76
+ }
77
+ }
78
+
79
+ // Handle radio show/hide
80
+ function handleRadioContent ($control, $content) {
81
+ // All radios in this group which control content
82
+ var selector = selectors.radio + '[name=' + escapeElementName($control.attr('name')) + '][aria-controls]'
83
+ var $form = $control.closest('form')
84
+ var $radios = $form.length ? $form.find(selector) : $(selector)
85
+
86
+ // Hide content for radios in group
87
+ $radios.each(function () {
88
+ hideToggledContent($(this))
89
+ })
90
+
91
+ // Select content for this control
92
+ if ($control.is('[aria-controls]')) {
93
+ showToggledContent($control, $content)
94
+ }
95
+ }
96
+
97
+ // Handle checkbox show/hide
98
+ function handleCheckboxContent ($control, $content) {
99
+ // Show checkbox content
100
+ if ($control.is(':checked')) {
101
+ showToggledContent($control, $content)
102
+ } else { // Hide checkbox content
103
+ hideToggledContent($control, $content)
104
+ }
105
+ }
106
+
107
+ // Set up event handlers etc
108
+ function init ($container, elementSelector, eventSelectors, handler) {
109
+ $container = $container || $(document.body)
110
+
111
+ // Handle control clicks
112
+ function deferred () {
113
+ var $control = $(this)
114
+ handler($control, getToggledContent($control))
115
+ }
116
+
117
+ // Prepare ARIA attributes
118
+ var $controls = $(elementSelector)
119
+ $controls.each(initToggledContent)
120
+
121
+ // Handle events
122
+ $.each(eventSelectors, function (idx, eventSelector) {
123
+ $container.on('click.' + selectors.namespace, eventSelector, deferred)
124
+ })
125
+
126
+ // Any already :checked on init?
127
+ if ($controls.is(':checked')) {
128
+ $controls.filter(':checked').each(deferred)
129
+ }
130
+ }
131
+
132
+ // Get event selectors for all radio groups
133
+ function getEventSelectorsForRadioGroups () {
134
+ var radioGroups = []
135
+
136
+ // Build an array of radio group selectors
137
+ return $(selectors.radio).map(function () {
138
+ var groupName = $(this).attr('name')
139
+
140
+ if ($.inArray(groupName, radioGroups) === -1) {
141
+ radioGroups.push(groupName)
142
+ return 'input[type="radio"][name="' + $(this).attr('name') + '"]'
143
+ }
144
+ return null
145
+ })
146
+ }
147
+
148
+ // Set up radio show/hide content for container
149
+ self.showHideRadioToggledContent = function ($container) {
150
+ init($container, selectors.radio, getEventSelectorsForRadioGroups(), handleRadioContent)
151
+ }
152
+
153
+ // Set up checkbox show/hide content for container
154
+ self.showHideCheckboxToggledContent = function ($container) {
155
+ init($container, selectors.checkbox, [selectors.checkbox], handleCheckboxContent)
156
+ }
157
+
158
+ // Remove event handlers
159
+ self.destroy = function ($container) {
160
+ $container = $container || $(document.body)
161
+ $container.off('.' + selectors.namespace)
162
+ }
163
+ }
164
+
165
+ ShowHideContent.prototype.init = function ($container) {
166
+ this.showHideRadioToggledContent($container)
167
+ this.showHideCheckboxToggledContent($container)
168
+ }
169
+
170
+ GOVUK.ShowHideContent = ShowHideContent
171
+ global.GOVUK = GOVUK
172
+ })(window)
@@ -0,0 +1,128 @@
1
+ ;(function (global) {
2
+ 'use strict'
3
+
4
+ var $ = global.jQuery
5
+ var GOVUK = global.GOVUK || {}
6
+
7
+ // Stick elements to top of screen when you scroll past, documentation is in the README.md
8
+ var sticky = {
9
+ _hasScrolled: false,
10
+ _scrollTimeout: false,
11
+ _hasResized: false,
12
+ _resizeTimeout: false,
13
+
14
+ getWindowDimensions: function () {
15
+ return {
16
+ height: $(global).height(),
17
+ width: $(global).width()
18
+ }
19
+ },
20
+ getWindowPositions: function () {
21
+ return {
22
+ scrollTop: $(global).scrollTop()
23
+ }
24
+ },
25
+ getElementOffset: function ($el) {
26
+ return $el.offset()
27
+ },
28
+ init: function () {
29
+ var $els = $('.js-stick-at-top-when-scrolling')
30
+
31
+ if ($els.length > 0) {
32
+ sticky.$els = $els
33
+
34
+ if (sticky._scrollTimeout === false) {
35
+ $(global).scroll(sticky.onScroll)
36
+ sticky._scrollTimeout = global.setInterval(sticky.checkScroll, 50)
37
+ }
38
+
39
+ if (sticky._resizeTimeout === false) {
40
+ $(global).resize(sticky.onResize)
41
+ sticky._resizeTimeout = global.setInterval(sticky.checkResize, 50)
42
+ }
43
+ }
44
+ if (GOVUK.stopScrollingAtFooter) {
45
+ $els.each(function (i, el) {
46
+ var $img = $(el).find('img')
47
+ if ($img.length > 0) {
48
+ var image = new global.Image()
49
+ image.onload = function () {
50
+ GOVUK.stopScrollingAtFooter.addEl($(el), $(el).outerHeight())
51
+ }
52
+ image.src = $img.attr('src')
53
+ } else {
54
+ GOVUK.stopScrollingAtFooter.addEl($(el), $(el).outerHeight())
55
+ }
56
+ })
57
+ }
58
+ },
59
+ onScroll: function () {
60
+ sticky._hasScrolled = true
61
+ },
62
+ onResize: function () {
63
+ sticky._hasResized = true
64
+ },
65
+ checkScroll: function () {
66
+ if (sticky._hasScrolled === true) {
67
+ sticky._hasScrolled = false
68
+
69
+ var windowVerticalPosition = sticky.getWindowPositions().scrollTop
70
+
71
+ var windowDimensions = sticky.getWindowDimensions()
72
+
73
+ sticky.$els.each(function (i, el) {
74
+ var $el = $(el)
75
+ var scrolledFrom = $el.data('scrolled-from')
76
+
77
+ if (scrolledFrom && windowVerticalPosition < scrolledFrom) {
78
+ sticky.release($el)
79
+ } else if (windowDimensions.width > 768 && windowVerticalPosition >= sticky.getElementOffset($el).top) {
80
+ sticky.stick($el)
81
+ }
82
+ })
83
+ }
84
+ },
85
+ checkResize: function () {
86
+ if (sticky._hasResized === true) {
87
+ sticky._hasResized = false
88
+
89
+ var windowDimensions = sticky.getWindowDimensions()
90
+
91
+ sticky.$els.each(function (i, el) {
92
+ var $el = $(el)
93
+
94
+ var elResize = $el.hasClass('js-sticky-resize')
95
+ if (elResize) {
96
+ var $shim = $('.shim')
97
+ var $elParent = $el.parent('div')
98
+ var elParentWidth = $elParent.width()
99
+ $shim.css('width', elParentWidth)
100
+ $el.css('width', elParentWidth)
101
+ }
102
+
103
+ if (windowDimensions.width <= 768) {
104
+ sticky.release($el)
105
+ }
106
+ })
107
+ }
108
+ },
109
+ stick: function ($el) {
110
+ if (!$el.hasClass('content-fixed')) {
111
+ $el.data('scrolled-from', sticky.getElementOffset($el).top)
112
+ var height = Math.max($el.height(), 1)
113
+ var width = $el.width()
114
+ $el.before('<div class="shim" style="width: ' + width + 'px; height: ' + height + 'px">&nbsp;</div>')
115
+ $el.css('width', width + 'px').addClass('content-fixed')
116
+ }
117
+ },
118
+ release: function ($el) {
119
+ if ($el.hasClass('content-fixed')) {
120
+ $el.data('scrolled-from', false)
121
+ $el.removeClass('content-fixed').css('width', '')
122
+ $el.siblings('.shim').remove()
123
+ }
124
+ }
125
+ }
126
+ GOVUK.stickAtTopWhenScrolling = sticky
127
+ global.GOVUK = GOVUK
128
+ })(window)