Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 198x 34x 34x 164x 198x 292x 292x 108x 108x 108x 292x 56x 198x 42x 42x 198x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 90x 90x 16x 16x 90x 90x 14x 14x 14x 14x 14x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 90x 2x 2x 2x 2x 2x 2x 2x 2x 74x 74x 74x 30x 30x 30x 30x 4x 30x 26x 26x 26x 26x 30x 30x 74x 74x 74x 74x 134x 134x 134x 134x 134x 14x 14x 14x 14x 14x 14x 14x 134x 134x 134x 134x 74x 74x 74x 74x 74x 2x 2x 2x 2x 2x 2x 34x 34x 76x 76x 76x 34x 2x 2x 414x 414x 414x 266x 414x 148x 148x 414x | import { effect } from '../../../reactivity/effects.js'; import { listen_to_event_and_reset_event } from './shared.js'; import { untrack, yield_updates } from '../../../runtime.js'; import { is } from '../../../proxy.js'; /** * Selects the correct option(s) (depending on whether this is a multiple select) * @template V * @param {HTMLSelectElement} select * @param {V} value * @param {boolean} [mounting] */ export function select_option(select, value, mounting) { if (select.multiple) { return select_options(select, value); } for (var option of select.options) { var option_value = get_option_value(option); if (is(option_value, value)) { option.selected = true; return; } } if (!mounting || value !== undefined) { select.selectedIndex = -1; // no option should be selected } } /** * Selects the correct option(s) if `value` is given, * and then sets up a mutation observer to sync the * current selection to the dom when it changes. Such * changes could for example occur when options are * inside an `#each` block. * @template V * @param {HTMLSelectElement} select * @param {() => V} [get_value] */ export function init_select(select, get_value) { effect(() => { if (get_value) { select_option(select, untrack(get_value)); } var observer = new MutationObserver(() => { // @ts-ignore var value = select.__value; select_option(select, value); // Deliberately don't update the potential binding value, // the model should be preserved unless explicitly changed }); observer.observe(select, { // Listen to option element changes childList: true, subtree: true, // because of <optgroup> // Listen to option element value attribute changes // (doesn't get notified of select value changes, // because that property is not reflected as an attribute) attributes: true, attributeFilter: ['value'] }); return () => { observer.disconnect(); }; }); } /** * @param {HTMLSelectElement} select * @param {() => unknown} get_value * @param {(value: unknown) => void} update * @returns {void} */ export function bind_select_value(select, get_value, update) { var mounting = true; listen_to_event_and_reset_event(select, 'change', () => { /** @type {unknown} */ var value; if (select.multiple) { value = [].map.call(select.querySelectorAll(':checked'), get_option_value); } else { /** @type {HTMLOptionElement | null} */ var selected_option = select.querySelector(':checked'); value = selected_option && get_option_value(selected_option); } yield_updates(() => update(value)); }); // 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 effect(() => { var value = get_value(); select_option(select, value, mounting); // Mounting and value undefined -> take selection from dom if (mounting && value === undefined) { /** @type {HTMLOptionElement | null} */ var selected_option = select.querySelector(':checked'); if (selected_option !== null) { value = get_option_value(selected_option); update(value); } } // @ts-ignore select.__value = value; mounting = false; }); // don't pass get_value, we already initialize it in the effect above init_select(select); } /** * @template V * @param {HTMLSelectElement} select * @param {V} value */ function select_options(select, value) { for (var option of select.options) { // @ts-ignore option.selected = ~value.indexOf(get_option_value(option)); } } /** @param {HTMLOptionElement} option */ function get_option_value(option) { // __value only exists if the <option> has a value attribute if ('__value' in option) { return option.__value; } else { return option.value; } } |