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,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)