feat: add observer for 'selected' setter of HTMLOptionElement and try to fix issue #746 (#810)

* feat: add observer for 'selected' setter of HTMLOptionElement and try to fix issue #746

* style: add description of mechanism
This commit is contained in:
Yun Feng
2026-04-01 12:00:00 +08:00
committed by GitHub
parent 0153270680
commit b277b9a7a6
3 changed files with 10 additions and 4 deletions

View File

@@ -491,7 +491,7 @@ function serializeNode(
}
}
if (tagName === 'option') {
if ((n as HTMLOptionElement).selected) {
if ((n as HTMLOptionElement).selected && !maskInputOptions['select']) {
attributes.selected = true;
} else {
// ignore the html attribute (which corresponds to DOM (n as HTMLOptionElement).defaultSelected)

View File

@@ -371,8 +371,14 @@ function initInputObserver(
userTriggeredOnInput: boolean,
): listenerHandler {
function eventHandler(event: Event) {
const target = getEventTarget(event);
let target = getEventTarget(event);
const userTriggered = event.isTrusted;
/**
* If a site changes the value 'selected' of an option element, the value of its parent element, usually a select element, will be changed as well.
* We can treat this change as a value change of the select element the current target belongs to.
*/
if (target && (target as Element).tagName === 'OPTION')
target = (target as Element).parentElement;
if (
!target ||
!(target as Element).tagName ||
@@ -463,6 +469,7 @@ function initInputObserver(
[HTMLTextAreaElement.prototype, 'value'],
// Some UI library use selectedIndex to set select value
[HTMLSelectElement.prototype, 'selectedIndex'],
[HTMLOptionElement.prototype, 'selected'],
];
if (propertyDescriptor && propertyDescriptor.set) {
handlers.push(

View File

@@ -6066,8 +6066,7 @@ exports[`record integration tests should not record input values if maskAllInput
\\"type\\": 2,
\\"tagName\\": \\"option\\",
\\"attributes\\": {
\\"value\\": \\"1\\",
\\"selected\\": true
\\"value\\": \\"1\\"
},
\\"childNodes\\": [
{