diff options
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/htmlselectelement.rs | 47 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLSelectElement.webidl | 4 |
2 files changed, 48 insertions, 3 deletions
diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index 222dff3e52c..6cf63c7e630 100644 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -6,6 +6,7 @@ use dom::attr::Attr; use dom::bindings::codegen::Bindings::HTMLOptionElementBinding::HTMLOptionElementMethods; use dom::bindings::codegen::Bindings::HTMLSelectElementBinding; use dom::bindings::codegen::Bindings::HTMLSelectElementBinding::HTMLSelectElementMethods; +use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::UnionTypes::HTMLElementOrLong; use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement; use dom::bindings::inheritance::Castable; @@ -17,7 +18,7 @@ use dom::htmlelement::HTMLElement; use dom::htmlfieldsetelement::HTMLFieldSetElement; use dom::htmlformelement::{FormDatumValue, FormControl, FormDatum, HTMLFormElement}; use dom::htmloptionelement::HTMLOptionElement; -use dom::node::{Node, UnbindContext, window_from_node}; +use dom::node::{document_from_node, Node, UnbindContext, window_from_node}; use dom::nodelist::NodeList; use dom::validation::Validatable; use dom::validitystate::ValidityState; @@ -183,6 +184,50 @@ impl HTMLSelectElementMethods for HTMLSelectElement { fn Labels(&self) -> Root<NodeList> { self.upcast::<HTMLElement>().labels() } + + // https://html.spec.whatwg.org/multipage/#dom-select-length + fn SetLength(&self, value: u32) { + let length = self.Length(); + let node = self.upcast::<Node>(); + if value < length { // truncate the number of option elements + let mut iter = node.rev_children().take((length - value) as usize); + while let Some(child) = iter.next() { + if let Err(e) = node.RemoveChild(&child) { + warn!("Error removing child of HTMLSelectElement: {:?}", e); + } + } + } else if value > length { // add new blank option elements + let document = document_from_node(self); + for _ in 0..(value - length) { + let element = HTMLOptionElement::new(atom!("option"), None, &document.upcast()); + if let Err(e) = node.AppendChild(element.upcast()) { + warn!("error appending child of HTMLSelectElement: {:?}", e); + } + } + } + } + + // https://html.spec.whatwg.org/multipage/#dom-select-length + fn Length(&self) -> u32 { + self.upcast::<Node>() + .traverse_preorder() + .filter_map(Root::downcast::<HTMLOptionElement>) + .count() as u32 + } + + // https://html.spec.whatwg.org/multipage/#dom-select-item + fn Item(&self, index: u32) -> Option<Root<Element>> { + self.upcast::<Node>() + .traverse_preorder() + .filter_map(Root::downcast::<HTMLOptionElement>) + .nth(index as usize) + .map(|item| Root::from_ref(item.upcast())) + } + + // https://html.spec.whatwg.org/multipage/#dom-select-item + fn IndexedGetter(&self, index: u32) -> Option<Root<Element>> { + self.Item(index) + } } impl VirtualMethods for HTMLSelectElement { diff --git a/components/script/dom/webidls/HTMLSelectElement.webidl b/components/script/dom/webidls/HTMLSelectElement.webidl index ba84d183a72..b513806f965 100644 --- a/components/script/dom/webidls/HTMLSelectElement.webidl +++ b/components/script/dom/webidls/HTMLSelectElement.webidl @@ -15,8 +15,8 @@ interface HTMLSelectElement : HTMLElement { readonly attribute DOMString type; //readonly attribute HTMLOptionsCollection options; - // attribute unsigned long length; - //getter Element? item(unsigned long index); + attribute unsigned long length; + getter Element? item(unsigned long index); //HTMLOptionElement? namedItem(DOMString name); // Note: this function currently only exists for union.html. void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null); |