govuk_publishing_components 21.62.0 → 21.64.0
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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/govuk_publishing_components/components/govspeak.js +17 -15
- data/app/assets/javascripts/govuk_publishing_components/components/step-by-step-nav.js +402 -340
- data/app/assets/javascripts/govuk_publishing_components/dependencies.js +0 -5
- data/app/assets/javascripts/govuk_publishing_components/lib.js +1 -0
- data/app/assets/javascripts/govuk_publishing_components/lib/govspeak/barchart-enhancement.js +18 -11
- data/app/assets/javascripts/govuk_publishing_components/lib/govspeak/magna-charta.js +423 -0
- data/app/assets/javascripts/govuk_publishing_components/lib/toggle.js +126 -65
- data/app/assets/javascripts/govuk_publishing_components/vendor/polyfills/closest.js +23 -0
- data/app/assets/javascripts/govuk_publishing_components/vendor/polyfills/indexOf.js +9 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_breadcrumbs.scss +3 -16
- data/app/assets/stylesheets/govuk_publishing_components/components/_panel.scss +7 -1
- data/app/views/govuk_publishing_components/component_guide/example.html.erb +4 -1
- data/app/views/govuk_publishing_components/component_guide/show.html.erb +3 -1
- data/app/views/govuk_publishing_components/components/_breadcrumbs.html.erb +1 -1
- data/app/views/govuk_publishing_components/components/_cookie_banner.html.erb +1 -1
- data/app/views/govuk_publishing_components/components/_document_list.html.erb +18 -9
- data/app/views/govuk_publishing_components/components/_panel.html.erb +13 -11
- data/app/views/govuk_publishing_components/components/_radio.html.erb +3 -1
- data/app/views/govuk_publishing_components/components/_search.html.erb +6 -2
- data/app/views/govuk_publishing_components/components/docs/document_list.yml +18 -0
- data/app/views/govuk_publishing_components/components/feedback/_problem_form.html.erb +6 -6
- data/app/views/govuk_publishing_components/components/feedback/_survey_signup_form.html.erb +6 -6
- data/app/views/govuk_publishing_components/components/feedback/_yes_no_banner.html.erb +8 -10
- data/config/locales/en.yml +18 -0
- data/lib/govuk_publishing_components/presenters/breadcrumb_selector.rb +5 -0
- data/lib/govuk_publishing_components/presenters/content_breadcrumbs_based_on_priority.rb +19 -5
- data/lib/govuk_publishing_components/presenters/contextual_navigation.rb +1 -1
- data/lib/govuk_publishing_components/version.rb +1 -1
- metadata +5 -3
- data/app/assets/javascripts/govuk_publishing_components/vendor/magna-charta.min.js +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19018ea589b383f250f5b7298d06301f5b55e196b475b092e80f707f09bd399b
|
4
|
+
data.tar.gz: 1748c5cd55d806fe8e5ef22025ad348a5fe720a045d7879644980224693f8986
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 209e7cf684d04b5be7ad3c45ad8a0083c2da82c170877fca927b51b5c422e89f82de285b9c2131f5db65996aac0a28af4a7c680d34ffb827ba382b0682314d10
|
7
|
+
data.tar.gz: 17df0e8345e4fb29baaf8c3c61eeb63c68acaebdcc30a3f4cdc07e857b18f1b45368d1178717008b5027c9de1c2fffb2d4c9d84ee20c4db976376937939e4aec
|
@@ -2,25 +2,27 @@ window.GOVUK = window.GOVUK || {}
|
|
2
2
|
window.GOVUK.Modules = window.GOVUK.Modules || {};
|
3
3
|
|
4
4
|
(function (Modules) {
|
5
|
-
|
5
|
+
function Govspeak () { }
|
6
6
|
|
7
|
-
|
8
|
-
this
|
9
|
-
if (!$element.hasClass('disable-youtube')) {
|
10
|
-
this.embedYoutube($element)
|
11
|
-
}
|
7
|
+
Govspeak.prototype.start = function ($module) {
|
8
|
+
this.$module = $module[0]
|
12
9
|
|
13
|
-
|
10
|
+
if (this.$module.className.indexOf('disable-youtube') === -1) {
|
11
|
+
this.embedYoutube()
|
14
12
|
}
|
15
13
|
|
16
|
-
this.
|
17
|
-
|
18
|
-
enhancement.init()
|
19
|
-
}
|
14
|
+
this.createBarcharts()
|
15
|
+
}
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
}
|
17
|
+
Govspeak.prototype.embedYoutube = function () {
|
18
|
+
var enhancement = new window.GOVUK.GovspeakYoutubeLinkEnhancement(this.$module)
|
19
|
+
enhancement.init()
|
25
20
|
}
|
21
|
+
|
22
|
+
Govspeak.prototype.createBarcharts = function () {
|
23
|
+
var enhancement = new window.GOVUK.GovspeakBarchartEnhancement(this.$module)
|
24
|
+
enhancement.init()
|
25
|
+
}
|
26
|
+
|
27
|
+
Modules.Govspeak = Govspeak
|
26
28
|
})(window.GOVUK.Modules)
|
@@ -1,432 +1,494 @@
|
|
1
|
-
|
1
|
+
//= require govuk/vendor/polyfills/Element/prototype/classList.js
|
2
|
+
//= require ../vendor/polyfills/closest.js
|
3
|
+
//= require ../vendor/polyfills/indexOf.js
|
2
4
|
|
3
5
|
window.GOVUK = window.GOVUK || {}
|
4
6
|
window.GOVUK.Modules = window.GOVUK.Modules || {};
|
5
7
|
|
6
8
|
(function (Modules) {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
9
|
+
function Gemstepnav () { }
|
10
|
+
|
11
|
+
Gemstepnav.prototype.start = function ($module) {
|
12
|
+
this.$module = $module[0]
|
13
|
+
this.$module.actions = {} // stores text for JS appended elements 'show' and 'hide' on steps, and 'show/hide all' button
|
14
|
+
this.$module.rememberShownStep = false
|
15
|
+
this.$module.stepNavSize = false
|
16
|
+
this.$module.sessionStoreLink = 'govuk-step-nav-active-link'
|
17
|
+
this.$module.activeLinkClass = 'gem-c-step-nav__list-item--active'
|
18
|
+
this.$module.activeStepClass = 'gem-c-step-nav__step--active'
|
19
|
+
this.$module.activeLinkHref = '#content'
|
20
|
+
this.$module.uniqueId = false
|
21
|
+
|
22
|
+
// Indicate that js has worked
|
23
|
+
this.$module.classList.add('gem-c-step-nav--active')
|
24
|
+
|
25
|
+
// Prevent FOUC, remove class hiding content
|
26
|
+
this.$module.classList.remove('js-hidden')
|
27
|
+
|
28
|
+
this.$module.stepNavSize = this.$module.classList.contains('gem-c-step-nav--large') ? 'Big' : 'Small'
|
29
|
+
this.$module.rememberShownStep = !!this.$module.hasAttribute('data-remember') && this.$module.stepNavSize === 'Big'
|
30
|
+
|
31
|
+
this.$module.steps = this.$module.querySelectorAll('.js-step')
|
32
|
+
this.$module.stepHeaders = this.$module.querySelectorAll('.js-toggle-panel')
|
33
|
+
this.$module.totalSteps = this.$module.querySelectorAll('.js-panel').length
|
34
|
+
this.$module.totalLinks = this.$module.querySelectorAll('.gem-c-step-nav__link').length
|
35
|
+
this.$module.showOrHideAllButton = false
|
36
|
+
|
37
|
+
this.$module.uniqueId = this.$module.getAttribute('data-id') || false
|
38
|
+
|
39
|
+
if (this.$module.uniqueId) {
|
40
|
+
this.$module.sessionStoreLink = this.$module.sessionStoreLink + '_' + this.$module.uniqueId
|
41
|
+
}
|
39
42
|
|
40
|
-
|
43
|
+
var stepNavTracker = new this.StepNavTracker(this.$module.uniqueId, this.$module.totalSteps, this.$module.totalLinks)
|
41
44
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
this.getTextForInsertedElements()
|
46
|
+
this.addButtonstoSteps()
|
47
|
+
this.addShowHideAllButton()
|
48
|
+
this.addShowHideToggle()
|
49
|
+
this.addAriaControlsAttrForShowHideAllButton()
|
47
50
|
|
48
|
-
|
49
|
-
|
51
|
+
this.ensureOnlyOneActiveLink()
|
52
|
+
this.showPreviouslyOpenedSteps()
|
50
53
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
+
this.bindToggleForSteps(stepNavTracker)
|
55
|
+
this.bindToggleShowHideAllButton(stepNavTracker)
|
56
|
+
this.bindComponentLinkClicks(stepNavTracker)
|
57
|
+
}
|
54
58
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
Gemstepnav.prototype.getTextForInsertedElements = function () {
|
60
|
+
this.$module.actions.showText = this.$module.getAttribute('data-show-text')
|
61
|
+
this.$module.actions.hideText = this.$module.getAttribute('data-hide-text')
|
62
|
+
this.$module.actions.showAllText = this.$module.getAttribute('data-show-all-text')
|
63
|
+
this.$module.actions.hideAllText = this.$module.getAttribute('data-hide-all-text')
|
64
|
+
}
|
61
65
|
|
62
|
-
|
63
|
-
|
64
|
-
|
66
|
+
Gemstepnav.prototype.addShowHideAllButton = function () {
|
67
|
+
var showall = document.createElement('div')
|
68
|
+
showall.className = 'gem-c-step-nav__controls'
|
69
|
+
showall.innerHTML = '<button aria-expanded="false" class="gem-c-step-nav__button gem-c-step-nav__button--controls js-step-controls-button">' + this.$module.actions.showAllText + '</button>'
|
65
70
|
|
66
|
-
|
67
|
-
|
68
|
-
var linkText = actions.showText // eslint-disable-line no-unused-vars
|
71
|
+
var steps = this.$module.querySelectorAll('.gem-c-step-nav__steps')[0]
|
72
|
+
this.$module.insertBefore(showall, steps)
|
69
73
|
|
70
|
-
|
71
|
-
|
72
|
-
}
|
74
|
+
this.$module.showOrHideAllButton = this.$module.querySelectorAll('.js-step-controls-button')[0]
|
75
|
+
}
|
73
76
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
)
|
78
|
-
}
|
79
|
-
})
|
80
|
-
}
|
77
|
+
Gemstepnav.prototype.addShowHideToggle = function () {
|
78
|
+
for (var i = 0; i < this.$module.stepHeaders.length; i++) {
|
79
|
+
var thisel = this.$module.stepHeaders[i]
|
81
80
|
|
82
|
-
|
83
|
-
|
81
|
+
if (!thisel.querySelectorAll('.js-toggle-link').length) {
|
82
|
+
var span = document.createElement('span')
|
83
|
+
span.className = 'gem-c-step-nav__toggle-link js-toggle-link'
|
84
|
+
span.setAttribute('aria-hidden', true)
|
85
|
+
span.setAttribute('hidden', 'hidden')
|
86
|
+
thisel.querySelectorAll('.js-step-title-button')[0].appendChild(span)
|
84
87
|
}
|
88
|
+
}
|
89
|
+
}
|
85
90
|
|
86
|
-
|
87
|
-
|
91
|
+
Gemstepnav.prototype.headerIsOpen = function (stepHeader) {
|
92
|
+
return (typeof stepHeader.parentNode.getAttribute('show') !== 'undefined')
|
93
|
+
}
|
88
94
|
|
89
|
-
|
90
|
-
|
91
|
-
|
95
|
+
Gemstepnav.prototype.addAriaControlsAttrForShowHideAllButton = function () {
|
96
|
+
var ariaControlsValue = this.$module.querySelectorAll('.js-panel')[0].getAttribute('id')
|
97
|
+
this.$module.showOrHideAllButton.setAttribute('aria-controls', ariaControlsValue)
|
98
|
+
}
|
92
99
|
|
93
|
-
|
94
|
-
|
95
|
-
|
100
|
+
// called by show all/hide all, sets all steps accordingly
|
101
|
+
Gemstepnav.prototype.setAllStepsShownState = function (isShown) {
|
102
|
+
var data = []
|
96
103
|
|
97
|
-
|
98
|
-
|
99
|
-
|
104
|
+
for (var i = 0; i < this.$module.steps.length; i++) {
|
105
|
+
var stepView = new this.StepView(this.$module.steps[i], this.$module.actions.showText, this.$module.actions.hideText)
|
106
|
+
stepView.setIsShown(isShown)
|
100
107
|
|
101
|
-
|
102
|
-
|
103
|
-
}
|
104
|
-
})
|
105
|
-
|
106
|
-
if (isShown) {
|
107
|
-
saveToSessionStorage(uniqueId, JSON.stringify(data))
|
108
|
-
} else {
|
109
|
-
removeFromSessionStorage(uniqueId)
|
110
|
-
}
|
108
|
+
if (isShown) {
|
109
|
+
data.push(this.$module.steps[i].getAttribute('id'))
|
111
110
|
}
|
111
|
+
}
|
112
112
|
|
113
|
-
|
114
|
-
|
115
|
-
|
113
|
+
if (isShown) {
|
114
|
+
this.saveToSessionStorage(this.$module.uniqueId, JSON.stringify(data))
|
115
|
+
} else {
|
116
|
+
this.removeFromSessionStorage(this.$module.uniqueId)
|
117
|
+
}
|
118
|
+
}
|
116
119
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
+
// called on load, determines whether each step should be open or closed
|
121
|
+
Gemstepnav.prototype.showPreviouslyOpenedSteps = function () {
|
122
|
+
var data = this.loadFromSessionStorage(this.$module.uniqueId) || []
|
120
123
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
}
|
127
|
-
})
|
124
|
+
for (var i = 0; i < this.$module.steps.length; i++) {
|
125
|
+
var thisel = this.$module.steps[i]
|
126
|
+
var id = thisel.getAttribute('id')
|
127
|
+
var stepView = new this.StepView(thisel, this.$module.actions.showText, this.$module.actions.hideText)
|
128
|
+
var shouldBeShown = thisel.hasAttribute('data-show')
|
128
129
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
130
|
+
// show the step if it has been remembered or if it has the 'data-show' attribute
|
131
|
+
if ((this.$module.rememberShownStep && data.indexOf(id) > -1) || (shouldBeShown && shouldBeShown !== 'undefined')) {
|
132
|
+
stepView.setIsShown(true)
|
133
|
+
} else {
|
134
|
+
stepView.setIsShown(false)
|
133
135
|
}
|
136
|
+
}
|
134
137
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
138
|
+
if (data.length > 0) {
|
139
|
+
this.$module.showOrHideAllButton.setAttribute('aria-expanded', true)
|
140
|
+
this.setShowHideAllText()
|
141
|
+
}
|
142
|
+
}
|
140
143
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
+
Gemstepnav.prototype.addButtonstoSteps = function () {
|
145
|
+
for (var i = 0; i < this.$module.steps.length; i++) {
|
146
|
+
var thisel = this.$module.steps[i]
|
147
|
+
var title = thisel.querySelectorAll('.js-step-title')[0]
|
148
|
+
var contentId = thisel.querySelectorAll('.js-panel')[0].getAttribute('id')
|
149
|
+
var titleText = title.textContent || title.innerText // IE8 fallback
|
144
150
|
|
145
|
-
|
146
|
-
|
151
|
+
title.outerHTML =
|
152
|
+
'<span class="js-step-title">' +
|
153
|
+
'<button ' +
|
147
154
|
'class="gem-c-step-nav__button gem-c-step-nav__button--title js-step-title-button" ' +
|
148
155
|
'aria-expanded="false" aria-controls="' + contentId + '">' +
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
156
|
+
'<span class="js-step-title-text">' + titleText + '</span>' +
|
157
|
+
'</button>' +
|
158
|
+
'</span>'
|
159
|
+
}
|
160
|
+
}
|
153
161
|
|
154
|
-
|
155
|
-
|
156
|
-
|
162
|
+
Gemstepnav.prototype.bindToggleForSteps = function (stepNavTracker) {
|
163
|
+
var that = this
|
164
|
+
var togglePanels = this.$module.querySelectorAll('.js-toggle-panel')
|
157
165
|
|
158
|
-
|
159
|
-
|
166
|
+
for (var i = 0; i < togglePanels.length; i++) {
|
167
|
+
togglePanels[i].addEventListener('click', function (event) {
|
168
|
+
var stepView = new that.StepView(this.parentNode, that.$module.actions.showText, that.$module.actions.hideText)
|
169
|
+
stepView.toggle()
|
160
170
|
|
161
|
-
|
162
|
-
|
163
|
-
|
171
|
+
var stepIsOptional = this.parentNode.hasAttribute('data-optional')
|
172
|
+
var toggleClick = new that.StepToggleClick(event, stepView, stepNavTracker, stepIsOptional, that.$module.stepNavSize)
|
173
|
+
toggleClick.trackClick()
|
164
174
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
175
|
+
that.setShowHideAllText()
|
176
|
+
that.rememberStepState(this.parentNode)
|
177
|
+
})
|
178
|
+
}
|
179
|
+
}
|
169
180
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
}
|
185
|
-
}
|
186
|
-
saveToSessionStorage(uniqueId, JSON.stringify(data))
|
181
|
+
// if the step is open, store its id in session store
|
182
|
+
// if the step is closed, remove its id from session store
|
183
|
+
Gemstepnav.prototype.rememberStepState = function (step) {
|
184
|
+
if (this.$module.rememberShownStep) {
|
185
|
+
var data = JSON.parse(this.loadFromSessionStorage(this.$module.uniqueId)) || []
|
186
|
+
var thisstep = step.getAttribute('id')
|
187
|
+
var shown = step.classList.contains('step-is-shown')
|
188
|
+
|
189
|
+
if (shown) {
|
190
|
+
data.push(thisstep)
|
191
|
+
} else {
|
192
|
+
var i = data.indexOf(thisstep)
|
193
|
+
if (i > -1) {
|
194
|
+
data.splice(i, 1)
|
187
195
|
}
|
188
196
|
}
|
197
|
+
this.saveToSessionStorage(this.$module.uniqueId, JSON.stringify(data))
|
198
|
+
}
|
199
|
+
}
|
189
200
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
linkClick.track()
|
195
|
-
var thisLinkHref = $(this).attr('href')
|
196
|
-
|
197
|
-
if ($(this).attr('rel') !== 'external') {
|
198
|
-
saveToSessionStorage(sessionStoreLink, $(this).attr('data-position'))
|
199
|
-
}
|
200
|
-
|
201
|
-
if (thisLinkHref === activeLinkHref) {
|
202
|
-
setOnlyThisLinkActive($(this))
|
203
|
-
setActiveStepClass()
|
204
|
-
}
|
205
|
-
})
|
206
|
-
}
|
201
|
+
// tracking click events on links in step content
|
202
|
+
Gemstepnav.prototype.bindComponentLinkClicks = function (stepNavTracker) {
|
203
|
+
var jsLinks = this.$module.querySelectorAll('.js-link')
|
204
|
+
var that = this
|
207
205
|
|
208
|
-
|
209
|
-
|
210
|
-
|
206
|
+
for (var i = 0; i < jsLinks.length; i++) {
|
207
|
+
jsLinks[i].addEventListener('click', function (event) {
|
208
|
+
var dataPosition = this.getAttribute('data-position')
|
209
|
+
var linkClick = new that.ComponentLinkClick(event, stepNavTracker, dataPosition, that.$module.stepNavSize)
|
210
|
+
linkClick.trackClick()
|
211
211
|
|
212
|
-
|
213
|
-
|
214
|
-
|
212
|
+
if (this.getAttribute('rel') !== 'external') {
|
213
|
+
that.saveToSessionStorage(that.$module.sessionStoreLink, dataPosition)
|
214
|
+
}
|
215
215
|
|
216
|
-
|
217
|
-
|
218
|
-
|
216
|
+
if (this.getAttribute('href') === that.$module.activeLinkHref) {
|
217
|
+
that.setOnlyThisLinkActive(this)
|
218
|
+
that.setActiveStepClass()
|
219
|
+
}
|
220
|
+
})
|
221
|
+
}
|
222
|
+
}
|
219
223
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
}
|
224
|
+
Gemstepnav.prototype.saveToSessionStorage = function (key, value) {
|
225
|
+
window.sessionStorage.setItem(key, value)
|
226
|
+
}
|
224
227
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
// this code ensures only that link and its corresponding step have the highlighting
|
229
|
-
// otherwise it accepts what the backend has already passed to the component
|
230
|
-
function ensureOnlyOneActiveLink () {
|
231
|
-
var $activeLinks = $element.find('.js-list-item.' + activeLinkClass)
|
228
|
+
Gemstepnav.prototype.loadFromSessionStorage = function (key, value) {
|
229
|
+
return window.sessionStorage.getItem(key)
|
230
|
+
}
|
232
231
|
|
233
|
-
|
234
|
-
|
235
|
-
|
232
|
+
Gemstepnav.prototype.removeFromSessionStorage = function (key) {
|
233
|
+
window.sessionStorage.removeItem(key)
|
234
|
+
}
|
236
235
|
|
237
|
-
|
236
|
+
Gemstepnav.prototype.setOnlyThisLinkActive = function (clicked) {
|
237
|
+
var allActiveLinks = this.$module.querySelectorAll('.' + this.$module.activeLinkClass)
|
238
|
+
for (var i = 0; i < allActiveLinks.length; i++) {
|
239
|
+
allActiveLinks[i].classList.remove(this.$module.activeLinkClass)
|
240
|
+
}
|
241
|
+
clicked.parentNode.classList.add(this.$module.activeLinkClass)
|
242
|
+
}
|
238
243
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
}
|
244
|
+
// if a link occurs more than once in a step nav, the backend doesn't know which one to highlight
|
245
|
+
// so it gives all those links the 'active' attribute and highlights the last step containing that link
|
246
|
+
// if the user clicked on one of those links previously, it will be in the session store
|
247
|
+
// this code ensures only that link and its corresponding step have the highlighting
|
248
|
+
// otherwise it accepts what the backend has already passed to the component
|
249
|
+
Gemstepnav.prototype.ensureOnlyOneActiveLink = function () {
|
250
|
+
var activeLinks = this.$module.querySelectorAll('.js-list-item.' + this.$module.activeLinkClass)
|
247
251
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
$(this).removeClass(activeLinkClass)
|
252
|
-
$(this).find('.visuallyhidden').remove()
|
253
|
-
}
|
254
|
-
})
|
255
|
-
}
|
252
|
+
if (activeLinks.length <= 1) {
|
253
|
+
return
|
254
|
+
}
|
256
255
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
256
|
+
var loaded = this.loadFromSessionStorage(this.$module.sessionStoreLink)
|
257
|
+
var activeParent = this.$module.querySelectorAll('.' + this.$module.activeLinkClass)[0]
|
258
|
+
var activeChild = activeParent.firstChild
|
259
|
+
var foundLink = activeChild.getAttribute('data-position')
|
260
|
+
var lastClicked = loaded || foundLink // the value saved has priority
|
261
261
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
$element.find('.js-toggle-link').html(actions.hideText)
|
270
|
-
shouldshowAll = true
|
271
|
-
|
272
|
-
stepNavTracker.track('pageElementInteraction', 'stepNavAllShown', {
|
273
|
-
label: actions.showAllText + ': ' + stepNavSize
|
274
|
-
})
|
275
|
-
} else {
|
276
|
-
$showOrHideAllButton.text(actions.showAllText)
|
277
|
-
$element.find('.js-toggle-link').html(actions.showText)
|
278
|
-
shouldshowAll = false
|
279
|
-
|
280
|
-
stepNavTracker.track('pageElementInteraction', 'stepNavAllHidden', {
|
281
|
-
label: actions.hideAllText + ': ' + stepNavSize
|
282
|
-
})
|
283
|
-
}
|
284
|
-
|
285
|
-
setAllStepsShownState(shouldshowAll)
|
286
|
-
$showOrHideAllButton.attr('aria-expanded', shouldshowAll)
|
287
|
-
setShowHideAllText()
|
288
|
-
|
289
|
-
return false
|
290
|
-
})
|
262
|
+
// it's possible for the saved link position value to not match any of the currently duplicate highlighted links
|
263
|
+
// so check this otherwise it'll take the highlighting off all of them
|
264
|
+
var checkLink = this.$module.querySelectorAll('[data-position="' + lastClicked + '"]')[0]
|
265
|
+
|
266
|
+
if (checkLink) {
|
267
|
+
if (!checkLink.parentNode.classList.contains(this.$module.activeLinkClass)) {
|
268
|
+
lastClicked = checkLink
|
291
269
|
}
|
270
|
+
} else {
|
271
|
+
lastClicked = foundLink
|
272
|
+
}
|
273
|
+
|
274
|
+
this.removeActiveStateFromAllButCurrent(activeLinks, lastClicked)
|
275
|
+
this.setActiveStepClass()
|
276
|
+
}
|
292
277
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
278
|
+
Gemstepnav.prototype.removeActiveStateFromAllButCurrent = function (activeLinks, current) {
|
279
|
+
for (var i = 0; i < activeLinks.length; i++) {
|
280
|
+
var thisel = activeLinks[i]
|
281
|
+
if (thisel.querySelectorAll('.js-link')[0].getAttribute('data-position').toString() !== current.toString()) {
|
282
|
+
thisel.classList.remove(this.$module.activeLinkClass)
|
283
|
+
var visuallyHidden = thisel.querySelectorAll('.visuallyhidden')
|
284
|
+
if (visuallyHidden.length) {
|
285
|
+
visuallyHidden[0].parentNode.removeChild(visuallyHidden[0])
|
300
286
|
}
|
301
287
|
}
|
302
288
|
}
|
289
|
+
}
|
303
290
|
|
304
|
-
|
305
|
-
|
306
|
-
|
291
|
+
Gemstepnav.prototype.setActiveStepClass = function () {
|
292
|
+
// remove the 'active/open' state from all steps
|
293
|
+
var allActiveSteps = this.$module.querySelectorAll('.' + this.$module.activeStepClass)
|
294
|
+
for (var i = 0; i < allActiveSteps.length; i++) {
|
295
|
+
allActiveSteps[i].classList.remove(this.$module.activeStepClass)
|
296
|
+
allActiveSteps[i].removeAttribute('data-show')
|
297
|
+
}
|
307
298
|
|
308
|
-
|
309
|
-
|
299
|
+
// find the current page link and apply 'active/open' state to parent step
|
300
|
+
var activeLink = this.$module.querySelectorAll('.' + this.$module.activeLinkClass)[0]
|
301
|
+
if (activeLink) {
|
302
|
+
var activeStep = activeLink.closest('.gem-c-step-nav__step')
|
303
|
+
activeStep.classList.add(this.$module.activeStepClass)
|
304
|
+
activeStep.setAttribute('data-show', '')
|
305
|
+
}
|
306
|
+
}
|
310
307
|
|
311
|
-
|
312
|
-
|
313
|
-
this.toggle = toggle
|
314
|
-
this.setIsShown = setIsShown
|
315
|
-
this.isShown = isShown
|
316
|
-
this.isHidden = isHidden
|
317
|
-
this.numberOfContentItems = numberOfContentItems
|
308
|
+
Gemstepnav.prototype.bindToggleShowHideAllButton = function (stepNavTracker) {
|
309
|
+
var that = this
|
318
310
|
|
319
|
-
|
320
|
-
|
321
|
-
|
311
|
+
this.$module.showOrHideAllButton.addEventListener('click', function (event) {
|
312
|
+
var shouldshowAll
|
313
|
+
var showHideTexts = that.$module.querySelectorAll('.js-toggle-link')
|
314
|
+
var textContent = this.textContent || this.innerText
|
322
315
|
|
323
|
-
|
324
|
-
|
325
|
-
|
316
|
+
if (textContent === that.$module.actions.showAllText) {
|
317
|
+
that.$module.showOrHideAllButton.textContent = that.$module.actions.hideAllText
|
318
|
+
for (var i = 0; i < showHideTexts.length; i++) {
|
319
|
+
showHideTexts[i].innerHTML = that.$module.actions.hideText
|
320
|
+
}
|
321
|
+
shouldshowAll = true
|
326
322
|
|
327
|
-
|
328
|
-
|
329
|
-
|
323
|
+
stepNavTracker.trackClick('pageElementInteraction', 'stepNavAllShown', {
|
324
|
+
label: that.$module.actions.showAllText + ': ' + that.$module.stepNavSize
|
325
|
+
})
|
326
|
+
} else {
|
327
|
+
that.$module.showOrHideAllButton.textContent = that.$module.actions.showAllText
|
328
|
+
for (var j = 0; j < showHideTexts.length; j++) {
|
329
|
+
showHideTexts[j].innerHTML = that.$module.actions.showText
|
330
|
+
}
|
331
|
+
shouldshowAll = false
|
330
332
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
$titleLink.attr('aria-expanded', isShown)
|
335
|
-
$stepElement.find('.js-toggle-link').html(isShown ? actions.hideText : actions.showText)
|
333
|
+
stepNavTracker.trackClick('pageElementInteraction', 'stepNavAllHidden', {
|
334
|
+
label: that.$module.actions.hideAllText + ': ' + that.$module.stepNavSize
|
335
|
+
})
|
336
336
|
}
|
337
337
|
|
338
|
-
|
339
|
-
|
340
|
-
|
338
|
+
that.setAllStepsShownState(shouldshowAll)
|
339
|
+
that.$module.showOrHideAllButton.setAttribute('aria-expanded', shouldshowAll)
|
340
|
+
that.setShowHideAllText()
|
341
341
|
|
342
|
-
|
343
|
-
|
344
|
-
|
342
|
+
return false
|
343
|
+
})
|
344
|
+
}
|
345
345
|
|
346
|
-
|
347
|
-
|
348
|
-
|
346
|
+
Gemstepnav.prototype.setShowHideAllText = function () {
|
347
|
+
var shownSteps = this.$module.querySelectorAll('.step-is-shown').length
|
348
|
+
// Find out if the number of is-opens == total number of steps
|
349
|
+
if (shownSteps === this.$module.totalSteps) {
|
350
|
+
this.$module.showOrHideAllButton.textContent = this.$module.actions.hideAllText
|
351
|
+
} else {
|
352
|
+
this.$module.showOrHideAllButton.textContent = this.$module.actions.showAllText
|
349
353
|
}
|
354
|
+
}
|
350
355
|
|
351
|
-
|
352
|
-
|
353
|
-
|
356
|
+
Gemstepnav.prototype.StepView = function (stepElement, showText, hideText) {
|
357
|
+
this.stepElement = stepElement
|
358
|
+
this.stepContent = this.stepElement.querySelectorAll('.js-panel')[0]
|
359
|
+
this.titleButton = this.stepElement.querySelectorAll('.js-step-title-button')[0]
|
360
|
+
var textElement = this.stepElement.querySelectorAll('.js-step-title-text')[0]
|
361
|
+
this.title = textElement.textContent || textElement.innerText
|
362
|
+
this.title = this.title.replace(/^\s+|\s+$/g, '') // this is 'trim' but supporting IE8
|
363
|
+
this.showText = showText
|
364
|
+
this.hideText = hideText
|
365
|
+
|
366
|
+
this.show = function () {
|
367
|
+
this.setIsShown(true)
|
368
|
+
}
|
354
369
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
}
|
370
|
+
this.hide = function () {
|
371
|
+
this.setIsShown(false)
|
372
|
+
}
|
359
373
|
|
360
|
-
|
361
|
-
|
362
|
-
|
374
|
+
this.toggle = function () {
|
375
|
+
this.setIsShown(this.isHidden())
|
376
|
+
}
|
363
377
|
|
364
|
-
|
365
|
-
|
366
|
-
|
378
|
+
this.setIsShown = function (isShown) {
|
379
|
+
if (isShown) {
|
380
|
+
this.stepElement.classList.add('step-is-shown')
|
381
|
+
this.stepContent.classList.remove('js-hidden')
|
382
|
+
} else {
|
383
|
+
this.stepElement.classList.remove('step-is-shown')
|
384
|
+
this.stepContent.classList.add('js-hidden')
|
367
385
|
}
|
368
386
|
|
369
|
-
|
370
|
-
|
371
|
-
|
387
|
+
this.titleButton.setAttribute('aria-expanded', isShown)
|
388
|
+
var showHideText = this.stepElement.querySelectorAll('.js-toggle-link')[0]
|
389
|
+
showHideText.innerHTML = isShown ? this.hideText : this.showText
|
390
|
+
}
|
372
391
|
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
} else if (clickedOnHeading()) {
|
377
|
-
return 'Heading click'
|
378
|
-
} else {
|
379
|
-
return 'Elsewhere click'
|
380
|
-
}
|
381
|
-
}
|
392
|
+
this.isShown = function () {
|
393
|
+
return this.stepElement.classList.contains('step-is-shown')
|
394
|
+
}
|
382
395
|
|
383
|
-
|
384
|
-
|
385
|
-
|
396
|
+
this.isHidden = function () {
|
397
|
+
return !this.isShown()
|
398
|
+
}
|
386
399
|
|
387
|
-
|
388
|
-
|
389
|
-
|
400
|
+
this.numberOfContentItems = function () {
|
401
|
+
return this.stepContent.querySelectorAll('.js-link').length
|
402
|
+
}
|
403
|
+
}
|
390
404
|
|
391
|
-
|
392
|
-
|
393
|
-
|
405
|
+
Gemstepnav.prototype.StepToggleClick = function (event, stepView, stepNavTracker, stepIsOptional, stepNavSize) {
|
406
|
+
this.target = event.target
|
407
|
+
this.stepIsOptional = stepIsOptional
|
408
|
+
this.stepNavSize = stepNavSize
|
409
|
+
|
410
|
+
this.trackClick = function () {
|
411
|
+
var trackingOptions = { label: this.trackingLabel(), dimension28: stepView.numberOfContentItems().toString() }
|
412
|
+
stepNavTracker.trackClick('pageElementInteraction', this.trackingAction(), trackingOptions)
|
413
|
+
}
|
414
|
+
|
415
|
+
this.trackingLabel = function () {
|
416
|
+
var clickedNearbyToggle = this.target.closest('.js-step').querySelectorAll('.js-toggle-panel')[0]
|
417
|
+
return clickedNearbyToggle.getAttribute('data-position') + ' - ' + stepView.title + ' - ' + this.locateClickElement() + ': ' + this.stepNavSize + this.isOptional()
|
418
|
+
}
|
419
|
+
|
420
|
+
// returns index of the clicked step in the overall number of steps
|
421
|
+
this.stepIndex = function () { // eslint-disable-line no-unused-vars
|
422
|
+
return this.$module.steps.index(stepView.element) + 1
|
423
|
+
}
|
424
|
+
|
425
|
+
this.trackingAction = function () {
|
426
|
+
return (stepView.isHidden() ? 'stepNavHidden' : 'stepNavShown')
|
427
|
+
}
|
394
428
|
|
395
|
-
|
396
|
-
|
429
|
+
this.locateClickElement = function () {
|
430
|
+
if (this.clickedOnIcon()) {
|
431
|
+
return this.iconType() + ' click'
|
432
|
+
} else if (this.clickedOnHeading()) {
|
433
|
+
return 'Heading click'
|
434
|
+
} else {
|
435
|
+
return 'Elsewhere click'
|
397
436
|
}
|
398
437
|
}
|
399
438
|
|
400
|
-
function
|
401
|
-
this.
|
439
|
+
this.clickedOnIcon = function () {
|
440
|
+
return this.target.classList.contains('js-toggle-link')
|
441
|
+
}
|
402
442
|
|
403
|
-
|
404
|
-
|
405
|
-
|
443
|
+
this.clickedOnHeading = function () {
|
444
|
+
return this.target.classList.contains('js-step-title-text')
|
445
|
+
}
|
406
446
|
|
407
|
-
|
408
|
-
|
409
|
-
|
447
|
+
this.iconType = function () {
|
448
|
+
return (stepView.isHidden() ? 'Minus' : 'Plus')
|
449
|
+
}
|
450
|
+
|
451
|
+
this.isOptional = function () {
|
452
|
+
return (this.stepIsOptional ? ' ; optional' : '')
|
453
|
+
}
|
454
|
+
}
|
455
|
+
|
456
|
+
Gemstepnav.prototype.ComponentLinkClick = function (event, stepNavTracker, linkPosition, size) {
|
457
|
+
this.size = size
|
458
|
+
this.target = event.target
|
410
459
|
|
411
|
-
|
460
|
+
this.trackClick = function () {
|
461
|
+
var trackingOptions = { label: this.target.getAttribute('href') + ' : ' + this.size }
|
462
|
+
var dimension28 = this.target.closest('.gem-c-step-nav__list').getAttribute('data-length')
|
463
|
+
|
464
|
+
if (dimension28) {
|
465
|
+
trackingOptions.dimension28 = dimension28
|
412
466
|
}
|
467
|
+
|
468
|
+
stepNavTracker.trackClick('stepNavLinkClicked', linkPosition, trackingOptions)
|
413
469
|
}
|
470
|
+
}
|
414
471
|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
472
|
+
// A helper that sends a custom event request to Google Analytics if
|
473
|
+
// the GOVUK module is setup
|
474
|
+
Gemstepnav.prototype.StepNavTracker = function (uniqueId, totalSteps, totalLinks) {
|
475
|
+
this.totalSteps = totalSteps
|
476
|
+
this.totalLinks = totalLinks
|
477
|
+
this.uniqueId = uniqueId
|
478
|
+
|
479
|
+
this.trackClick = function (category, action, options) {
|
480
|
+
// dimension26 records the total number of expand/collapse steps in this step nav
|
481
|
+
// dimension27 records the total number of links in this step nav
|
482
|
+
// dimension28 records the number of links in the step that was shown/hidden (handled in click event)
|
483
|
+
if (window.GOVUK.analytics && window.GOVUK.analytics.trackEvent) {
|
484
|
+
options = options || {}
|
485
|
+
options.dimension26 = options.dimension26 || this.totalSteps.toString()
|
486
|
+
options.dimension27 = options.dimension27 || this.totalLinks.toString()
|
487
|
+
options.dimension96 = options.dimension96 || this.uniqueId
|
488
|
+
window.GOVUK.analytics.trackEvent(category, action, options)
|
429
489
|
}
|
430
490
|
}
|
431
491
|
}
|
492
|
+
|
493
|
+
Modules.Gemstepnav = Gemstepnav
|
432
494
|
})(window.GOVUK.Modules)
|