Implement Element#closest

fixes #4603

- Add definition to the Element.webidl and implementation to element.rs.
- Create inclusive_ancestors helper in NodeHelpers
- Update test expectations
This commit is contained in:
Jim Hoskins 2015-01-12 22:34:17 -08:00
parent 2a9acdcb73
commit 7759358e09
6 changed files with 27 additions and 83 deletions

View file

@ -1120,6 +1120,23 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
}
}
}
// https://dom.spec.whatwg.org/#dom-element-closest
fn Closest(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> {
let parser_context = ParserContext {
origin: StylesheetOrigin::Author,
};
match style::parse_selector_list_from_str(&parser_context, selectors.as_slice()) {
Err(()) => Err(Syntax),
Ok(ref selectors) => {
let root: JSRef<Node> = NodeCast::from_ref(self);
Ok(root.inclusive_ancestors()
.filter_map(ElementCast::to_ref)
.find(|element| matches(selectors, &NodeCast::from_ref(*element), &mut None))
.map(Temporary::from_rooted))
}
}
}
}
pub fn get_attribute_parts<'a>(name: &'a str) -> (Option<&'a str>, &'a str) {

View file

@ -397,6 +397,7 @@ impl<'a> Iterator<JSRef<'a, Node>> for QuerySelectorIterator<'a> {
pub trait NodeHelpers<'a> {
fn ancestors(self) -> AncestorIterator<'a>;
fn inclusive_ancestors(self) -> AncestorIterator<'a>;
fn children(self) -> NodeChildrenIterator<'a>;
fn rev_children(self) -> ReverseChildrenIterator;
fn child_elements(self) -> ChildElementIterator<'a>;
@ -798,6 +799,12 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
}
}
fn inclusive_ancestors(self) -> AncestorIterator<'a> {
AncestorIterator {
current: Some(self.clone())
}
}
fn owner_doc(self) -> Temporary<Document> {
self.owner_doc.get().unwrap()
}

View file

@ -44,6 +44,9 @@ interface Element : Node {
boolean hasAttribute(DOMString name);
boolean hasAttributeNS(DOMString? namespace, DOMString localName);
[Throws]
Element? closest(DOMString selectors);
[Throws]
boolean matches(DOMString selectors);