diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-01-10 22:55:15 +0530 |
---|---|---|
committer | bors-servo <lbergstrom+bors@mozilla.com> | 2016-01-10 22:55:15 +0530 |
commit | 99d01422931cee3ee0b51d7546796de6d09fb7a0 (patch) | |
tree | e9f1008cc59505a49261db299d38fc50ed7a5ade | |
parent | d3889b4be43eb4d637f2d1ac5d021603653601eb (diff) | |
parent | bff8947e43dbdf3b004b597bf30cde24616807f3 (diff) | |
download | servo-99d01422931cee3ee0b51d7546796de6d09fb7a0.tar.gz servo-99d01422931cee3ee0b51d7546796de6d09fb7a0.zip |
Auto merge of #9237 - frewsxcv:htmlformelement-elements, r=KiChjang
Implement HTMLFormElement::Elements
Fixes #8566
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9237)
<!-- Reviewable:end -->
14 files changed, 142 insertions, 68 deletions
diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs index 1e80481ac68..ec71502bf42 100644 --- a/components/script/dom/htmlcollection.rs +++ b/components/script/dom/htmlcollection.rs @@ -66,7 +66,7 @@ pub struct HTMLCollection { impl HTMLCollection { #[allow(unrooted_must_root)] - fn new_inherited(root: &Node, filter: Box<CollectionFilter + 'static>) -> HTMLCollection { + pub fn new_inherited(root: &Node, filter: Box<CollectionFilter + 'static>) -> HTMLCollection { HTMLCollection { reflector_: Reflector::new(), root: JS::from_ref(root), diff --git a/components/script/dom/htmlformcontrolscollection.rs b/components/script/dom/htmlformcontrolscollection.rs new file mode 100644 index 00000000000..2b9b3060a86 --- /dev/null +++ b/components/script/dom/htmlformcontrolscollection.rs @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods; +use dom::bindings::codegen::Bindings::HTMLFormControlsCollectionBinding; +use dom::bindings::codegen::Bindings::HTMLFormControlsCollectionBinding::HTMLFormControlsCollectionMethods; +use dom::bindings::global::GlobalRef; +use dom::bindings::js::Root; +use dom::bindings::reflector::reflect_dom_object; +use dom::element::Element; +use dom::htmlcollection::{CollectionFilter, HTMLCollection}; +use dom::node::Node; +use dom::window::Window; +use util::str::DOMString; + +#[dom_struct] +pub struct HTMLFormControlsCollection { + collection: HTMLCollection, +} + +impl HTMLFormControlsCollection { + fn new_inherited(root: &Node, filter: Box<CollectionFilter + 'static>) -> HTMLFormControlsCollection { + HTMLFormControlsCollection { + collection: HTMLCollection::new_inherited(root, filter) + } + } + + pub fn new(window: &Window, root: &Node, filter: Box<CollectionFilter + 'static>) + -> Root<HTMLFormControlsCollection> + { + reflect_dom_object(box HTMLFormControlsCollection::new_inherited(root, filter), + GlobalRef::Window(window), + HTMLFormControlsCollectionBinding::Wrap) + } + + // FIXME: This shouldn't need to be implemented here since HTMLCollection (the parent of + // HTMLFormControlsCollection) implements Length + pub fn Length(&self) -> u32 { + self.collection.Length() + } +} + +impl HTMLFormControlsCollectionMethods for HTMLFormControlsCollection { + // https://html.spec.whatwg.org/multipage/#dom-htmlformcontrolscollection-nameditem + fn NamedGetter(&self, name: DOMString, found: &mut bool) -> Option<Root<Element>> { + self.collection.NamedGetter(name, found) + } + + // https://html.spec.whatwg.org/multipage/#the-htmlformcontrolscollection-interface:supported-property-names + fn SupportedPropertyNames(&self) -> Vec<DOMString> { + self.collection.SupportedPropertyNames() + } + + // FIXME: This shouldn't need to be implemented here since HTMLCollection (the parent of + // HTMLFormControlsCollection) implements IndexedGetter + // + // https://dom.spec.whatwg.org/#dom-htmlcollection-item + fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<Element>> { + self.collection.IndexedGetter(index, found) + } +} diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 512a0d6a56c..072231d4054 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -20,10 +20,14 @@ use dom::element::Element; use dom::event::{EventBubbles, EventCancelable}; use dom::eventtarget::EventTarget; use dom::htmlbuttonelement::HTMLButtonElement; +use dom::htmlcollection::CollectionFilter; use dom::htmldatalistelement::HTMLDataListElement; use dom::htmlelement::HTMLElement; +use dom::htmlfieldsetelement::HTMLFieldSetElement; +use dom::htmlformcontrolscollection::HTMLFormControlsCollection; use dom::htmlinputelement::HTMLInputElement; use dom::htmlobjectelement::HTMLObjectElement; +use dom::htmloutputelement::HTMLOutputElement; use dom::htmlselectelement::HTMLSelectElement; use dom::htmltextareaelement::HTMLTextAreaElement; use dom::node::{Node, document_from_node, window_from_node}; @@ -135,6 +139,62 @@ impl HTMLFormElementMethods for HTMLFormElement { fn Reset(&self) { self.reset(ResetFrom::FromFormResetMethod); } + + // https://html.spec.whatwg.org/multipage/#dom-form-elements + fn Elements(&self) -> Root<HTMLFormControlsCollection> { + #[derive(JSTraceable, HeapSizeOf)] + struct ElementsFilter { + form: Root<HTMLFormElement> + } + impl CollectionFilter for ElementsFilter { + fn filter<'a>(&self, elem: &'a Element, _root: &'a Node) -> bool { + let form_owner = match elem.upcast::<Node>().type_id() { + NodeTypeId::Element(ElementTypeId::HTMLElement(t)) => { + match t { + HTMLElementTypeId::HTMLButtonElement => { + elem.downcast::<HTMLButtonElement>().unwrap().form_owner() + } + HTMLElementTypeId::HTMLFieldSetElement => { + elem.downcast::<HTMLFieldSetElement>().unwrap().form_owner() + } + HTMLElementTypeId::HTMLInputElement => { + let input_elem = elem.downcast::<HTMLInputElement>().unwrap(); + if input_elem.type_() == atom!("image") { + return false; + } + input_elem.form_owner() + } + HTMLElementTypeId::HTMLObjectElement => { + elem.downcast::<HTMLObjectElement>().unwrap().form_owner() + } + HTMLElementTypeId::HTMLOutputElement => { + elem.downcast::<HTMLOutputElement>().unwrap().form_owner() + } + HTMLElementTypeId::HTMLSelectElement => { + elem.downcast::<HTMLSelectElement>().unwrap().form_owner() + } + HTMLElementTypeId::HTMLTextAreaElement => { + elem.downcast::<HTMLTextAreaElement>().unwrap().form_owner() + } + _ => { + debug_assert!(!elem.downcast::<HTMLElement>().unwrap().is_listed_element()); + return false; + } + } + } + _ => return false, + }; + + match form_owner { + Some(form_owner) => form_owner == self.form, + None => false, + } + } + } + let filter = box ElementsFilter { form: Root::from_ref(self) }; + let window = window_from_node(self); + HTMLFormControlsCollection::new(window.r(), self.upcast(), filter) + } } #[derive(Copy, Clone, HeapSizeOf, PartialEq)] diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 89b0745dbc3..38abcd56ddd 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -272,6 +272,7 @@ pub mod htmlelement; pub mod htmlembedelement; pub mod htmlfieldsetelement; pub mod htmlfontelement; +pub mod htmlformcontrolscollection; pub mod htmlformelement; pub mod htmlframeelement; pub mod htmlframesetelement; diff --git a/components/script/dom/webidls/HTMLFormControlsCollection.webidl b/components/script/dom/webidls/HTMLFormControlsCollection.webidl new file mode 100644 index 00000000000..e7f2e84a566 --- /dev/null +++ b/components/script/dom/webidls/HTMLFormControlsCollection.webidl @@ -0,0 +1,16 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// https://html.spec.whatwg.org/multipage/#htmlformcontrolscollection +interface HTMLFormControlsCollection : HTMLCollection { + // inherits length and item() + // getter (RadioNodeList or Element)? namedItem(DOMString name); // shadows inherited namedItem() +}; + +/* +interface RadioNodeList : NodeList { + attribute DOMString value; +}; +*/ diff --git a/components/script/dom/webidls/HTMLFormElement.webidl b/components/script/dom/webidls/HTMLFormElement.webidl index e2423dcce6c..4fde856a6a5 100644 --- a/components/script/dom/webidls/HTMLFormElement.webidl +++ b/components/script/dom/webidls/HTMLFormElement.webidl @@ -16,7 +16,7 @@ interface HTMLFormElement : HTMLElement { attribute boolean noValidate; attribute DOMString target; - //[SameObject] readonly attribute HTMLFormControlsCollection elements; + [SameObject] readonly attribute HTMLFormControlsCollection elements; //readonly attribute long length; //getter Element (unsigned long index); //getter (RadioNodeList or Element) (DOMString name); diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 39e0719589b..30a17856204 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -1365,15 +1365,6 @@ [HTMLFormControlsCollection interface: existence and properties of interface object] expected: FAIL - [HTMLFormControlsCollection interface object length] - expected: FAIL - - [HTMLFormControlsCollection interface: existence and properties of interface prototype object] - expected: FAIL - - [HTMLFormControlsCollection interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - [HTMLFormControlsCollection interface: operation namedItem(DOMString)] expected: FAIL @@ -4767,9 +4758,6 @@ [HTMLFormElement interface: existence and properties of interface object] expected: FAIL - [HTMLFormElement interface: attribute elements] - expected: FAIL - [HTMLFormElement interface: attribute length] expected: FAIL @@ -4782,9 +4770,6 @@ [HTMLFormElement interface: operation requestAutocomplete()] expected: FAIL - [HTMLFormElement interface: document.createElement("form") must inherit property "elements" with the proper type (9)] - expected: FAIL - [HTMLFormElement interface: document.createElement("form") must inherit property "length" with the proper type (10)] expected: FAIL @@ -9243,9 +9228,6 @@ [HTMLAllCollection interface object name] expected: FAIL - [HTMLFormControlsCollection interface object name] - expected: FAIL - [RadioNodeList interface object name] expected: FAIL diff --git a/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html.ini b/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html.ini index 0bbbc371769..7b06a0aef35 100644 --- a/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html.ini +++ b/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html.ini @@ -3,33 +3,12 @@ [The length attribute must return the number of elements in the form] expected: FAIL - [HTMLFormControlsCollection.item(index) must return the indexed item] - expected: FAIL - - [HTMLFormControlsCollection[index\] must return the indexed item] - expected: FAIL - [HTMLFormControlsCollection(name) must return the named item] expected: FAIL - [HTMLFormControlsCollection[name\] must return the named item] - expected: FAIL - - [HTMLFormControlsCollection.namedItem(name) must return the named item] - expected: FAIL - - [The namedItem(name) must return an Element] - expected: FAIL - [The namedItem(name) must return RadioNodeList] expected: FAIL - [The namedItem(name) must return null if the name is empty] - expected: FAIL - - [The namedItem(name) must return null if there is no matched element] - expected: FAIL - [Controls can be indexed by id or name attribute] expected: FAIL @@ -38,7 +17,3 @@ [The HTMLFormControlsCollection interface is used for collections of listed elements in form element] expected: FAIL - - [The controls in the form element must be sorted in tree order] - expected: FAIL - diff --git a/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/radionodelist.html.ini b/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/radionodelist.html.ini index c209722ce7a..a4c1cf16d69 100644 --- a/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/radionodelist.html.ini +++ b/tests/wpt/metadata/html/infrastructure/common-dom-interfaces/collections/radionodelist.html.ini @@ -1,6 +1,5 @@ [radionodelist.html] type: testharness - expected: ERROR [The value attribute should be empty if no element is checked] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/constraints/form-validation-validate.html.ini b/tests/wpt/metadata/html/semantics/forms/constraints/form-validation-validate.html.ini index 5e15dd039e3..69ad893bb1d 100644 --- a/tests/wpt/metadata/html/semantics/forms/constraints/form-validation-validate.html.ini +++ b/tests/wpt/metadata/html/semantics/forms/constraints/form-validation-validate.html.ini @@ -1,6 +1,5 @@ [form-validation-validate.html] type: testharness - expected: ERROR [If there is any invalid submittable element whose form owner is the form, the form.checkValidity must be false] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-interfaces-01.html.ini b/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-interfaces-01.html.ini deleted file mode 100644 index 10c5562ed1f..00000000000 --- a/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-interfaces-01.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[form-elements-interfaces-01.html] - type: testharness - [Testing interface HTMLFormControlsCollection] - expected: FAIL - - [Testing interface HTMLCollection] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-matches.html.ini b/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-matches.html.ini deleted file mode 100644 index e35a3dfb489..00000000000 --- a/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-matches.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[form-elements-matches.html] - type: testharness - [input type=image should not be present in the form.elements collection] - expected: FAIL - - [form.elements should include elements whose name starts with a number] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-nameditem-02.html.ini b/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-nameditem-02.html.ini deleted file mode 100644 index 7ff051dee7a..00000000000 --- a/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-nameditem-02.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[form-elements-nameditem-02.html] - type: testharness - [form.elements should work correctly in the face of table syntax errors] - expected: FAIL - diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html index 647beb3ef03..9f04099f7a6 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html @@ -125,6 +125,7 @@ var interfaceNamesInGlobalScope = [ "HTMLEmbedElement", "HTMLFieldSetElement", "HTMLFontElement", + "HTMLFormControlsCollection", "HTMLFormElement", "HTMLFrameElement", "HTMLFrameSetElement", |