Auto merge of #13066 - mskrzypkows:htmlselect_index, r=KiChjang

Implement indexed access on select elements

<!-- Please describe your changes on the following line: -->
Added methods for indexed access on select: SetLength, Length, Item, IndexedGetter

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #11763 (github issue number if applicable).

<!-- Either: -->
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13066)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-09-22 13:14:27 -05:00 committed by GitHub
commit d74f6adf54
5 changed files with 48 additions and 41 deletions

View file

@ -6,6 +6,7 @@ use dom::attr::Attr;
use dom::bindings::codegen::Bindings::HTMLOptionElementBinding::HTMLOptionElementMethods; use dom::bindings::codegen::Bindings::HTMLOptionElementBinding::HTMLOptionElementMethods;
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding; use dom::bindings::codegen::Bindings::HTMLSelectElementBinding;
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding::HTMLSelectElementMethods; 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::HTMLElementOrLong;
use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement; use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement;
use dom::bindings::inheritance::Castable; use dom::bindings::inheritance::Castable;
@ -17,7 +18,7 @@ use dom::htmlelement::HTMLElement;
use dom::htmlfieldsetelement::HTMLFieldSetElement; use dom::htmlfieldsetelement::HTMLFieldSetElement;
use dom::htmlformelement::{FormDatumValue, FormControl, FormDatum, HTMLFormElement}; use dom::htmlformelement::{FormDatumValue, FormControl, FormDatum, HTMLFormElement};
use dom::htmloptionelement::HTMLOptionElement; 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::nodelist::NodeList;
use dom::validation::Validatable; use dom::validation::Validatable;
use dom::validitystate::ValidityState; use dom::validitystate::ValidityState;
@ -183,6 +184,50 @@ impl HTMLSelectElementMethods for HTMLSelectElement {
fn Labels(&self) -> Root<NodeList> { fn Labels(&self) -> Root<NodeList> {
self.upcast::<HTMLElement>().labels() 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 { impl VirtualMethods for HTMLSelectElement {

View file

@ -15,8 +15,8 @@ interface HTMLSelectElement : HTMLElement {
readonly attribute DOMString type; readonly attribute DOMString type;
//readonly attribute HTMLOptionsCollection options; //readonly attribute HTMLOptionsCollection options;
// attribute unsigned long length; attribute unsigned long length;
//getter Element? item(unsigned long index); getter Element? item(unsigned long index);
//HTMLOptionElement? namedItem(DOMString name); //HTMLOptionElement? namedItem(DOMString name);
// Note: this function currently only exists for union.html. // Note: this function currently only exists for union.html.
void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null); void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);

View file

@ -16,10 +16,6 @@
expected: FAIL expected: FAIL
bug: https://github.com/servo/servo/issues/10911 bug: https://github.com/servo/servo/issues/10911
[Passing an platform object that supports indexed properties as the blobParts array should work (select).]
expected: FAIL
bug: https://github.com/servo/servo/issues/11763
[Passing a FrozenArray as the blobParts array should work (FrozenArray<MessagePort>).] [Passing a FrozenArray as the blobParts array should work (FrozenArray<MessagePort>).]
expected: FAIL expected: FAIL
bug: https://github.com/servo/servo/issues/7457 bug: https://github.com/servo/servo/issues/7457

View file

@ -3750,12 +3750,6 @@
[HTMLSelectElement interface: attribute options] [HTMLSelectElement interface: attribute options]
expected: FAIL expected: FAIL
[HTMLSelectElement interface: attribute length]
expected: FAIL
[HTMLSelectElement interface: operation item(unsigned long)]
expected: FAIL
[HTMLSelectElement interface: operation namedItem(DOMString)] [HTMLSelectElement interface: operation namedItem(DOMString)]
expected: FAIL expected: FAIL
@ -3801,15 +3795,6 @@
[HTMLSelectElement interface: document.createElement("select") must inherit property "options" with the proper type (9)] [HTMLSelectElement interface: document.createElement("select") must inherit property "options" with the proper type (9)]
expected: FAIL expected: FAIL
[HTMLSelectElement interface: document.createElement("select") must inherit property "length" with the proper type (10)]
expected: FAIL
[HTMLSelectElement interface: document.createElement("select") must inherit property "item" with the proper type (11)]
expected: FAIL
[HTMLSelectElement interface: calling item(unsigned long) on document.createElement("select") with too few arguments must throw TypeError]
expected: FAIL
[HTMLSelectElement interface: document.createElement("select") must inherit property "namedItem" with the proper type (12)] [HTMLSelectElement interface: document.createElement("select") must inherit property "namedItem" with the proper type (12)]
expected: FAIL expected: FAIL
@ -10679,4 +10664,3 @@
[Navigator interface: window.navigator must inherit property "hardwareConcurrency" with the proper type (22)] [Navigator interface: window.navigator must inherit property "hardwareConcurrency" with the proper type (22)]
expected: FAIL expected: FAIL

View file

@ -1,18 +0,0 @@
[common-HTMLOptionsCollection.html]
type: testharness
[On getting, the length attribute must return the number of nodes represented by the collection.]
expected: FAIL
bug: https://github.com/servo/servo/issues/11763
[Changing the length adds new nodes; The number of new nodes = new length minus old length]
expected: FAIL
bug: https://github.com/servo/servo/issues/11763
[New nodes have no value]
expected: FAIL
bug: https://github.com/servo/servo/issues/11763
[Setting a length equal to existing length changes nothing]
expected: FAIL
bug: https://github.com/servo/servo/issues/11763