@ -81,8 +81,6 @@ export function set_checked(element, checked) {
* @ param { boolean } [ skip _warning ]
* /
export function set _attribute ( element , attribute , value , skip _warning ) {
value = value == null ? null : value + '' ;
// @ts-expect-error
var attributes = ( element . _ _attributes ? ? = { } ) ;
@ -95,7 +93,7 @@ export function set_attribute(element, attribute, value, skip_warning) {
( attribute === 'href' && element . nodeName === 'LINK' )
) {
if ( ! skip _warning ) {
check _src _in _dev _hydration ( element , attribute , value ) ;
check _src _in _dev _hydration ( element , attribute , value ? ? '' ) ;
}
// If we reset these attributes, they would result in another network request, which we want to avoid.
@ -113,8 +111,11 @@ export function set_attribute(element, attribute, value, skip_warning) {
element [ LOADING _ATTR _SYMBOL ] = value ;
}
if ( value == = null ) {
if ( value == null ) {
element . removeAttribute ( attribute ) ;
} else if ( typeof value !== 'string' && get _setters ( element ) . includes ( attribute ) ) {
// @ts-ignore
element [ attribute ] = value ;
} else {
element . setAttribute ( attribute , value ) ;
}
@ -135,18 +136,8 @@ export function set_xlink_attribute(dom, attribute, value) {
* @ param { any } value
* /
export function set _custom _element _data ( node , prop , value ) {
if ( prop in node ) {
// Reading the prop could cause an error, we don't want this to fail everything else
try {
var curr _val = node [ prop ] ;
} catch {
set _attribute ( node , prop , value ) ;
return ;
}
var next _val = typeof curr _val === 'boolean' && value === '' ? true : value ;
if ( typeof curr _val !== 'object' || curr _val !== next _val ) {
node [ prop ] = next _val ;
}
if ( get _setters ( node ) . includes ( prop ) ) {
node [ prop ] = value ;
} else {
set _attribute ( node , prop , value ) ;
}
@ -160,6 +151,7 @@ export function set_custom_element_data(node, prop, value) {
* @ param { string } [ css _hash ]
* @ param { boolean } preserve _attribute _case
* @ param { boolean } [ skip _warning ]
* @ param { boolean } [ is _custom _element ]
* @ returns { Record < string , any > }
* /
export function set _attributes (
@ -168,7 +160,8 @@ export function set_attributes(
next ,
css _hash ,
preserve _attribute _case = false ,
skip _warning
skip _warning = false ,
is _custom _element = false
) {
var current = prev || { } ;
var is _option _element = element . tagName === 'OPTION' ;
@ -183,8 +176,7 @@ export function set_attributes(
next . class = next . class ? next . class + ' ' + css _hash : css _hash ;
}
var setters = setters _cache . get ( element . nodeName ) ;
if ( ! setters ) setters _cache . set ( element . nodeName , ( setters = get _setters ( element ) ) ) ;
var setters = get _setters ( element ) ;
// @ts-expect-error
var attributes = /** @type {Record<string, unknown>} **/ ( element . _ _attributes ? ? = { } ) ;
@ -271,14 +263,11 @@ export function set_attributes(
delegate ( [ event _name ] ) ;
}
}
} else if ( value == null ) {
attributes [ key ] = null ;
element . removeAttribute ( key ) ;
} else if ( key === 'style' ) {
} else if ( key === 'style' && value != null ) {
element . style . cssText = value + '' ;
} else if ( key === 'autofocus' ) {
autofocus ( /** @type {HTMLElement} */ ( element ) , Boolean ( value ) ) ;
} else if ( key === '__value' || key === 'value' ) {
} else if ( key === '__value' || ( key === 'value' && value != null ) ) {
// @ts-ignore
element . value = element [ key ] = element . _ _value = value ;
} else {
@ -287,15 +276,18 @@ export function set_attributes(
name = normalize _attribute ( name ) ;
}
if ( setters . includes ( name ) ) {
if ( value == null && ! is _custom _element ) {
attributes [ key ] = null ;
element . removeAttribute ( key ) ;
} else if ( setters . includes ( name ) && ( is _custom _element || typeof value !== 'string' ) ) {
// @ts-ignore
element [ name ] = value ;
} else if ( typeof value !== 'function' ) {
if ( hydrating && ( name === 'src' || name === 'href' || name === 'srcset' ) ) {
if ( ! skip _warning ) check _src _in _dev _hydration ( element , name , value ) ;
if ( ! skip _warning ) check _src _in _dev _hydration ( element , name , value ? ? '' ) ;
} else {
// @ts-ignore
element [ name ] = value ;
set _attribute ( element , name , value ) ;
}
} else if ( typeof value !== 'function' ) {
set _attribute ( element , name , value ) ;
}
}
}
@ -316,57 +308,14 @@ export function set_attributes(
return current ;
}
/ * *
* @ param { Element } node
* @ param { Record < string , any > | undefined } prev
* @ param { Record < string , any > } next The new attributes - this function mutates this object
* @ param { string } [ css _hash ]
* /
export function set _dynamic _element _attributes ( node , prev , next , css _hash ) {
if ( node . tagName . includes ( '-' ) ) {
for ( var key in prev ) {
if ( ! ( key in next ) ) {
next [ key ] = null ;
}
}
if ( css _hash !== undefined ) {
next . class = next . class ? next . class + ' ' + css _hash : css _hash ;
}
for ( key in next ) {
set _custom _element _data ( node , key , next [ key ] ) ;
}
return next ;
}
return set _attributes (
/** @type {Element & ElementCSSInlineStyle} */ ( node ) ,
prev ,
next ,
css _hash ,
node . namespaceURI !== NAMESPACE _SVG
) ;
}
/ * *
* List of attributes that should always be set through the attr method ,
* because updating them through the property setter doesn ' t work reliably .
* In the example of ` width ` / ` height ` , the problem is that the setter only
* accepts numeric values , but the attribute can also be set to a string like ` 50% ` .
* In case of draggable trying to set ` element.draggable='false' ` will actually set
* draggable to ` true ` . If this list becomes too big , rethink this approach .
* /
var always _set _through _set _attribute = [ 'width' , 'height' , 'draggable' ] ;
/** @type {Map<string, string[]>} */
var setters _cache = new Map ( ) ;
/** @param {Element} element */
function get _setters ( element ) {
/** @type {string[]} */
var setters = [ ] ;
var setters = setters _cache . get ( element . nodeName ) ;
if ( setters ) return setters ;
setters _cache . set ( element . nodeName , ( setters = [ ] ) ) ;
var descriptors ;
var proto = get _prototype _of ( element ) ;
@ -375,7 +324,7 @@ function get_setters(element) {
descriptors = get _descriptors ( proto ) ;
for ( var key in descriptors ) {
if ( descriptors [ key ] . set && ! always _set _through _set _attribute . includes ( key ) ) {
if ( descriptors [ key ] . set ) {
setters . push ( key ) ;
}
}
@ -389,12 +338,12 @@ function get_setters(element) {
/ * *
* @ param { any } element
* @ param { string } attribute
* @ param { string | null } value
* @ param { string } value
* /
function check _src _in _dev _hydration ( element , attribute , value ) {
if ( ! DEV ) return ;
if ( attribute === 'srcset' && srcset _url _equal ( element , value ) ) return ;
if ( src _url _equal ( element . getAttribute ( attribute ) ? ? '' , value ? ? '' ) ) return ;
if ( src _url _equal ( element . getAttribute ( attribute ) ? ? '' , value ) ) return ;
w . hydration _attribute _changed (
attribute ,
@ -420,12 +369,12 @@ function split_srcset(srcset) {
/ * *
* @ param { HTMLSourceElement | HTMLImageElement } element
* @ param { string | undefined | null } srcset
* @ param { string } srcset
* @ returns { boolean }
* /
function srcset _url _equal ( element , srcset ) {
var element _urls = split _srcset ( element . srcset ) ;
var urls = split _srcset ( srcset ? ? '' ) ;
var urls = split _srcset ( srcset ) ;
return (
urls . length === element _urls . length &&