HTMLOptionElement-impl.js
3.01 KB
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
"use strict";
const HTMLElementImpl = require("./HTMLElement-impl").implementation;
const { stripAndCollapseASCIIWhitespace } = require("../helpers/strings");
const { domSymbolTree } = require("../helpers/internal-constants");
const { closest } = require("../helpers/traversal");
const { formOwner } = require("../helpers/form-controls");
class HTMLOptionElementImpl extends HTMLElementImpl {
constructor(globalObject, args, privateData) {
super(globalObject, args, privateData);
// whenever selectedness is set to true, make sure all
// other options set selectedness to false
this._selectedness = false;
this._dirtyness = false;
}
_removeOtherSelectedness() {
// Remove the selectedness flag from all other options in this select
const select = this._selectNode;
if (select && !select.hasAttributeNS(null, "multiple")) {
for (const option of select.options) {
if (option !== this) {
option._selectedness = false;
}
}
}
}
_askForAReset() {
const select = this._selectNode;
if (select) {
select._askedForAReset();
}
}
_attrModified(name) {
if (!this._dirtyness && name === "selected") {
this._selectedness = this.hasAttributeNS(null, "selected");
if (this._selectedness) {
this._removeOtherSelectedness();
}
this._askForAReset();
}
super._attrModified.apply(this, arguments);
}
get _selectNode() {
let select = domSymbolTree.parent(this);
if (!select) {
return null;
}
if (select.nodeName.toUpperCase() !== "SELECT") {
select = domSymbolTree.parent(select);
if (!select || select.nodeName.toUpperCase() !== "SELECT") {
return null;
}
}
return select;
}
get form() {
return formOwner(this);
}
get text() {
// TODO is not correctly excluding script and SVG script descendants
return stripAndCollapseASCIIWhitespace(this.textContent);
}
set text(value) {
this.textContent = value;
}
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-option-value
_getValue() {
if (this.hasAttributeNS(null, "value")) {
return this.getAttributeNS(null, "value");
}
return this.text;
}
get value() {
return this._getValue();
}
set value(value) {
this.setAttributeNS(null, "value", value);
}
get index() {
const select = closest(this, "select");
if (select === null) {
return 0;
}
return select.options.indexOf(this);
}
get selected() {
return this._selectedness;
}
set selected(s) {
this._dirtyness = true;
this._selectedness = Boolean(s);
if (this._selectedness) {
this._removeOtherSelectedness();
}
this._askForAReset();
this._modified();
}
get label() {
if (this.hasAttributeNS(null, "label")) {
return this.getAttributeNS(null, "label");
}
return this.text;
}
set label(value) {
this.setAttributeNS(null, "label", value);
}
}
module.exports = {
implementation: HTMLOptionElementImpl
};