@@ -38,10 +38,14 @@ var ACCORDION_TRANSLATIONS = {
38
38
* attribute, which also provides accessibility.
39
39
*
40
40
* @class
41
- * @param {HTMLElement } $module - HTML element to use for accordion
41
+ * @param {Element } $module - HTML element to use for accordion
42
42
* @param {AccordionConfig } [config] - Accordion config
43
43
*/
44
44
function Accordion ( $module , config ) {
45
+ if ( ! $module ) {
46
+ return this
47
+ }
48
+
45
49
this . $module = $module
46
50
47
51
var defaultConfig = {
@@ -79,16 +83,21 @@ function Accordion ($module, config) {
79
83
this . sectionSummaryFocusClass = 'govuk-accordion__section-summary-focus'
80
84
this . sectionContentClass = 'govuk-accordion__section-content'
81
85
82
- this . $sections = this . $module . querySelectorAll ( '.' + this . sectionClass )
86
+ var $sections = this . $module . querySelectorAll ( '.' + this . sectionClass )
87
+ if ( ! $sections . length ) {
88
+ return this
89
+ }
90
+
91
+ this . $sections = $sections
83
92
this . browserSupportsSessionStorage = helper . checkForSessionStorage ( )
84
93
}
85
94
86
95
/**
87
96
* Initialise component
88
97
*/
89
98
Accordion . prototype . init = function ( ) {
90
- // Check for module
91
- if ( ! this . $module ) {
99
+ // Check that required elements are present
100
+ if ( ! this . $module || ! this . $sections ) {
92
101
return
93
102
}
94
103
@@ -145,6 +154,9 @@ Accordion.prototype.initSectionHeaders = function () {
145
154
// Loop through sections
146
155
nodeListForEach ( $sections , function ( $section , i ) {
147
156
var $header = $section . querySelector ( '.' + $component . sectionHeaderClass )
157
+ if ( ! $header ) {
158
+ return
159
+ }
148
160
149
161
// Set header attributes
150
162
$component . constructHeaderMarkup ( $header , i )
@@ -162,14 +174,18 @@ Accordion.prototype.initSectionHeaders = function () {
162
174
/**
163
175
* Construct section header
164
176
*
165
- * @param {HTMLElement } $header - Section header
177
+ * @param {Element } $header - Section header
166
178
* @param {number } index - Section index
167
179
*/
168
180
Accordion . prototype . constructHeaderMarkup = function ( $header , index ) {
169
181
var $span = $header . querySelector ( '.' + this . sectionButtonClass )
170
182
var $heading = $header . querySelector ( '.' + this . sectionHeadingClass )
171
183
var $summary = $header . querySelector ( '.' + this . sectionSummaryClass )
172
184
185
+ if ( ! $span || ! $heading ) {
186
+ return
187
+ }
188
+
173
189
// Create a button element that will replace the '.govuk-accordion__section-button' span
174
190
var $button = document . createElement ( 'button' )
175
191
$button . setAttribute ( 'type' , 'button' )
@@ -227,7 +243,7 @@ Accordion.prototype.constructHeaderMarkup = function ($header, index) {
227
243
$button . appendChild ( this . getButtonPunctuationEl ( ) )
228
244
229
245
// If summary content exists add to DOM in correct order
230
- if ( typeof ( $summary ) !== 'undefined' && $summary !== null ) {
246
+ if ( $summary ) {
231
247
// Create a new `span` element and copy the summary line content from the original `div` to the
232
248
// new `span`
233
249
// This is because the summary line text is now inside a button element, which can only contain
@@ -267,7 +283,13 @@ Accordion.prototype.constructHeaderMarkup = function ($header, index) {
267
283
* @param {Event } event - Generic event
268
284
*/
269
285
Accordion . prototype . onBeforeMatch = function ( event ) {
270
- var $section = event . target . closest ( '.' + this . sectionClass )
286
+ var $fragment = event . target
287
+ if ( ! $fragment ) {
288
+ return
289
+ }
290
+
291
+ // Handle when fragment is inside section
292
+ var $section = $fragment . closest ( '.' + this . sectionClass )
271
293
if ( $section ) {
272
294
this . setExpanded ( true , $section )
273
295
}
@@ -276,7 +298,7 @@ Accordion.prototype.onBeforeMatch = function (event) {
276
298
/**
277
299
* When section toggled, set and store state
278
300
*
279
- * @param {HTMLElement } $section - Section element
301
+ * @param {Element } $section - Section element
280
302
*/
281
303
Accordion . prototype . onSectionToggle = function ( $section ) {
282
304
var expanded = this . isExpanded ( $section )
@@ -309,14 +331,21 @@ Accordion.prototype.onShowOrHideAllToggle = function () {
309
331
* Set section attributes when opened/closed
310
332
*
311
333
* @param {boolean } expanded - Section expanded
312
- * @param {HTMLElement } $section - Section element
334
+ * @param {Element } $section - Section element
313
335
*/
314
336
Accordion . prototype . setExpanded = function ( expanded , $section ) {
315
337
var $showHideIcon = $section . querySelector ( '.' + this . upChevronIconClass )
316
338
var $showHideText = $section . querySelector ( '.' + this . sectionShowHideTextClass )
317
339
var $button = $section . querySelector ( '.' + this . sectionButtonClass )
318
340
var $content = $section . querySelector ( '.' + this . sectionContentClass )
319
341
342
+ if ( ! $showHideIcon ||
343
+ ! $showHideText ||
344
+ ! $button ||
345
+ ! $content ) {
346
+ return
347
+ }
348
+
320
349
var newButtonText = expanded
321
350
? this . i18n . t ( 'hideSection' )
322
351
: this . i18n . t ( 'showSection' )
@@ -368,7 +397,7 @@ Accordion.prototype.setExpanded = function (expanded, $section) {
368
397
/**
369
398
* Get state of section
370
399
*
371
- * @param {HTMLElement } $section - Section element
400
+ * @param {Element } $section - Section element
372
401
* @returns {boolean } True if expanded
373
402
*/
374
403
Accordion . prototype . isExpanded = function ( $section ) {
@@ -434,7 +463,7 @@ var helper = {
434
463
/**
435
464
* Set the state of the accordions in sessionStorage
436
465
*
437
- * @param {HTMLElement } $section - Section element
466
+ * @param {Element } $section - Section element
438
467
*/
439
468
Accordion . prototype . storeState = function ( $section ) {
440
469
if ( this . browserSupportsSessionStorage ) {
@@ -458,7 +487,7 @@ Accordion.prototype.storeState = function ($section) {
458
487
/**
459
488
* Read the state of the accordions from sessionStorage
460
489
*
461
- * @param {HTMLElement } $section - Section element
490
+ * @param {Element } $section - Section element
462
491
*/
463
492
Accordion . prototype . setInitialState = function ( $section ) {
464
493
if ( this . browserSupportsSessionStorage ) {
@@ -482,7 +511,7 @@ Accordion.prototype.setInitialState = function ($section) {
482
511
* into thematic chunks.
483
512
* See https://github.com/alphagov/govuk-frontend/issues/2327#issuecomment-922957442
484
513
*
485
- * @returns {HTMLElement } DOM element
514
+ * @returns {Element } DOM element
486
515
*/
487
516
Accordion . prototype . getButtonPunctuationEl = function ( ) {
488
517
var $punctuationEl = document . createElement ( 'span' )
0 commit comments