1
+ import { isNotNull } from './utils'
1
2
import { TEXT_NODE } from './helpers'
2
3
3
4
const labelledNodeNames = [
@@ -10,7 +11,9 @@ const labelledNodeNames = [
10
11
'input' ,
11
12
]
12
13
13
- function getTextContent ( node ) {
14
+ function getTextContent (
15
+ node : Node | Element | HTMLInputElement ,
16
+ ) : string | null {
14
17
if ( labelledNodeNames . includes ( node . nodeName . toLowerCase ( ) ) ) {
15
18
return ''
16
19
}
@@ -22,37 +25,46 @@ function getTextContent(node) {
22
25
. join ( '' )
23
26
}
24
27
25
- function getLabelContent ( node ) {
28
+ function getLabelContent ( node : Node | Element | HTMLInputElement ) {
26
29
let textContent
27
- if ( node . tagName . toLowerCase ( ) === 'label' ) {
30
+ if ( 'tagName' in node && node . tagName . toLowerCase ( ) === 'label' ) {
28
31
textContent = getTextContent ( node )
32
+ } else if ( 'value' in node ) {
33
+ textContent = node . value
29
34
} else {
30
- textContent = node . value || node . textContent
35
+ textContent = node . textContent
31
36
}
32
37
return textContent
33
38
}
34
39
35
40
// Based on https://github.com/eps1lon/dom-accessibility-api/pull/352
36
- function getRealLabels ( element ) {
37
- if ( element . labels !== undefined ) return element . labels ?? [ ]
41
+ function getRealLabels ( element : Element | HTMLInputElement ) {
42
+ // for old browsers
43
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
44
+ if ( 'labels' in element && element . labels !== undefined )
45
+ return element . labels ?? [ ]
38
46
39
47
if ( ! isLabelable ( element ) ) return [ ]
40
48
41
49
const labels = element . ownerDocument . querySelectorAll ( 'label' )
42
50
return Array . from ( labels ) . filter ( label => label . control === element )
43
51
}
44
52
45
- function isLabelable ( element ) {
53
+ function isLabelable ( element : Element ) {
54
+ const labelableRegex = / B U T T O N | M E T E R | O U T P U T | P R O G R E S S | S E L E C T | T E X T A R E A /
46
55
return (
47
- element . tagName . match ( / B U T T O N | M E T E R | O U T P U T | P R O G R E S S | S E L E C T | T E X T A R E A / ) ||
56
+ labelableRegex . test ( element . tagName ) ||
48
57
( element . tagName === 'INPUT' && element . getAttribute ( 'type' ) !== 'hidden' )
49
58
)
50
59
}
51
60
52
- function getLabels ( container , element , { selector = '*' } = { } ) {
53
- const labelsId = element . getAttribute ( 'aria-labelledby' )
54
- ? element . getAttribute ( 'aria-labelledby' ) . split ( ' ' )
55
- : [ ]
61
+ function getLabels (
62
+ container : Element ,
63
+ element : Element ,
64
+ { selector = '*' } = { } ,
65
+ ) {
66
+ const ariaLabelledBy = element . getAttribute ( 'aria-labelledby' )
67
+ const labelsId = isNotNull ( ariaLabelledBy ) ? ariaLabelledBy . split ( ' ' ) : [ ]
56
68
return labelsId . length
57
69
? labelsId . map ( labelId => {
58
70
const labellingElement = container . querySelector ( `[id="${ labelId } "]` )
@@ -67,7 +79,6 @@ function getLabels(container, element, {selector = '*'} = {}) {
67
79
const labelledFormControl = Array . from (
68
80
label . querySelectorAll ( formControlSelector ) ,
69
81
) . filter ( formControlElement => formControlElement . matches ( selector ) ) [ 0 ]
70
-
71
82
return { content : textToMatch , formControl : labelledFormControl }
72
83
} )
73
84
}
0 commit comments