govuk_publishing_components 24.21.0 → 25.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/analytics.js +2 -0
  3. data/app/assets/javascripts/govuk_publishing_components/{lib → analytics}/track-click.js +0 -0
  4. data/app/assets/javascripts/govuk_publishing_components/{lib/select.js → analytics/track-select-change.js} +0 -0
  5. data/app/assets/javascripts/govuk_publishing_components/components/intervention.js +16 -0
  6. data/app/assets/javascripts/govuk_publishing_components/components/layout-super-navigation-header.js +234 -40
  7. data/app/assets/javascripts/govuk_publishing_components/lib/govspeak/youtube-link-enhancement.js +6 -0
  8. data/app/assets/javascripts/govuk_publishing_components/lib/header-navigation.js +34 -5
  9. data/app/assets/javascripts/govuk_publishing_components/modules.js +11 -17
  10. data/app/assets/stylesheets/govuk_publishing_components/component_support.scss +0 -1
  11. data/app/assets/stylesheets/govuk_publishing_components/components/_intervention.scss +12 -10
  12. data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +580 -41
  13. data/app/assets/stylesheets/govuk_publishing_components/components/_notice.scss +2 -17
  14. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_charts.scss +5 -0
  15. data/app/views/govuk_publishing_components/components/_fieldset.html.erb +1 -1
  16. data/app/views/govuk_publishing_components/components/_input.html.erb +1 -1
  17. data/app/views/govuk_publishing_components/components/_intervention.html.erb +26 -8
  18. data/app/views/govuk_publishing_components/components/_label.html.erb +6 -4
  19. data/app/views/govuk_publishing_components/components/_layout_for_public.html.erb +1 -1
  20. data/app/views/govuk_publishing_components/components/_layout_super_navigation_header.html.erb +244 -63
  21. data/app/views/govuk_publishing_components/components/_notice.html.erb +19 -13
  22. data/app/views/govuk_publishing_components/components/_radio.html.erb +5 -6
  23. data/app/views/govuk_publishing_components/components/_search.html.erb +11 -3
  24. data/app/views/govuk_publishing_components/components/_select.html.erb +3 -1
  25. data/app/views/govuk_publishing_components/components/_summary_list.html.erb +1 -1
  26. data/app/views/govuk_publishing_components/components/_title.html.erb +14 -7
  27. data/app/views/govuk_publishing_components/components/docs/notice.yml +15 -0
  28. data/app/views/govuk_publishing_components/components/docs/radio.yml +4 -15
  29. data/app/views/govuk_publishing_components/components/docs/search.yml +5 -0
  30. data/app/views/govuk_publishing_components/components/docs/title.yml +7 -12
  31. data/config/locales/ar.yml +5 -3
  32. data/config/locales/az.yml +5 -3
  33. data/config/locales/be.yml +5 -3
  34. data/config/locales/bg.yml +5 -3
  35. data/config/locales/bn.yml +5 -3
  36. data/config/locales/cs.yml +5 -3
  37. data/config/locales/cy.yml +8 -6
  38. data/config/locales/da.yml +5 -3
  39. data/config/locales/de.yml +5 -3
  40. data/config/locales/dr.yml +5 -3
  41. data/config/locales/el.yml +5 -3
  42. data/config/locales/en.yml +91 -84
  43. data/config/locales/es-419.yml +5 -3
  44. data/config/locales/es.yml +5 -3
  45. data/config/locales/et.yml +5 -3
  46. data/config/locales/fa.yml +5 -3
  47. data/config/locales/fi.yml +5 -3
  48. data/config/locales/fr.yml +5 -3
  49. data/config/locales/gd.yml +5 -3
  50. data/config/locales/gu.yml +5 -3
  51. data/config/locales/he.yml +5 -3
  52. data/config/locales/hi.yml +5 -3
  53. data/config/locales/hr.yml +5 -3
  54. data/config/locales/hu.yml +5 -3
  55. data/config/locales/hy.yml +5 -3
  56. data/config/locales/id.yml +5 -3
  57. data/config/locales/is.yml +5 -3
  58. data/config/locales/it.yml +5 -3
  59. data/config/locales/ja.yml +5 -3
  60. data/config/locales/ka.yml +5 -3
  61. data/config/locales/kk.yml +5 -3
  62. data/config/locales/ko.yml +5 -3
  63. data/config/locales/lt.yml +5 -3
  64. data/config/locales/lv.yml +5 -3
  65. data/config/locales/ms.yml +5 -3
  66. data/config/locales/mt.yml +5 -3
  67. data/config/locales/nl.yml +5 -3
  68. data/config/locales/no.yml +5 -3
  69. data/config/locales/pa-pk.yml +5 -3
  70. data/config/locales/pa.yml +5 -3
  71. data/config/locales/pl.yml +5 -3
  72. data/config/locales/ps.yml +5 -3
  73. data/config/locales/pt.yml +5 -3
  74. data/config/locales/ro.yml +5 -3
  75. data/config/locales/ru.yml +5 -3
  76. data/config/locales/si.yml +5 -3
  77. data/config/locales/sk.yml +5 -3
  78. data/config/locales/sl.yml +5 -3
  79. data/config/locales/so.yml +5 -3
  80. data/config/locales/sq.yml +5 -3
  81. data/config/locales/sr.yml +5 -3
  82. data/config/locales/sv.yml +5 -3
  83. data/config/locales/sw.yml +5 -3
  84. data/config/locales/ta.yml +5 -3
  85. data/config/locales/th.yml +5 -3
  86. data/config/locales/tk.yml +5 -3
  87. data/config/locales/tr.yml +5 -3
  88. data/config/locales/uk.yml +5 -3
  89. data/config/locales/ur.yml +5 -3
  90. data/config/locales/uz.yml +5 -3
  91. data/config/locales/vi.yml +5 -3
  92. data/config/locales/zh-hk.yml +5 -3
  93. data/config/locales/zh-tw.yml +5 -3
  94. data/config/locales/zh.yml +5 -3
  95. data/lib/govuk_publishing_components/presenters/content_breadcrumbs_based_on_priority.rb +2 -0
  96. data/lib/govuk_publishing_components/presenters/shared_helper.rb +5 -1
  97. data/lib/govuk_publishing_components/version.rb +1 -1
  98. metadata +5 -16
  99. data/app/assets/stylesheets/govuk_publishing_components/components/helpers/_px-to-em.scss +0 -12
  100. data/app/assets/stylesheets/govuk_publishing_components/components/print/_attachment.scss +0 -2
  101. data/app/assets/stylesheets/govuk_publishing_components/components/print/_back-link.scss +0 -2
  102. data/app/assets/stylesheets/govuk_publishing_components/components/print/_feedback.scss +0 -2
  103. data/app/assets/stylesheets/govuk_publishing_components/components/print/_layout-footer.scss +0 -2
  104. data/app/assets/stylesheets/govuk_publishing_components/components/print/_layout-header.scss +0 -2
  105. data/app/assets/stylesheets/govuk_publishing_components/components/print/_metadata.scss +0 -2
  106. data/app/assets/stylesheets/govuk_publishing_components/components/print/_search.scss +0 -2
  107. data/app/assets/stylesheets/govuk_publishing_components/components/print/_share-links.scss +0 -2
  108. data/app/assets/stylesheets/govuk_publishing_components/components/print/_skip-link.scss +0 -2
  109. data/app/assets/stylesheets/govuk_publishing_components/components/print/_subscription-links.scss +0 -2
  110. data/app/assets/stylesheets/govuk_publishing_components/components/print/_translation-nav.scss +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e658a82fdcc66d27c4e76f3fcfc8743612d80ca4f4b98493db30bc650ba5175c
4
- data.tar.gz: 65fa6a0bd681467c70a64a106b39933c4275cf716c1e961e6397912d43f32a50
3
+ metadata.gz: 30b1c979671a113e33ce87e4db1b19cbd0b26d2c64a6f1f4a98da31c24ac6294
4
+ data.tar.gz: 8c1a5fa5e9d9fa2f78adb033a0409deb8a6da43f6149b8b6f2f041b4cc859809
5
5
  SHA512:
6
- metadata.gz: cd7c02f1d17a3a72a5e74d70e1cad6b66d9ed2b48c8ab3d123a2397bb8062024084ffc650030a24742d556285f7e21b0474814e233a90554e29b5163a3cbd9c3
7
- data.tar.gz: '0890b578800c9eb7649ad5450b0f8cc94c1d2838947f3ce151932ee129c501599eb2072df826c63cbfdfc16fefa4c21e4712c719d8f1187b397c64d66cc3b0b5'
6
+ metadata.gz: 591e1edddd512c62aa2c7948b7e901c23842f06fc518ef1e2b24277af9ac933044d274f353d1e0d1ad8bb5e8b0ce92fe33989e059cf77288c9aaec86f7d19e47
7
+ data.tar.gz: 891a548c447d50c57b464ff8244b75f8f069655555f45b71568708350b608dc606f1956de61fc67542856c6e1087e1eb5dcd66dacb60179350f9483efc6c52c2
@@ -15,3 +15,5 @@
15
15
  //= require ./analytics/init
16
16
  //= require ./analytics/scroll-tracker
17
17
  //= require ./analytics/explicit-cross-domain-links
18
+ //= require ./analytics/track-click
19
+ //= require ./analytics/track-select-change
@@ -0,0 +1,16 @@
1
+ window.GOVUK = window.GOVUK || {}
2
+ window.GOVUK.Modules = window.GOVUK.Modules || {};
3
+
4
+ (function (Modules) {
5
+ function Intervention ($module) {
6
+ this.$module = $module
7
+ }
8
+
9
+ Intervention.prototype.init = function () {
10
+ if (window.GOVUK.analytics && window.GOVUK.analytics.trackEvent) {
11
+ window.GOVUK.analytics.trackEvent('interventionBanner', 'interventionShown')
12
+ }
13
+ }
14
+
15
+ Modules.Intervention = Intervention
16
+ })(window.GOVUK.Modules)
@@ -4,68 +4,262 @@ window.GOVUK = window.GOVUK || {}
4
4
  window.GOVUK.Modules = window.GOVUK.Modules || {};
5
5
 
6
6
  (function (Modules) {
7
- function SuperNavigationToggle ($module) {
8
- this.$module = $module
7
+ var SETTINGS = {
8
+ breakpoint: {
9
+ desktop: 769
10
+ },
11
+ label: {
12
+ hide: 'data-text-for-hide',
13
+ show: 'data-text-for-show'
14
+ }
15
+ }
9
16
 
10
- this.showMenuText = $module.getAttribute('data-text-for-show-menu')
11
- this.hideMenuText = $module.getAttribute('data-text-for-hide-menu')
12
- this.buttonText = $module.getAttribute('data-text-for-button')
17
+ // Small helpers that update the label when the state of the button has
18
+ // changed:
19
+ var setLabel = function ($button, showOrHide) {
20
+ var newLabel = $button.getAttribute(SETTINGS.label[showOrHide])
13
21
 
14
- this.$button = this.setupButton($module)
22
+ if (newLabel) {
23
+ $button.setAttribute('aria-label', newLabel)
24
+ }
25
+ }
15
26
 
16
- this.$menu = document.getElementById(this.$button.getAttribute('aria-controls'))
27
+ // Wrapper functions to contain all of the mechanisms needed for hiding and
28
+ // toggling the menus.
29
+ var hide = function ($button, $menu) {
30
+ $button.setAttribute('aria-expanded', false)
31
+ $button.classList.remove('gem-c-layout-super-navigation-header__open-button')
32
+ $menu.setAttribute('hidden', 'hidden')
33
+ setLabel($button, 'show')
34
+ }
35
+ var show = function ($button, $menu) {
36
+ $button.setAttribute('aria-expanded', true)
37
+ $button.classList.add('gem-c-layout-super-navigation-header__open-button')
38
+ $menu.removeAttribute('hidden')
39
+ setLabel($button, 'hide')
40
+ }
17
41
 
18
- this.syncStatus()
42
+ var toggle = function ($button, $menu) {
43
+ var isOpen = $button.getAttribute('aria-expanded') === 'true'
44
+ var trackingLabel = $button.getAttribute('data-tracking-key')
45
+ if (isOpen) {
46
+ hide($button, $menu)
47
+ } else {
48
+ show($button, $menu)
49
+ }
50
+
51
+ // Fire analytics if analytics are available
52
+ if (window.GOVUK.analytics && window.GOVUK.analytics.trackEvent && trackingLabel) {
53
+ window.GOVUK.analytics.trackEvent('headerClicked', trackingLabel + (isOpen ? 'Closed' : 'Opened'), { label: 'none' })
54
+ }
55
+ }
56
+
57
+ // Clicking an element inside a `button` element causes the `event.target` to
58
+ // be the inside element, not the button. This can be taken care of by setting
59
+ // the CSS pointer-events to be none, but that doesn't work for older
60
+ // browsers, won't work for people with CSS turned off, or for people who are
61
+ // using CSS overrides.
62
+ // This checks if the $element is the `elementType`; if it is, it gets
63
+ // returned; if not it recursively checks to see if the parent element is a
64
+ // `elementType`. This means that it can be used with `pointer-events: none`.
65
+ var closestParentIncluding = function ($element, elementType) {
66
+ if ($element.tagName.toLowerCase() === elementType.toLowerCase()) {
67
+ return $element
68
+ }
69
+ return closestParentIncluding($element.parentNode, elementType)
19
70
  }
20
71
 
21
- SuperNavigationToggle.prototype.setupButton = function (target) {
22
- var menuHeading = target.getAttribute('aria-labelledby')
23
- var adjacentTo = target.querySelector('#' + menuHeading)
24
- var buttonText = document.createTextNode(this.buttonText)
72
+ // Searched the previous elements to find one with the same tag as set in
73
+ // `elementType` . If it's found the element is returned; if not, it returns
74
+ // null.
75
+ var closestPrevious = function ($element, elementType) {
76
+ if ($element === null) {
77
+ return null
78
+ }
25
79
 
26
- var button = document.createElement('button')
27
- button.type = 'button'
28
- button.className = 'govuk-header__menu-button gem-c-layout-super-navigation-header__menu-button'
29
- button.setAttribute('aria-controls', 'super-navigation-menu')
30
- button.setAttribute('aria-label', this.showMenuText)
31
- button.setAttribute('aria-expanded', false)
80
+ // Using `previousSibling` means that there is a possibility that the
81
+ // $element could be a text node or a comment node - checking the `nodeType`
82
+ // of the element will ensure that it's a real element.
83
+ if ($element.nodeType === 1 && $element.tagName.toLowerCase() === elementType.toLowerCase()) {
84
+ return $element
85
+ }
32
86
 
33
- button.appendChild(buttonText)
34
- adjacentTo.insertAdjacentElement('beforebegin', button)
87
+ // If `previousElementSibling` can be used then let's use it as it'll be
88
+ // slightly faster since it skips things that aren't elements. If not,
89
+ // `previousSibling` can still be used as there's a `nodeType` check.
90
+ var previousElement = $element.previousElementSibling || $element.previousSibling
35
91
 
36
- return button
92
+ return closestPrevious(previousElement, elementType)
37
93
  }
38
94
 
39
- SuperNavigationToggle.prototype.syncStatus = function () {
40
- this.status = this.$button.getAttribute('aria-expanded') === 'true' ? 'open' : 'closed'
95
+ // When moving from one screen size to another (eg mobile to desktop) we need
96
+ // to find out whether a submenu is open so the parent menu can be kept open.
97
+ var hasSubMenusOpen = function ($menu) {
98
+ return $menu.querySelectorAll('button[aria-expanded="true"]').length > 0
41
99
  }
42
100
 
43
- SuperNavigationToggle.prototype.closeMenu = function () {
44
- this.$menu.classList.remove('gem-c-layout-super-navigation-header__items--open')
101
+ // Returns what screen size the window is currently. Returns a string of
102
+ // either `desktop` or `mobile` so it can be interpolated to access the
103
+ // `data-toggle-{desktop|mobile}-group` attribute.
104
+ var windowSize = function () {
105
+ return window.innerWidth >= SETTINGS.breakpoint.desktop ? 'desktop' : 'mobile'
106
+ }
45
107
 
46
- this.$button.classList.remove('govuk-header__menu-button--open')
47
- this.$button.setAttribute('aria-expanded', false)
48
- this.$button.setAttribute('aria-label', this.showMenuText)
108
+ function SuperNavigationMegaMenu ($module) {
109
+ this.$module = $module
110
+ this.$navigationToggle = this.$module.querySelector('#super-navigation-menu-toggle')
111
+ this.$navigationMenu = this.$module.querySelector('#super-navigation-menu')
112
+ this.$searchToggle = this.$module.querySelector('#super-search-menu-toggle')
113
+ this.$searchMenu = this.$module.querySelector('#super-search-menu')
114
+
115
+ // The menu toggler buttons need three attributes for this to work:
116
+ // - `aria-controls` contains the id of the menu to be toggled
117
+ // - `data-toggle-mobile-group` is the group that the menu belongs to on
118
+ // smaller screens
119
+ // - `data-toggle-desktop-group` is the group that the menu belongs to on
120
+ // larger screens
121
+ this.$buttons = this.$module.querySelectorAll(
122
+ 'button[aria-controls][data-toggle-mobile-group][data-toggle-desktop-group]'
123
+ )
124
+
125
+ this.hiddenButtons = this.$module.querySelectorAll('button[hidden]')
126
+
127
+ this.lastWindowSize = undefined
49
128
  }
50
129
 
51
- SuperNavigationToggle.prototype.openMenu = function () {
52
- this.$menu.classList.add('gem-c-layout-super-navigation-header__items--open')
130
+ SuperNavigationMegaMenu.prototype.windowSize = windowSize
53
131
 
54
- this.$button.classList.add('govuk-header__menu-button--open')
55
- this.$button.setAttribute('aria-expanded', true)
56
- this.$button.setAttribute('aria-label', this.hideMenuText)
132
+ // Resizes the space needed for the dropdown menu so that it doesn't overlap
133
+ // with the page content. As this is an event that needs to be added and
134
+ // removed it can't be be bound to `this` because that changes the fingerprint
135
+ // of the function, and makes it unable to be removed with
136
+ // `removeEventListener`.
137
+ SuperNavigationMegaMenu.prototype.resizeHandler = function () {
138
+ var $module = document.querySelector('[data-module="super-navigation-mega-menu"]')
139
+ var $openButton = $module.querySelector('[aria-expanded="true"][data-toggle-desktop-group="top"]')
140
+ var $openMenu = $openButton ? $module.querySelector('#' + $openButton.getAttribute('aria-controls')) : null
141
+ var margin = $openMenu && windowSize() === 'desktop' ? $openMenu.offsetHeight : 0
142
+
143
+ $module.style.marginBottom = margin + 'px'
57
144
  }
58
145
 
59
- SuperNavigationToggle.prototype.handleToggle = function () {
60
- if (this.status === 'open') this.closeMenu()
61
- if (this.status === 'closed') this.openMenu()
146
+ SuperNavigationMegaMenu.prototype.updateStates = function () {
147
+ if (this.windowSize() === 'mobile' && this.lastWindowSize !== 'mobile') {
148
+ this.$navigationToggle.removeAttribute('hidden')
149
+
150
+ // Hides navigation menu unless a submenu is open - this could be common
151
+ // as the desktop view has the navigation submenu as top level in the
152
+ // menu.
153
+ if (!hasSubMenusOpen(this.$navigationMenu)) {
154
+ hide(this.$navigationToggle, this.$navigationMenu)
155
+ }
156
+
157
+ this.$module.style.marginBottom = '0'
158
+
159
+ window.removeEventListener('resize', this.resizeHandler, { passive: true })
62
160
 
63
- this.syncStatus()
161
+ this.lastWindowSize = this.windowSize()
162
+ }
163
+
164
+ // Hide the navigation toggle button and show the navigation submenu:
165
+ if (this.windowSize() === 'desktop' && this.lastWindowSize !== 'desktop') {
166
+ this.$navigationToggle.setAttribute('hidden', 'hidden')
167
+ this.$navigationMenu.removeAttribute('hidden')
168
+
169
+ window.addEventListener('resize', this.resizeHandler, { passive: true })
170
+
171
+ this.lastWindowSize = this.windowSize()
172
+ }
173
+ }
174
+
175
+ SuperNavigationMegaMenu.prototype.buttonHandler = function (event) {
176
+ var $target = closestParentIncluding(event.target, 'button')
177
+ var $targetMenu = this.$module.querySelector('#' + $target.getAttribute('aria-controls'))
178
+
179
+ var toggleGroupAttribute = 'data-toggle-' + this.windowSize() + '-group'
180
+ var toggleGroupName = $target.getAttribute(toggleGroupAttribute)
181
+ var toggleGroupList = this.$module.querySelectorAll('[' + toggleGroupAttribute + '="' + toggleGroupName + '"]')
182
+
183
+ for (var k = 0; k < toggleGroupList.length; k++) {
184
+ var $element = toggleGroupList[k]
185
+ if ($element !== $target) {
186
+ var $menu = this.$module.querySelector('#' + $element.getAttribute('aria-controls'))
187
+ hide($element, $menu)
188
+ }
189
+ }
190
+
191
+ toggle($target, $targetMenu)
192
+
193
+ if (this.windowSize() === 'desktop') {
194
+ this.$module.style.marginBottom = $targetMenu.offsetHeight + 'px'
195
+ }
64
196
  }
65
197
 
66
- SuperNavigationToggle.prototype.init = function () {
67
- this.$button.addEventListener('click', this.handleToggle.bind(this))
198
+ SuperNavigationMegaMenu.prototype.init = function () {
199
+ for (var j = 0; j < this.$buttons.length; j++) {
200
+ var $button = this.$buttons[j]
201
+ $button.addEventListener('click', this.buttonHandler.bind(this), true)
202
+ }
203
+
204
+ // The toggle buttons are hardcoded to be hidden in the markup - this means
205
+ // that people without JavaScript turned on won't have buttons present that
206
+ // don't do anything.
207
+ // Since JavaScript is enabled we can remove the hidden attribute from
208
+ // the buttons so that they're perceivable by users.
209
+ // As the toggle buttons are now selectable, we should prevent the links
210
+ // from being selectable to avoid confusion.
211
+ for (var i = 0; i < this.hiddenButtons.length; i++) {
212
+ var $element = this.hiddenButtons[i]
213
+ $element.removeAttribute('hidden')
214
+
215
+ var closestSiblingLink = closestPrevious($element, 'a')
216
+ if (closestSiblingLink) {
217
+ closestSiblingLink.setAttribute('hidden', 'hidden')
218
+ }
219
+ }
220
+
221
+ this.$module.querySelector('.gem-c-layout-super-navigation-header__search-item-link')
222
+ .setAttribute('hidden', 'hidden')
223
+
224
+ // Navigation menu and search menu are hardcoded to be open in the markup -
225
+ // this means that the menu still makes sense with CSS and JavaScript turned
226
+ // off.
227
+ // The menus now need to be hidden as part of the JavaScript
228
+ // initialisation.
229
+ // - On both mobile and desktop, this means hiding the search menu
230
+ // - On mobile, this means hiding the navigation
231
+ // - On desktop, this means hiding the navigation button, showing the
232
+ // second level navigation menu
233
+ hide(this.$searchToggle, this.$searchMenu)
234
+ this.updateStates()
235
+
236
+ this.lastWindowSize = this.windowSize()
237
+
238
+ // The menu needs to be updated when the window is resized - specifically,
239
+ // the top level navigation toggle needs to be shown or hidden.
240
+ // Using `matchMedia` to listen for both resize events means that this
241
+ // will only fire when the media query is matched so is more efficient. The
242
+ // fallback is the `window.resize` event with a check to make sure that it
243
+ // only does things when moving from mobile to desktop view.
244
+ var setupResizeListener = function () {
245
+ window.addEventListener('resize', this.updateStates.bind(this), { passive: true })
246
+ }.bind(this)
247
+
248
+ if (typeof window.matchMedia === 'function') {
249
+ // Internet Explorer 11 supports `matchMedia`, but doesn't support
250
+ // the `change` event[1] - so we try it, and then fail back to using
251
+ // `window.resize`.
252
+ // [1]: https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/onchange
253
+ try {
254
+ window.matchMedia('screen and (min-width:' + SETTINGS.breakpoint.desktop + 'px)')
255
+ .addEventListener('change', this.updateStates.bind(this))
256
+ } catch (error) {
257
+ setupResizeListener()
258
+ }
259
+ } else {
260
+ setupResizeListener()
261
+ }
68
262
  }
69
263
 
70
- Modules.SuperNavigationToggle = SuperNavigationToggle
264
+ Modules.SuperNavigationMegaMenu = SuperNavigationMegaMenu
71
265
  })(window.GOVUK.Modules)
@@ -9,9 +9,15 @@
9
9
 
10
10
  YoutubeLinkEnhancement.prototype.init = function () {
11
11
  if (!this.campaignCookiesAllowed()) {
12
+ this.startModule = this.startModule.bind(this)
13
+ window.addEventListener('cookie-consent', this.startModule)
12
14
  return
13
15
  }
16
+ this.startModule()
17
+ }
14
18
 
19
+ YoutubeLinkEnhancement.prototype.startModule = function () {
20
+ window.removeEventListener('cookie-consent', this.startModule)
15
21
  var $youtubeLinks = this.$element.querySelectorAll('a[href*="youtube.com"], a[href*="youtu.be"]')
16
22
 
17
23
  if ($youtubeLinks.length > 0) {
@@ -7,12 +7,41 @@
7
7
 
8
8
  if (document.querySelectorAll && document.addEventListener) {
9
9
  var els = document.querySelectorAll('.js-header-toggle')
10
- var i
11
- var _i
12
- for (i = 0, _i = els.length; i < _i; i++) {
13
- els[i].addEventListener('click', function (e) {
10
+ for (var i = 0; i < els.length; i++) {
11
+ // Reassign current index to bypass rules in Chrome and Firefox around indexed property setting
12
+ var thisEl = els[i]
13
+
14
+ // If the element is an a tag, convert it to a button
15
+ // This is to target instances where we want to change behaviour between a js and a no-js view eg: the search button on the mobile menu for some government pages. On no-js it's just a link to /search
16
+ // This swaps a link for no-js to a button, making it interactable. Using a link for interactivity is poor accessibility as it's a misuse of the link tag and can be confusing to assistive tech users
17
+
18
+ if (thisEl.tagName === 'A') {
19
+ var attributes = thisEl.attributes
20
+ var button = document.createElement('button')
21
+
22
+ for (var k = 0; k < attributes.length; k++) {
23
+ var thisAttr = attributes[k].name
24
+
25
+ if (thisAttr === 'href') {
26
+ if (button.getAttribute('data-search-toggle-for')) {
27
+ continue
28
+ } else {
29
+ button.setAttribute('data-search-toggle-for', thisEl.getAttribute('href').substr(1))
30
+ }
31
+ } else if (thisAttr !== 'data-button-text') {
32
+ button.setAttribute(thisAttr, thisEl.getAttribute(thisAttr))
33
+ }
34
+ }
35
+
36
+ button.innerText = thisEl.getAttribute('data-button-text') || thisEl.innerText
37
+
38
+ thisEl.parentNode.replaceChild(button, thisEl)
39
+ thisEl = button
40
+ }
41
+
42
+ thisEl.addEventListener('click', function (e) {
14
43
  e.preventDefault()
15
- var target = this.getAttribute('href') ? document.getElementById(this.getAttribute('href').substr(1)) : document.getElementById(this.getAttribute('data-search-toggle-for'))
44
+ var target = document.getElementById(this.getAttribute('data-search-toggle-for'))
16
45
  var targetClass = target.getAttribute('class') || ''
17
46
  var sourceClass = this.getAttribute('class') || ''
18
47
  var isSearchToggle = sourceClass.match('search-toggle')
@@ -30,27 +30,21 @@
30
30
  var moduleNames = element.data('module').split(' ')
31
31
 
32
32
  for (var j = 0, k = moduleNames.length; j < k; j++) {
33
- var module
34
33
  var moduleName = camelCaseAndCapitalise(moduleNames[j])
35
34
  var started = element.data(moduleNames[j] + '-module-started')
36
35
 
37
- if ( // GOV.UK Publishing & Legacy Modules
38
- typeof GOVUK.Modules[moduleName] === 'function' &&
39
- !GOVUK.Modules[moduleName].prototype.init &&
40
- !started
41
- ) {
42
- module = new GOVUK.Modules[moduleName]()
43
- module.start(element)
44
- element.data(moduleNames[j] + '-module-started', true)
45
- }
36
+ if (typeof GOVUK.Modules[moduleName] === 'function' && !started) {
37
+ // GOV.UK Legacy Modules using jQuery
38
+ if (!GOVUK.Modules[moduleName].prototype.init) {
39
+ new GOVUK.Modules[moduleName]().start(element)
40
+ element.data(moduleNames[j] + '-module-started', true)
41
+ }
46
42
 
47
- if ( // GOV.UK Frontend Modules
48
- typeof GOVUK.Modules[moduleName] === 'function' &&
49
- GOVUK.Modules[moduleName].prototype.init &&
50
- !started
51
- ) {
52
- module = new GOVUK.Modules[moduleName](element[0]).init()
53
- element.data(moduleNames[j] + '-module-started', true)
43
+ // Vanilla JavaScript GOV.UK Modules and GOV.UK Frontend Modules
44
+ if (GOVUK.Modules[moduleName].prototype.init) {
45
+ new GOVUK.Modules[moduleName](element[0]).init()
46
+ element.data(moduleNames[j] + '-module-started', true)
47
+ }
54
48
  }
55
49
  }
56
50
  }