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 -->
This commit is contained in:
bors-servo 2016-01-10 22:55:15 +05:30
commit 99d0142293
14 changed files with 142 additions and 68 deletions

View file

@ -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),

View file

@ -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)
}
}

View file

@ -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)]

View file

@ -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;

View file

@ -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;
};
*/

View file

@ -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);