Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Html options collection#13129 #13380

Merged
merged 4 commits into from Sep 26, 2016

Conversation

splav
Copy link
Contributor

@splav splav commented Sep 22, 2016

Implement HTMLOptionsCollection and related HTMLSelectElement items


  • There are tests for these changes OR
  • These changes do not require tests because _____

This change is Reviewable

@highfive
Copy link

Heads up! This PR modifies the following files:

  • @KiChjang: components/script/dom/bindings/codegen/CodegenRust.py, components/script/dom/htmloptionscollection.rs, components/script/dom/webidls/HTMLOptionsCollection.webidl, components/script/dom/webidls/HTMLSelectElement.webidl, components/script/dom/mod.rs, components/script/dom/htmlselectelement.rs

@highfive highfive added the S-awaiting-review There is new code that needs to be reviewed. label Sep 22, 2016
@jdm jdm added the S-needs-rebase There are merge conflict errors. label Sep 22, 2016
#[dom_struct]
pub struct HTMLOptionsCollection {
collection: HTMLCollection,
root: MutHeap<JS<Node>>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary? The parent class already has this field.

@@ -28,7 +32,8 @@ use style::element_state::*;

#[dom_struct]
pub struct HTMLSelectElement {
htmlelement: HTMLElement
htmlelement: HTMLElement,
options: MutNullableHeap<JS<HTMLOptionsCollection>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be nullable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not? It's done so in HTMLFormElement.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's expensive to create an HTMLFormControlsCollection for HTMLFormElement, but for HTMLSelectElement, creating an HTMLOptionsCollection is just a straightforward filter, hence it isn't necessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this isn't possible to create an HTMLOptionsCollection during the creation of HTMLSelectElement. Ignore my comment and leave it as-is.

let options = HTMLOptionsCollection::new(window.r(), self.upcast(), filter);
self.options.set(Some(&options));
options
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Indentation.


// https://html.spec.whatwg.org/multipage/#dom-select-item
fn Item(&self, index: u32) -> Option<Root<Element>> {
self.Options().IndexedGetter(index)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not Item(index) instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no such method for HTMLOptionsCollection.


// https://html.spec.whatwg.org/multipage/#dom-htmloptionscollection-add
fn Add(&self, element: HTMLOptionElementOrHTMLOptGroupElement, before: Option<HTMLElementOrLong >) -> ErrorResult {
// TODO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this TODO doing here?

let name = QualName::new(ns!(html), name_atom.clone());
let element = Element::create(name, None, document.r(), ElementCreator::ScriptCreated);
let node = element.r().upcast::<Node>();
try!(Node::pre_insert(node, root.r(), None));
Copy link
Contributor

@KiChjang KiChjang Sep 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty messy, you can achieve the same simply by using the AppendChild WebIDL function on Node and HTMLOptionElement::new.

// // https://html.spec.whatwg.org/multipage/#dom-select-setter
// fn IndexedSetter(&self, index: u32, value: Option<&HTMLOptionElement>) -> ErrorResult {
// self.Options().IndexedSetter(index, value)
// }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this commented out?

// // https://html.spec.whatwg.org/multipage/#dom-select-remove
// fn Remove(&self, index: i32) -> ErrorResult {
// self.Options().Remove(index)
// }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this commented out?

element.r().Remove();
Ok(())
} else {
Err(Error::NotFound)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec doesn't say that you should throw a NotFoundError in this case, instead it says to abort the algorithm.

if delta < 0 {
// new length is lower - deleting last option elements
for index in (length..current_length).rev() {
self.Remove(index as i32).unwrap()
Copy link
Contributor

@KiChjang KiChjang Sep 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unwrapping is not fine here, since it can fail. If you don't care about the result of removing, you can do let _ = self.Remove(index as i32);

@KiChjang KiChjang added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. S-needs-rebase There are merge conflict errors. labels Sep 22, 2016
.filter_map(Root::downcast::<HTMLOptionElement>)
.nth(index as usize)
.map(|item| Root::from_ref(item.upcast()))
self.Options().IndexedGetter(index)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not self.Options().Item(index)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you ignored my review comment here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the previous similar - there is no such method (Item) for HTMLOptionsCollection.

@KiChjang KiChjang assigned KiChjang and unassigned asajeffrey Sep 22, 2016
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Sep 23, 2016
fn add_new_elements(&self, count: u32) -> ErrorResult {
let root = self.collection.get_root();
let document = document_from_node(root.r());
let name_atom = Atom::from(DOMString::from("option".to_owned()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let name_atom = atom!("option");

@splav splav force-pushed the HTMLOptionsCollection#13129 branch 3 times, most recently from 3dfce35 to c8574ec Compare September 24, 2016 16:50
@splav
Copy link
Contributor Author

splav commented Sep 24, 2016

@KiChjang fixed latest one, fixed indentation in idl file.

@splav
Copy link
Contributor Author

splav commented Sep 24, 2016

@KiChjang as for Item method - how are they used from JS? The collection should inherit these methods from HTMLCollection, but binding generator does not require them for HTMLOptionsCollection. Should I implement it anyway?

@KiChjang
Copy link
Contributor

What you need to do is to .upcast::<HTMLCollection>() the resulting HTMLOptionsCollection, and call Item() on it.

fn add_new_elements(&self, count: u32) -> ErrorResult {
let root = self.collection.get_root();
let document = document_from_node(root.r());
let name_atom = atom!("option");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this in my previous review, but name_atom is completely unnecessary. You can just call atom!("option") directly in HTMLOptionElement::new.

for _ in 0..count {
let element = HTMLOptionElement::new(name_atom.clone(), None, document.r());
let node = element.upcast::<Node>();
try!(root.AppendChild(node).map(|_| ()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the map necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppentChild returns Fallable

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And...?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presumably this function returns ErrorResult, which is Fallible<(), Error>.

Copy link
Contributor Author

@splav splav Sep 25, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, AppendChild returns Fallible<Root<Node>, Error> and the function returns Fallible<(), Error> so I had to map Root<Node> to ().

@@ -229,6 +229,9 @@ impl HTMLCollection {
}
}

pub fn get_root(&self) -> Root<Node> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call this root_node instead.


let node = match element {
HTMLOptionElementOrHTMLOptGroupElement::HTMLOptionElement(ref element) => element.upcast::<Node>(),
HTMLOptionElementOrHTMLOptGroupElement::HTMLOptGroupElement(ref element) => element.upcast::<Node>(),
Copy link
Contributor

@KiChjang KiChjang Sep 25, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTMLOptionElementOrHTMLOptGroupElement::HTMLOptionElement(ref el) |
HTMLOptionElementOrHTMLOptGroupElement::HTMLOptGroupElement(ref el) => el.upcast::<Node>()

I'm not sure the above works, but if not, use the following:

let node: &Node = match element {
    // same as above, but use element.upcast() instead of element.upcast::<Node>()
}

Copy link
Member

@jdm jdm Sep 25, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe either of those will work - match arms that are combined must contain the exact same types.
edit: oh, I think I'm misreading your second suggestion. If "as above" means the original code, then that's fine.


fn add_new_elements(&self, count: u32) -> ErrorResult {
let root = self.collection.get_root();
let document = document_from_node(root.r());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why it has to be root.r(), but self works here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self is not derived from Node. Base 'class' is HTMLCollection.

@KiChjang KiChjang added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Sep 25, 2016
@jdm jdm added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-tests-failed The changes caused existing tests to fail. labels Sep 26, 2016
@bors-servo
Copy link
Contributor

🔒 Merge conflict

@bors-servo
Copy link
Contributor

☔ The latest upstream changes (presumably #13426) made this pull request unmergeable. Please resolve the merge conflicts.

@highfive highfive added the S-needs-rebase There are merge conflict errors. label Sep 26, 2016
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Sep 26, 2016
@jdm
Copy link
Member

jdm commented Sep 26, 2016

@bors-servo: r=KiChjang

@bors-servo
Copy link
Contributor

📌 Commit 6d5791f has been approved by KiChjang

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. S-needs-rebase There are merge conflict errors. labels Sep 26, 2016
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Sep 26, 2016
@jdm
Copy link
Member

jdm commented Sep 26, 2016

@bors-servo: r=KiChjang

@bors-servo
Copy link
Contributor

📌 Commit 80c70e3 has been approved by KiChjang

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. labels Sep 26, 2016
@bors-servo
Copy link
Contributor

⌛ Testing commit 80c70e3 with merge 7de13a6...

bors-servo pushed a commit that referenced this pull request Sep 26, 2016
Html options collection#13129

<!-- Please describe your changes on the following line: -->
Implement HTMLOptionsCollection and related HTMLSelectElement items

---
<!-- 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 #13129 (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/13380)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

☀️ Test successful - arm32, arm64, linux-dev, linux-rel, mac-dev-unit, mac-rel-css, mac-rel-wpt, windows-dev

@bors-servo bors-servo merged commit 80c70e3 into servo:master Sep 26, 2016
@highfive highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Sep 26, 2016
@splav splav deleted the HTMLOptionsCollection#13129 branch September 27, 2016 04:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement HTMLOptionsCollection
7 participants