@@ -444,20 +444,22 @@ export function class_toggle(dom, class_name, value) {
444
444
* @template V
445
445
* @param {HTMLSelectElement } select
446
446
* @param {V } value
447
+ * @param {boolean } [mounting]
447
448
*/
448
- export function select_option ( select , value ) {
449
+ export function select_option ( select , value , mounting ) {
449
450
if ( select . multiple ) {
450
451
return select_options ( select , value ) ;
451
452
}
452
- for ( let i = 0 ; i < select . options . length ; i += 1 ) {
453
- const option = select . options [ i ] ;
453
+ for ( const option of select . options ) {
454
454
const option_value = get_option_value ( option ) ;
455
455
if ( option_value === value ) {
456
456
option . selected = true ;
457
457
return ;
458
458
}
459
459
}
460
- select . value = '' ;
460
+ if ( ! mounting || value !== undefined ) {
461
+ select . value = '' ;
462
+ }
461
463
}
462
464
463
465
/**
@@ -466,8 +468,7 @@ export function select_option(select, value) {
466
468
* @param {V } value
467
469
*/
468
470
function select_options ( select , value ) {
469
- for ( let i = 0 ; i < select . options . length ; i += 1 ) {
470
- const option = select . options [ i ] ;
471
+ for ( const option of select . options ) {
471
472
// @ts -ignore
472
473
option . selected = ~ value . indexOf ( get_option_value ( option ) ) ;
473
474
}
@@ -897,20 +898,10 @@ export function selected(dom) {
897
898
}
898
899
select = select . parentNode ;
899
900
}
900
- if ( select != null ) {
901
- // @ts -ignore
902
- const select_value = select . __value ;
903
- // @ts -ignore
904
- const option_value = dom . __value ;
905
- const selected = select_value === option_value ;
906
- dom . selected = selected ;
907
- dom . value = option_value ;
908
- // Handle the edge case of new options being added to a select when its state is "nothing selected"
909
- // and keeping the selection state in sync (the DOM auto-selects the first option on insert)
910
- // @ts -ignore
911
- if ( select . __value === null ) {
912
- /** @type {HTMLSelectElement } */ ( select ) . value = '' ;
913
- }
901
+ // @ts -ignore
902
+ if ( select != null && dom . __value === select . __value ) {
903
+ // never set to false, since this causes browser to select default option
904
+ dom . selected = true ;
914
905
}
915
906
} ) ;
916
907
}
@@ -949,7 +940,7 @@ export function bind_value(dom, get_value, update) {
949
940
* @returns {void }
950
941
*/
951
942
export function bind_select_value ( dom , get_value , update ) {
952
- let mounted = false ;
943
+ let mounting = true ;
953
944
dom . addEventListener ( 'change' , ( ) => {
954
945
/** @type {unknown } */
955
946
let value ;
@@ -964,40 +955,19 @@ export function bind_select_value(dom, get_value, update) {
964
955
} ) ;
965
956
// Needs to be an effect, not a render_effect, so that in case of each loops the logic runs after the each block has updated
966
957
effect ( ( ) => {
967
- const value = get_value ( ) ;
968
- if ( value == null && ! mounted ) {
958
+ let value = get_value ( ) ;
959
+ select_option ( dom , value , mounting ) ;
960
+ if ( mounting && value === undefined ) {
969
961
/** @type {HTMLOptionElement | null } */
970
- let selected_option = value === undefined ? dom . querySelector ( ':checked' ) : null ;
971
- if ( selected_option === null ) {
972
- dom . value = '' ;
973
- // @ts -ignore
974
- dom . __value = null ;
962
+ let selected_option = dom . querySelector ( ':checked' ) ;
963
+ if ( selected_option !== null ) {
964
+ value = get_option_value ( selected_option ) ;
965
+ update ( value ) ;
975
966
}
976
- const options = dom . querySelectorAll ( 'option' ) ;
977
- for ( const option of options ) {
978
- if ( get_option_value ( option ) === value || option . hasAttribute ( 'selected' ) ) {
979
- if ( option . disabled ) {
980
- option . value = '' ;
981
- }
982
- option . selected = true ;
983
- selected_option = option ;
984
- break ;
985
- }
986
- }
987
- if ( selected_option != null ) {
988
- const non_null_value = get_option_value ( selected_option ) ;
989
- update ( non_null_value ) ;
990
- if ( selected_option . hasAttribute ( 'selected' ) ) {
991
- selected_option . removeAttribute ( 'selected' ) ;
992
- selected_option . selected = true ;
993
- }
994
- }
995
- } else {
996
- select_option ( dom , value ) ;
997
- // @ts -ignore
998
- dom . __value = value ;
999
967
}
1000
- mounted = true ;
968
+ // @ts -ignore
969
+ dom . __value = value ;
970
+ mounting = false ;
1001
971
} ) ;
1002
972
}
1003
973
0 commit comments