|
|
|
@ -1,5 +1,6 @@
|
|
|
|
import { hydrating, reset, set_hydrate_node, set_hydrating } from '../hydration.js';
|
|
|
|
import { hydrating, reset, set_hydrate_node, set_hydrating } from '../hydration.js';
|
|
|
|
import { create_comment } from '../operations.js';
|
|
|
|
import { create_comment } from '../operations.js';
|
|
|
|
|
|
|
|
import { attach } from './attachments.js';
|
|
|
|
|
|
|
|
|
|
|
|
/** @type {boolean | null} */
|
|
|
|
/** @type {boolean | null} */
|
|
|
|
let supported = null;
|
|
|
|
let supported = null;
|
|
|
|
@ -20,6 +21,52 @@ function is_supported() {
|
|
|
|
return supported;
|
|
|
|
return supported;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param {HTMLElement} element
|
|
|
|
|
|
|
|
* @param {(new_element: HTMLElement) => void} update_element
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
export function selectedcontent(element, update_element) {
|
|
|
|
|
|
|
|
// if it's not supported no need for special logic
|
|
|
|
|
|
|
|
if (!is_supported()) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// we use the attach function directly just to make sure is executed when is mounted to the dom
|
|
|
|
|
|
|
|
attach(element, () => () => {
|
|
|
|
|
|
|
|
const select = element.closest('select');
|
|
|
|
|
|
|
|
if (!select) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const observer = new MutationObserver((entries) => {
|
|
|
|
|
|
|
|
var selected = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const entry of entries) {
|
|
|
|
|
|
|
|
if (entry.target === element) {
|
|
|
|
|
|
|
|
// the `<selectedcontent>` already changed, no need to replace it
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if the changes doesn't include the selected `<option>` we don't need to do anything
|
|
|
|
|
|
|
|
selected ||= !!entry.target.parentElement?.closest('option')?.selected;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (selected) {
|
|
|
|
|
|
|
|
// replace the `<selectedcontent>` with a clone
|
|
|
|
|
|
|
|
element.replaceWith((element = /** @type {HTMLElement} */ (element.cloneNode(true))));
|
|
|
|
|
|
|
|
update_element(element);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
observer.observe(select, {
|
|
|
|
|
|
|
|
childList: true,
|
|
|
|
|
|
|
|
characterData: true,
|
|
|
|
|
|
|
|
subtree: true
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
|
|
observer.disconnect();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Handles rich HTML content inside `<option>`, `<optgroup>`, or `<select>` elements with browser-specific branching.
|
|
|
|
* Handles rich HTML content inside `<option>`, `<optgroup>`, or `<select>` elements with browser-specific branching.
|
|
|
|
* Modern browsers preserve HTML inside options, while older browsers strip it to text only.
|
|
|
|
* Modern browsers preserve HTML inside options, while older browsers strip it to text only.
|
|
|
|
|