aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/htmlselectelement.rs30
-rw-r--r--components/script/dom/webidls/HTMLSelectElement.webidl2
-rw-r--r--tests/wpt/metadata/MANIFEST.json6
-rw-r--r--tests/wpt/metadata/html/dom/interfaces.html.ini6
-rw-r--r--tests/wpt/web-platform-tests/html/semantics/forms/the-select-element/selected-index.html73
5 files changed, 110 insertions, 7 deletions
diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs
index 03d10e117f4..c44dac71000 100644
--- a/components/script/dom/htmlselectelement.rs
+++ b/components/script/dom/htmlselectelement.rs
@@ -299,6 +299,36 @@ impl HTMLSelectElementMethods for HTMLSelectElement {
opt.set_selectedness(false);
}
}
+
+ // https://html.spec.whatwg.org/multipage/#dom-select-selectedindex
+ fn SelectedIndex(&self) -> i32 {
+ self.upcast::<Node>()
+ .traverse_preorder()
+ .filter_map(Root::downcast::<HTMLOptionElement>)
+ .enumerate()
+ .filter(|&(_, ref opt_elem)| opt_elem.Selected())
+ .map(|(i, _)| i as i32)
+ .next()
+ .unwrap_or(-1)
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-select-selectedindex
+ fn SetSelectedIndex(&self, index: i32) {
+ let mut opt_iter = self.upcast::<Node>()
+ .traverse_preorder()
+ .filter_map(Root::downcast::<HTMLOptionElement>);
+ for opt in opt_iter.by_ref().take(index as usize) {
+ opt.set_selectedness(false);
+ }
+ if let Some(opt) = opt_iter.next() {
+ opt.set_selectedness(true);
+ opt.set_dirtiness(true);
+ // Reset remaining <option> elements
+ for opt in opt_iter {
+ opt.set_selectedness(false);
+ }
+ }
+ }
}
impl VirtualMethods for HTMLSelectElement {
diff --git a/components/script/dom/webidls/HTMLSelectElement.webidl b/components/script/dom/webidls/HTMLSelectElement.webidl
index a8fd2803c44..543c3267c64 100644
--- a/components/script/dom/webidls/HTMLSelectElement.webidl
+++ b/components/script/dom/webidls/HTMLSelectElement.webidl
@@ -25,7 +25,7 @@ interface HTMLSelectElement : HTMLElement {
//setter void (unsigned long index, HTMLOptionElement? option);
//readonly attribute HTMLCollection selectedOptions;
- // attribute long selectedIndex;
+ attribute long selectedIndex;
attribute DOMString value;
//readonly attribute boolean willValidate;
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index a5720317386..bfc8b84612d 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -37763,6 +37763,12 @@
"url": "/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-add.html"
}
],
+ "html/semantics/forms/the-select-element/selected-index.html": [
+ {
+ "path": "html/semantics/forms/the-select-element/selected-index.html",
+ "url": "/html/semantics/forms/the-select-element/selected-index.html"
+ }
+ ],
"html/webappapis/scripting/events/uncompiled_event_handler_with_scripting_disabled.html": [
{
"path": "html/webappapis/scripting/events/uncompiled_event_handler_with_scripting_disabled.html",
diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini
index 98ace57ae68..67181fad83d 100644
--- a/tests/wpt/metadata/html/dom/interfaces.html.ini
+++ b/tests/wpt/metadata/html/dom/interfaces.html.ini
@@ -3708,9 +3708,6 @@
[HTMLSelectElement interface: attribute selectedOptions]
expected: FAIL
- [HTMLSelectElement interface: attribute selectedIndex]
- expected: FAIL
-
[HTMLSelectElement interface: attribute willValidate]
expected: FAIL
@@ -3738,9 +3735,6 @@
[HTMLSelectElement interface: document.createElement("select") must inherit property "selectedOptions" with the proper type (17)]
expected: FAIL
- [HTMLSelectElement interface: document.createElement("select") must inherit property "selectedIndex" with the proper type (18)]
- expected: FAIL
-
[HTMLSelectElement interface: document.createElement("select") must inherit property "willValidate" with the proper type (20)]
expected: FAIL
diff --git a/tests/wpt/web-platform-tests/html/semantics/forms/the-select-element/selected-index.html b/tests/wpt/web-platform-tests/html/semantics/forms/the-select-element/selected-index.html
new file mode 100644
index 00000000000..1be5378cdf4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/forms/the-select-element/selected-index.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLSelectElement selectedIndex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+
+<form id=form>
+ <select id=empty></select>
+
+ <select id=default>
+ <option></option>
+ <option></option>
+ <option></option>
+ <option></option>
+ <option></option>
+ </select>
+
+ <select id=disabled>
+ <option disabled></option>
+ <option></option>
+ </select>
+
+ <select id=selected>
+ <option></option>
+ <option selected></option>
+ </select>
+</form>
+
+<script>
+test(function () {
+ var select = document.getElementById('empty');
+ assert_equals(select.selectedIndex, -1);
+}, "get empty");
+
+test(function () {
+ var select = document.getElementById('default');
+ assert_equals(select.selectedIndex, 0);
+}, "get default");
+
+test(function () {
+ var select = document.getElementById('disabled');
+ assert_equals(select.selectedIndex, 1);
+}, "get disabled");
+
+test(function () {
+ var select = document.getElementById('selected');
+ assert_equals(select.selectedIndex, 1);
+}, "get unselected");
+
+test(function () {
+ var select = document.getElementById('empty');
+ select.selectedIndex = 1;
+ assert_equals(select.selectedIndex, -1);
+}, "set empty");
+
+test(function () {
+ var select = document.getElementById('default');
+ assert_equals(select.selectedIndex, 0);
+ select.selectedIndex = 2;
+ assert_equals(select.selectedIndex, 2);
+}, "set");
+
+test(function () {
+ var select = document.getElementById('selected');
+ var form = document.getElementById('form');
+ assert_equals(select.selectedIndex, 1);
+ select.selectedIndex = 0;
+ assert_equals(select.selectedIndex, 0);
+ form.reset();
+ assert_equals(select.selectedIndex, 1);
+}, "set and reset");
+</script>