7
7
8
8
import type { LightningElement } from './lightning-element' ;
9
9
10
- const MULTI_SPACE = / \s + / g;
11
-
12
10
// Copied from lib.dom
13
11
interface DOMTokenList {
14
12
readonly length : number ;
@@ -28,6 +26,15 @@ interface DOMTokenList {
28
26
[ index : number ] : string ;
29
27
}
30
28
29
+ const MULTI_SPACE = / \s + / g;
30
+
31
+ function parseClassName ( className : string | null ) : string [ ] {
32
+ return ( className ?? '' )
33
+ . split ( MULTI_SPACE )
34
+ . map ( ( item ) => item . trim ( ) )
35
+ . filter ( Boolean ) ;
36
+ }
37
+
31
38
export class ClassList implements DOMTokenList {
32
39
el : LightningElement ;
33
40
@@ -36,22 +43,19 @@ export class ClassList implements DOMTokenList {
36
43
}
37
44
38
45
add ( ...newClassNames : string [ ] ) {
39
- const className = this . el . className ;
40
- const set = new Set ( className . split ( MULTI_SPACE ) . filter ( Boolean ) ) ;
46
+ const set = new Set ( parseClassName ( this . el . className ) ) ;
41
47
for ( const newClassName of newClassNames ) {
42
48
set . add ( newClassName ) ;
43
49
}
44
50
this . el . className = Array . from ( set ) . join ( ' ' ) ;
45
51
}
46
52
47
53
contains ( className : string ) {
48
- const currentClassNameStr = this . el . className ;
49
- return currentClassNameStr . split ( MULTI_SPACE ) . includes ( className ) ;
54
+ return parseClassName ( this . el . className ) . includes ( className ) ;
50
55
}
51
56
52
57
remove ( ...classNamesToRemove : string [ ] ) {
53
- const className = this . el . className ;
54
- const set = new Set ( className . split ( MULTI_SPACE ) . filter ( Boolean ) ) ;
58
+ const set = new Set ( parseClassName ( this . el . className ) ) ;
55
59
for ( const newClassName of classNamesToRemove ) {
56
60
set . delete ( newClassName ) ;
57
61
}
@@ -60,8 +64,7 @@ export class ClassList implements DOMTokenList {
60
64
61
65
replace ( oldClassName : string , newClassName : string ) {
62
66
let classWasReplaced = false ;
63
- const className = this . el . className ;
64
- const listOfClasses = className . split ( MULTI_SPACE ) . filter ( Boolean ) as string [ ] ;
67
+ const listOfClasses = parseClassName ( this . el . className ) ;
65
68
listOfClasses . forEach ( ( value , idx ) => {
66
69
if ( value === oldClassName ) {
67
70
classWasReplaced = true ;
@@ -73,8 +76,7 @@ export class ClassList implements DOMTokenList {
73
76
}
74
77
75
78
toggle ( classNameToToggle : string , force ?: boolean ) {
76
- const classNameStr = this . el . className ;
77
- const set = new Set ( classNameStr . split ( MULTI_SPACE ) . filter ( Boolean ) ) ;
79
+ const set = new Set ( parseClassName ( this . el . className ) ) ;
78
80
if ( ! set . has ( classNameToToggle ) && force !== false ) {
79
81
set . add ( classNameToToggle ) ;
80
82
} else if ( set . has ( classNameToToggle ) && force !== true ) {
@@ -93,22 +95,28 @@ export class ClassList implements DOMTokenList {
93
95
}
94
96
95
97
get length ( ) : number {
96
- const currentClassNameStr = this . el . className ?? '' ;
97
- return currentClassNameStr . split ( MULTI_SPACE ) . length ;
98
+ return parseClassName ( this . el . className ) . length ;
98
99
}
99
100
100
101
// Stubs to satisfy DOMTokenList interface
101
102
[ index : number ] : never ; // Can't implement arbitrary index getters without a proxy
102
- item ( _index : number ) : string | null {
103
- throw new Error ( 'Method "item" not implemented.' ) ;
104
- }
105
- supports ( _token : string ) : boolean {
106
- throw new Error ( 'Method "supports" not implemented.' ) ;
103
+
104
+ item ( index : number ) : string | null {
105
+ return parseClassName ( this . el . className ?? '' ) [ index ] ?? null ;
107
106
}
107
+
108
108
forEach (
109
- _callbackfn : ( value : string , key : number , parent : DOMTokenList ) => void ,
110
- _thisArg ?: any
109
+ callbackFn : ( value : string , key : number , parent : DOMTokenList ) => void ,
110
+ thisArg ?: any
111
111
) : void {
112
- throw new Error ( 'Method "forEach" not implemented.' ) ;
112
+ parseClassName ( this . el . className ) . forEach ( ( value , index ) =>
113
+ callbackFn . call ( thisArg , value , index , this )
114
+ ) ;
115
+ }
116
+
117
+ // This method is present on DOMTokenList but throws an error in the browser when used
118
+ // in connection with Element#classList.
119
+ supports ( _token : string ) : boolean {
120
+ throw new TypeError ( 'DOMTokenList has no supported tokens.' ) ;
113
121
}
114
122
}
0 commit comments