pull/15961/head
Rich Harris 4 months ago
parent fe4b86d36b
commit 5876ef7102

@ -205,25 +205,25 @@ export function RegularElement(node, context) {
build_set_attributes(attributes, class_directives, style_directives, context, node, node_id); build_set_attributes(attributes, class_directives, style_directives, context, node, node_id);
// If value binding exists, that one takes care of calling $.init_select // // If value binding exists, that one takes care of calling $.init_select
if (node.name === 'select' && !bindings.has('value')) { // if (node.name === 'select' && !bindings.has('value')) {
context.state.init.push( // context.state.init.push(
b.stmt(b.call('$.init_select', node_id, b.thunk(b.member(attributes_id, 'value')))) // b.stmt(b.call('$.init_select', node_id, b.thunk(b.member(attributes_id, 'value'))))
); // );
context.state.update.push( // context.state.update.push(
b.if( // b.if(
b.binary('in', b.literal('value'), attributes_id), // b.binary('in', b.literal('value'), attributes_id),
b.block([ // b.block([
// This ensures a one-way street to the DOM in case it's <select {value}> // // This ensures a one-way street to the DOM in case it's <select {value}>
// and not <select bind:value>. We need it in addition to $.init_select // // and not <select bind:value>. We need it in addition to $.init_select
// because the select value is not reflected as an attribute, so the // // because the select value is not reflected as an attribute, so the
// mutation observer wouldn't notice. // // mutation observer wouldn't notice.
b.stmt(b.call('$.select_option', node_id, b.member(attributes_id, 'value'))) // b.stmt(b.call('$.select_option', node_id, b.member(attributes_id, 'value')))
]) // ])
) // )
); // );
} // }
} else { } else {
/** If true, needs `__value` for inputs */ /** If true, needs `__value` for inputs */
const needs_special_value_handling = const needs_special_value_handling =

@ -20,8 +20,9 @@ import { clsx } from '../../../shared/attributes.js';
import { set_class } from './class.js'; import { set_class } from './class.js';
import { set_style } from './style.js'; import { set_style } from './style.js';
import { ATTACHMENT_KEY, NAMESPACE_HTML } from '../../../../constants.js'; import { ATTACHMENT_KEY, NAMESPACE_HTML } from '../../../../constants.js';
import { block, branch, destroy_effect } from '../../reactivity/effects.js'; import { block, branch, destroy_effect, effect } from '../../reactivity/effects.js';
import { derived } from '../../reactivity/deriveds.js'; import { derived } from '../../reactivity/deriveds.js';
import { init_select, select_option } from './bindings/select.js';
export const CLASS = Symbol('class'); export const CLASS = Symbol('class');
export const STYLE = Symbol('style'); export const STYLE = Symbol('style');
@ -483,11 +484,18 @@ export function attribute_effect(
/** @type {Record<symbol, Effect>} */ /** @type {Record<symbol, Effect>} */
var effects = {}; var effects = {};
var is_select = element.nodeName === 'SELECT';
var inited = false;
block(() => { block(() => {
var next = fn(...deriveds.map(get)); var next = fn(...deriveds.map(get));
set_attributes(element, prev, next, css_hash, skip_warning); set_attributes(element, prev, next, css_hash, skip_warning);
if (inited && is_select) {
select_option(/** @type {HTMLSelectElement} */ (element), next.value, false);
}
for (let symbol of Object.getOwnPropertySymbols(effects)) { for (let symbol of Object.getOwnPropertySymbols(effects)) {
if (!next[symbol]) destroy_effect(effects[symbol]); if (!next[symbol]) destroy_effect(effects[symbol]);
} }
@ -503,6 +511,12 @@ export function attribute_effect(
prev = next; prev = next;
}); });
if (is_select) {
init_select(/** @type {HTMLSelectElement} */ (element), () => prev.value);
}
inited = true;
} }
/** /**

@ -25,7 +25,11 @@ export function select_option(select, value, mounting) {
} }
// Otherwise, update the selection // Otherwise, update the selection
return select_options(select, value); for (var option of select.options) {
option.selected = value.includes(get_option_value(option));
}
return;
} }
for (var option of select.options) { for (var option of select.options) {
@ -136,16 +140,6 @@ export function bind_select_value(select, get, set = get) {
init_select(select); init_select(select);
} }
/**
* @param {HTMLSelectElement} select
* @param {unknown[]} value
*/
function select_options(select, value) {
for (var option of select.options) {
option.selected = value.includes(get_option_value(option));
}
}
/** @param {HTMLOptionElement} option */ /** @param {HTMLOptionElement} option */
function get_option_value(option) { function get_option_value(option) {
// __value only exists if the <option> has a value attribute // __value only exists if the <option> has a value attribute

Loading…
Cancel
Save