@@ -25,7 +25,7 @@ const primitives: Record<string, unknown> = {
25
25
const rboolean =
26
26
/ ^ (?: a u t o f o c u s | a u t o p l a y | a s y n c | c h e c k e d | c o n t r o l s | d e f e r | d i s a b l e d | h i d d e n | l o o p | m u l t i p l e | o p e n | r e a d o n l y | r e q u i r e d | s c o p e d | s e l e c t e d ) $ / i;
27
27
// Matches strings that look like JSON objects or arrays
28
- const rbrace = / ^ (?: { [ \w \W ] * } | \[ [ \w \W ] * ] ) $ / ;
28
+ const rbrace = / ^ { [ ^ ] * } $ | ^ \[ [ ^ ] * ] $ / ;
29
29
30
30
/**
31
31
* Gets a node's attribute. For boolean attributes, it will return the value's
@@ -39,11 +39,20 @@ const rbrace = /^(?:{[\w\W]*}|\[[\w\W]*])$/;
39
39
* @param name - Name of the attribute.
40
40
* @returns The attribute's value.
41
41
*/
42
- function getAttr ( elem : Node , name : undefined ) : Record < string , string > ;
43
- function getAttr ( elem : Node , name : string ) : string | undefined ;
44
42
function getAttr (
45
43
elem : Node ,
46
- name : string | undefined
44
+ name : undefined ,
45
+ xmlMode ?: boolean
46
+ ) : Record < string , string > ;
47
+ function getAttr (
48
+ elem : Node ,
49
+ name : string ,
50
+ xmlMode ?: boolean
51
+ ) : string | undefined ;
52
+ function getAttr (
53
+ elem : Node ,
54
+ name : string | undefined ,
55
+ xmlMode ?: boolean
47
56
) : Record < string , string > | string | undefined {
48
57
if ( ! elem || ! isTag ( elem ) ) return undefined ;
49
58
@@ -56,7 +65,7 @@ function getAttr(
56
65
57
66
if ( hasOwn . call ( elem . attribs , name ) ) {
58
67
// Get the (decoded) attribute
59
- return rboolean . test ( name ) ? name : elem . attribs [ name ] ;
68
+ return ! xmlMode && rboolean . test ( name ) ? name : elem . attribs [ name ] ;
60
69
}
61
70
62
71
// Mimic the DOM and return text content as value for `option's`
@@ -210,7 +219,9 @@ export function attr<T extends Node>(
210
219
} ) ;
211
220
}
212
221
213
- return arguments . length > 1 ? this : getAttr ( this [ 0 ] , name as string ) ;
222
+ return arguments . length > 1
223
+ ? this
224
+ : getAttr ( this [ 0 ] , name as string , this . options . xmlMode ) ;
214
225
}
215
226
216
227
/**
@@ -224,16 +235,17 @@ export function attr<T extends Node>(
224
235
*/
225
236
function getProp (
226
237
el : Node | undefined ,
227
- name : string
238
+ name : string ,
239
+ xmlMode ?: boolean
228
240
) : string | undefined | Element [ keyof Element ] {
229
241
if ( ! el || ! isTag ( el ) ) return ;
230
242
231
243
return name in el
232
244
? // @ts -expect-error TS doesn't like us accessing the value directly here.
233
245
el [ name ]
234
- : rboolean . test ( name )
235
- ? getAttr ( el , name ) !== undefined
236
- : getAttr ( el , name ) ;
246
+ : ! xmlMode && rboolean . test ( name )
247
+ ? getAttr ( el , name , false ) !== undefined
248
+ : getAttr ( el , name , xmlMode ) ;
237
249
}
238
250
239
251
/**
@@ -244,12 +256,16 @@ function getProp(
244
256
* @param name - The prop's name.
245
257
* @param value - The prop's value.
246
258
*/
247
- function setProp ( el : Element , name : string , value : unknown ) {
259
+ function setProp ( el : Element , name : string , value : unknown , xmlMode ?: boolean ) {
248
260
if ( name in el ) {
249
261
// @ts -expect-error Overriding value
250
262
el [ name ] = value ;
251
263
} else {
252
- setAttr ( el , name , rboolean . test ( name ) ? ( value ? '' : null ) : `${ value } ` ) ;
264
+ setAttr (
265
+ el ,
266
+ name ,
267
+ ! xmlMode && rboolean . test ( name ) ? ( value ? '' : null ) : `${ value } `
268
+ ) ;
253
269
}
254
270
}
255
271
@@ -353,7 +369,7 @@ export function prop<T extends Node>(
353
369
return this . html ( ) ;
354
370
355
371
default :
356
- return getProp ( this [ 0 ] , name ) ;
372
+ return getProp ( this [ 0 ] , name , this . options . xmlMode ) ;
357
373
}
358
374
}
359
375
@@ -363,7 +379,13 @@ export function prop<T extends Node>(
363
379
throw new Error ( 'Bad combination of arguments.' ) ;
364
380
}
365
381
return domEach ( this , ( el , i ) => {
366
- if ( isTag ( el ) ) setProp ( el , name , value . call ( el , i , getProp ( el , name ) ) ) ;
382
+ if ( isTag ( el ) )
383
+ setProp (
384
+ el ,
385
+ name ,
386
+ value . call ( el , i , getProp ( el , name , this . options . xmlMode ) ) ,
387
+ this . options . xmlMode
388
+ ) ;
367
389
} ) ;
368
390
}
369
391
@@ -373,10 +395,10 @@ export function prop<T extends Node>(
373
395
if ( typeof name === 'object' ) {
374
396
Object . keys ( name ) . forEach ( ( key ) => {
375
397
const val = name [ key ] ;
376
- setProp ( el , key , val ) ;
398
+ setProp ( el , key , val , this . options . xmlMode ) ;
377
399
} ) ;
378
400
} else {
379
- setProp ( el , name , value ) ;
401
+ setProp ( el , name , value , this . options . xmlMode ) ;
380
402
}
381
403
} ) ;
382
404
}
@@ -810,8 +832,8 @@ export function addClass<T extends Node, R extends ArrayLike<T>>(
810
832
// If selected element isn't a tag, move on
811
833
if ( ! isTag ( el ) ) continue ;
812
834
813
- // If we don't already have classes
814
- const className = getAttr ( el , 'class' ) ;
835
+ // If we don't already have classes — always set xmlMode to false here, as it doesn't matter for classes
836
+ const className = getAttr ( el , 'class' , false ) ;
815
837
816
838
if ( ! className ) {
817
839
setAttr ( el , 'class' , classNames . join ( ' ' ) . trim ( ) ) ;
0 commit comments