@@ -31,20 +31,14 @@ const IS_CUSTOM_ELEMENT = Symbol('is custom element');
3131const IS_HTML = Symbol ( 'is html' ) ;
3232
3333/**
34- * The value/checked attribute in the template actually corresponds to the defaultValue property,
35- * so we need to remove it upon hydration to avoid a bug when someone resets the form value,
36- * unless the property is presented in the spreaded objects and is handled by `set_attributes()`
34+ * The value/checked attribute in the template actually corresponds to the defaultValue property, so we need to remove
35+ * it upon hydration to avoid a bug when someone resets the form value
3736 * @param {HTMLInputElement } input
38- * @param {Record<string, any> } [spread]
3937 * @returns {void }
4038 */
41- export function remove_input_defaults ( input , spread ) {
39+ export function remove_input_defaults ( input ) {
4240 if ( ! hydrating ) return ;
4341
44- if ( spread && ( input . type === 'checkbox' ? 'defaultChecked' : 'defaultValue' ) in spread ) {
45- return ;
46- }
47-
4842 var already_removed = false ;
4943
5044 // We try and remove the default attributes later, rather than sync during hydration.
@@ -274,10 +268,30 @@ export function set_custom_element_data(node, prop, value) {
274268 * @param {Record<string | symbol, any> | undefined } prev
275269 * @param {Record<string | symbol, any> } next New attributes - this function mutates this object
276270 * @param {string } [css_hash]
271+ * @param {boolean } [should_remove_defaults]
277272 * @param {boolean } [skip_warning]
278273 * @returns {Record<string, any> }
279274 */
280- export function set_attributes ( element , prev , next , css_hash , skip_warning = false ) {
275+ export function set_attributes (
276+ element ,
277+ prev ,
278+ next ,
279+ css_hash ,
280+ should_remove_defaults = false ,
281+ skip_warning = false
282+ ) {
283+ // prettier-ignore
284+ if (
285+ hydrating &&
286+ should_remove_defaults &&
287+ element . tagName === 'INPUT' &&
288+ ( /** @type {HTMLInputElement } */ ( element ) . type === 'checkbox'
289+ ? ! ( 'defaultChecked' in next )
290+ : ! ( 'defaultValue' in next ) )
291+ ) {
292+ remove_input_defaults ( /** @type {HTMLInputElement } */ ( element ) ) ;
293+ }
294+
281295 var attributes = get_attributes ( element ) ;
282296
283297 var is_custom_element = attributes [ IS_CUSTOM_ELEMENT ] ;
@@ -471,6 +485,7 @@ export function set_attributes(element, prev, next, css_hash, skip_warning = fal
471485 * @param {Array<() => any> } sync
472486 * @param {Array<() => Promise<any>> } async
473487 * @param {string } [css_hash]
488+ * @param {boolean } [should_remove_defaults]
474489 * @param {boolean } [skip_warning]
475490 */
476491export function attribute_effect (
@@ -479,6 +494,7 @@ export function attribute_effect(
479494 sync = [ ] ,
480495 async = [ ] ,
481496 css_hash ,
497+ should_remove_defaults = false ,
482498 skip_warning = false
483499) {
484500 flatten ( sync , async , ( values ) => {
@@ -494,7 +510,14 @@ export function attribute_effect(
494510 block ( ( ) => {
495511 var next = fn ( ...values . map ( get ) ) ;
496512 /** @type {Record<string | symbol, any> } */
497- var current = set_attributes ( element , prev , next , css_hash , skip_warning ) ;
513+ var current = set_attributes (
514+ element ,
515+ prev ,
516+ next ,
517+ css_hash ,
518+ should_remove_defaults ,
519+ skip_warning
520+ ) ;
498521
499522 if ( inited && is_select && 'value' in next ) {
500523 select_option ( /** @type {HTMLSelectElement } */ ( element ) , next . value ) ;
0 commit comments