77
88import type { LightningElement } from './lightning-element' ;
99
10- const MULTI_SPACE = / \s + / g;
11-
1210// Copied from lib.dom
1311interface DOMTokenList {
1412 readonly length : number ;
@@ -28,6 +26,15 @@ interface DOMTokenList {
2826 [ index : number ] : string ;
2927}
3028
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+
3138export class ClassList implements DOMTokenList {
3239 el : LightningElement ;
3340
@@ -36,22 +43,19 @@ export class ClassList implements DOMTokenList {
3643 }
3744
3845 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 ) ) ;
4147 for ( const newClassName of newClassNames ) {
4248 set . add ( newClassName ) ;
4349 }
4450 this . el . className = Array . from ( set ) . join ( ' ' ) ;
4551 }
4652
4753 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 ) ;
5055 }
5156
5257 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 ) ) ;
5559 for ( const newClassName of classNamesToRemove ) {
5660 set . delete ( newClassName ) ;
5761 }
@@ -60,8 +64,7 @@ export class ClassList implements DOMTokenList {
6064
6165 replace ( oldClassName : string , newClassName : string ) {
6266 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 ) ;
6568 listOfClasses . forEach ( ( value , idx ) => {
6669 if ( value === oldClassName ) {
6770 classWasReplaced = true ;
@@ -73,8 +76,7 @@ export class ClassList implements DOMTokenList {
7376 }
7477
7578 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 ) ) ;
7880 if ( ! set . has ( classNameToToggle ) && force !== false ) {
7981 set . add ( classNameToToggle ) ;
8082 } else if ( set . has ( classNameToToggle ) && force !== true ) {
@@ -93,22 +95,28 @@ export class ClassList implements DOMTokenList {
9395 }
9496
9597 get length ( ) : number {
96- const currentClassNameStr = this . el . className ?? '' ;
97- return currentClassNameStr . split ( MULTI_SPACE ) . length ;
98+ return parseClassName ( this . el . className ) . length ;
9899 }
99100
100101 // Stubs to satisfy DOMTokenList interface
101102 [ 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 ;
107106 }
107+
108108 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
111111 ) : 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.' ) ;
113121 }
114122}
0 commit comments