diff --git a/components/script/dom/htmloptionelement.rs b/components/script/dom/htmloptionelement.rs index 132de2335b2..79f710db1d2 100644 --- a/components/script/dom/htmloptionelement.rs +++ b/components/script/dom/htmloptionelement.rs @@ -17,11 +17,18 @@ use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; use dom::node::{Node, NodeTypeId}; use dom::virtualmethods::VirtualMethods; +use std::cell::Cell; use util::str::{DOMString, split_html_space_chars}; #[dom_struct] pub struct HTMLOptionElement { - htmlelement: HTMLElement + htmlelement: HTMLElement, + + /// https://html.spec.whatwg.org/multipage/#attr-option-selected + selectedness: Cell, + + /// https://html.spec.whatwg.org/multipage/#concept-option-dirtiness + dirtiness: Cell, } impl HTMLOptionElementDerived for EventTarget { @@ -38,7 +45,9 @@ impl HTMLOptionElement { document: &Document) -> HTMLOptionElement { HTMLOptionElement { htmlelement: - HTMLElement::new_inherited(HTMLElementTypeId::HTMLOptionElement, localName, prefix, document) + HTMLElement::new_inherited(HTMLElementTypeId::HTMLOptionElement, localName, prefix, document), + selectedness: Cell::new(false), + dirtiness: Cell::new(false), } } @@ -122,6 +131,23 @@ impl HTMLOptionElementMethods for HTMLOptionElement { // https://html.spec.whatwg.org/multipage/#attr-option-label make_setter!(SetLabel, "label"); + // https://html.spec.whatwg.org/multipage/#dom-option-defaultselected + make_bool_getter!(DefaultSelected, "selected"); + + // https://html.spec.whatwg.org/multipage/#dom-option-defaultselected + make_bool_setter!(SetDefaultSelected, "selected"); + + // https://html.spec.whatwg.org/multipage/#dom-option-selected + fn Selected(&self) -> bool { + self.selectedness.get() + } + + // https://html.spec.whatwg.org/multipage/#dom-option-selected + fn SetSelected(&self, selected: bool) { + self.dirtiness.set(true); + self.selectedness.set(selected); + // FIXME: as per the spec, implement 'ask for a reset' + } } impl VirtualMethods for HTMLOptionElement { @@ -147,6 +173,22 @@ impl VirtualMethods for HTMLOptionElement { } } }, + &atom!(selected) => { + match mutation { + AttributeMutation::Set(_) => { + // https://html.spec.whatwg.org/multipage/#concept-option-selectedness + if !self.dirtiness.get() { + self.selectedness.set(true); + } + }, + AttributeMutation::Removed => { + // https://html.spec.whatwg.org/multipage/#concept-option-selectedness + if !self.dirtiness.get() { + self.selectedness.set(false); + } + }, + } + }, _ => {}, } } diff --git a/components/script/dom/webidls/HTMLOptionElement.webidl b/components/script/dom/webidls/HTMLOptionElement.webidl index c4f57ab4963..b4e3bdac353 100644 --- a/components/script/dom/webidls/HTMLOptionElement.webidl +++ b/components/script/dom/webidls/HTMLOptionElement.webidl @@ -11,8 +11,8 @@ interface HTMLOptionElement : HTMLElement { attribute boolean disabled; //readonly attribute HTMLFormElement? form; attribute DOMString label; - // attribute boolean defaultSelected; - // attribute boolean selected; + attribute boolean defaultSelected; + attribute boolean selected; attribute DOMString value; attribute DOMString text; diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 86cfdccb8fa..f291aeae279 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -17351,6 +17351,10 @@ "path": "html/semantics/forms/the-option-element/option-label.html", "url": "/html/semantics/forms/the-option-element/option-label.html" }, + { + "path": "html/semantics/forms/the-option-element/option-selected.html", + "url": "/html/semantics/forms/the-option-element/option-selected.html" + }, { "path": "html/semantics/forms/the-option-element/option-text-backslash.html", "url": "/html/semantics/forms/the-option-element/option-text-backslash.html" diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 22905a21630..b453290048c 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -5520,24 +5520,12 @@ [HTMLOptionElement interface: attribute form] expected: FAIL - [HTMLOptionElement interface: attribute defaultSelected] - expected: FAIL - - [HTMLOptionElement interface: attribute selected] - expected: FAIL - [HTMLOptionElement interface: attribute index] expected: FAIL [HTMLOptionElement interface: document.createElement("option") must inherit property "form" with the proper type (1)] expected: FAIL - [HTMLOptionElement interface: document.createElement("option") must inherit property "defaultSelected" with the proper type (3)] - expected: FAIL - - [HTMLOptionElement interface: document.createElement("option") must inherit property "selected" with the proper type (4)] - expected: FAIL - [HTMLOptionElement interface: document.createElement("option") must inherit property "index" with the proper type (7)] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-forms.html.ini b/tests/wpt/metadata/html/dom/reflection-forms.html.ini index 2e22a912497..851591ec145 100644 --- a/tests/wpt/metadata/html/dom/reflection-forms.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-forms.html.ini @@ -10542,114 +10542,6 @@ [option.tabIndex: IDL set to -2147483648 followed by getAttribute()] expected: FAIL - [option.defaultSelected (