mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
auto merge of #2632 : brunoabinader/servo/document-queryselectorall, r=Ms2ger
Spec: http://dom.spec.whatwg.org/#dom-parentnode-queryselectorall Closes #851.
This commit is contained in:
commit
baa97fe6e5
6 changed files with 116 additions and 3 deletions
|
@ -330,6 +330,7 @@ pub trait DocumentMethods {
|
|||
fn Location(&self) -> Temporary<Location>;
|
||||
fn Children(&self) -> Temporary<HTMLCollection>;
|
||||
fn QuerySelector(&self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>>;
|
||||
fn QuerySelectorAll(&self, selectors: DOMString) -> Fallible<Temporary<NodeList>>;
|
||||
fn GetOnclick(&self) -> Option<EventHandlerNonNull>;
|
||||
fn SetOnclick(&self, listener: Option<EventHandlerNonNull>);
|
||||
fn GetOnload(&self) -> Option<EventHandlerNonNull>;
|
||||
|
@ -821,6 +822,12 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
|
|||
root.query_selector(selectors)
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
|
||||
fn QuerySelectorAll(&self, selectors: DOMString) -> Fallible<Temporary<NodeList>> {
|
||||
let root: &JSRef<Node> = NodeCast::from_ref(self);
|
||||
root.query_selector_all(selectors)
|
||||
}
|
||||
|
||||
fn GetOnclick(&self) -> Option<EventHandlerNonNull> {
|
||||
let eventtarget: &JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
||||
eventtarget.get_event_handler_common("click")
|
||||
|
|
|
@ -11,6 +11,7 @@ use dom::element::Element;
|
|||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||
use dom::htmlcollection::HTMLCollection;
|
||||
use dom::node::{DocumentFragmentNodeTypeId, Node, NodeHelpers, window_from_node};
|
||||
use dom::nodelist::NodeList;
|
||||
use dom::window::{Window, WindowMethods};
|
||||
use servo_util::str::DOMString;
|
||||
|
||||
|
@ -49,6 +50,7 @@ impl DocumentFragment {
|
|||
pub trait DocumentFragmentMethods {
|
||||
fn Children(&self) -> Temporary<HTMLCollection>;
|
||||
fn QuerySelector(&self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>>;
|
||||
fn QuerySelectorAll(&self, selectors: DOMString) -> Fallible<Temporary<NodeList>>;
|
||||
}
|
||||
|
||||
impl<'a> DocumentFragmentMethods for JSRef<'a, DocumentFragment> {
|
||||
|
@ -63,4 +65,11 @@ impl<'a> DocumentFragmentMethods for JSRef<'a, DocumentFragment> {
|
|||
let root: &JSRef<Node> = NodeCast::from_ref(self);
|
||||
root.query_selector(selectors)
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
|
||||
fn QuerySelectorAll(&self, selectors: DOMString) -> Fallible<Temporary<NodeList>> {
|
||||
let root: &JSRef<Node> = NodeCast::from_ref(self);
|
||||
root.query_selector_all(selectors)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ use dom::htmlcollection::HTMLCollection;
|
|||
use dom::htmlserializer::serialize;
|
||||
use dom::node::{ElementNodeTypeId, Node, NodeHelpers, NodeIterator, document_from_node};
|
||||
use dom::node::{window_from_node, LayoutNodeHelpers};
|
||||
use dom::nodelist::NodeList;
|
||||
use dom::virtualmethods::{VirtualMethods, vtable_for};
|
||||
use layout_interface::ContentChangedDocumentDamage;
|
||||
use layout_interface::MatchSelectorsDocumentDamage;
|
||||
|
@ -430,6 +431,7 @@ pub trait ElementMethods {
|
|||
fn GetOuterHTML(&self) -> Fallible<DOMString>;
|
||||
fn Children(&self) -> Temporary<HTMLCollection>;
|
||||
fn QuerySelector(&self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>>;
|
||||
fn QuerySelectorAll(&self, selectors: DOMString) -> Fallible<Temporary<NodeList>>;
|
||||
fn Remove(&self);
|
||||
}
|
||||
|
||||
|
@ -712,6 +714,12 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
root.query_selector(selectors)
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
|
||||
fn QuerySelectorAll(&self, selectors: DOMString) -> Fallible<Temporary<NodeList>> {
|
||||
let root: &JSRef<Node> = NodeCast::from_ref(self);
|
||||
root.query_selector_all(selectors)
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-childnode-remove
|
||||
fn Remove(&self) {
|
||||
let node: &JSRef<Node> = NodeCast::from_ref(self);
|
||||
|
|
|
@ -399,6 +399,7 @@ pub trait NodeHelpers {
|
|||
fn get_content_boxes(&self) -> Vec<Rect<Au>>;
|
||||
|
||||
fn query_selector(&self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>>;
|
||||
fn query_selector_all(&self, selectors: DOMString) -> Fallible<Temporary<NodeList>>;
|
||||
|
||||
fn remove_self(&self);
|
||||
}
|
||||
|
@ -569,9 +570,9 @@ impl<'a> NodeHelpers for JSRef<'a, Node> {
|
|||
None => return Err(Syntax),
|
||||
// Step 3.
|
||||
Some(ref selectors) => {
|
||||
let root = self.ancestors().last().unwrap_or(self.clone());
|
||||
for selector in selectors.iter() {
|
||||
assert!(selector.pseudo_element.is_none());
|
||||
let root = self.ancestors().last().unwrap_or(self.clone());
|
||||
for node in root.traverse_preorder().filter(|node| node.is_element()) {
|
||||
let mut _shareable: bool = false;
|
||||
if matches_compound_selector(selector.compound_selectors.deref(), &node, &mut _shareable) {
|
||||
|
@ -585,6 +586,32 @@ impl<'a> NodeHelpers for JSRef<'a, Node> {
|
|||
Ok(None)
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
|
||||
fn query_selector_all(&self, selectors: DOMString) -> Fallible<Temporary<NodeList>> {
|
||||
// Step 1.
|
||||
let mut nodes = vec!();
|
||||
let root = self.ancestors().last().unwrap_or(self.clone());
|
||||
let namespace = NamespaceMap::new();
|
||||
match parse_selector_list(tokenize(selectors.as_slice()).map(|(token, _)| token).collect(), &namespace) {
|
||||
// Step 2.
|
||||
None => return Err(Syntax),
|
||||
// Step 3.
|
||||
Some(ref selectors) => {
|
||||
for selector in selectors.iter() {
|
||||
assert!(selector.pseudo_element.is_none());
|
||||
for node in root.traverse_preorder().filter(|node| node.is_element()) {
|
||||
let mut _shareable: bool = false;
|
||||
if matches_compound_selector(selector.compound_selectors.deref(), &node, &mut _shareable) {
|
||||
nodes.push(node.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let window = window_from_node(self).root();
|
||||
Ok(NodeList::new_simple_list(&window.root_ref(), nodes))
|
||||
}
|
||||
|
||||
fn ancestors(&self) -> AncestorIterator {
|
||||
AncestorIterator {
|
||||
current: self.parent_node.get().map(|node| (*node.root()).clone()),
|
||||
|
|
|
@ -24,8 +24,11 @@ interface ParentNode {
|
|||
// void append((Node or DOMString)... nodes);
|
||||
|
||||
//Element? query(DOMString relativeSelectors);
|
||||
//[NewObject] Elements queryAll(DOMString relativeSelectors);
|
||||
//[NewObject]
|
||||
//Elements queryAll(DOMString relativeSelectors);
|
||||
[Throws]
|
||||
Element? querySelector(DOMString selectors);
|
||||
//[NewObject] NodeList querySelectorAll(DOMString selectors);
|
||||
//[NewObject]
|
||||
[Throws]
|
||||
NodeList querySelectorAll(DOMString selectors);
|
||||
};
|
||||
|
|
59
src/test/content/test_parentNode_querySelectorAll.html
Normal file
59
src/test/content/test_parentNode_querySelectorAll.html
Normal file
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="harness.js"></script>
|
||||
<script>
|
||||
let foo = document.getElementById("foo");
|
||||
let bar = document.getElementById("bar");
|
||||
let baz = document.getElementById("baz");
|
||||
|
||||
{ // document.querySelector
|
||||
let nodelist = document.querySelectorAll(".test");
|
||||
is_a(nodelist, NodeList);
|
||||
is(nodelist.length, 3);
|
||||
is(nodelist.item(0), foo);
|
||||
is(nodelist.item(1), bar);
|
||||
is(nodelist.item(2), baz);
|
||||
|
||||
nodelist = document.querySelectorAll("div > .test");
|
||||
is(nodelist.length, 3);
|
||||
}
|
||||
|
||||
{ // element.querySelector
|
||||
let div = document.getElementById("parent");
|
||||
let nodelist = div.querySelectorAll(".test");
|
||||
is(nodelist.length, 3);
|
||||
|
||||
nodelist = div.querySelectorAll("div:nth-of-type(1)");
|
||||
is(nodelist.item(0), div);
|
||||
}
|
||||
|
||||
{ // docfrag.querySelector
|
||||
let docfrag = document.createDocumentFragment();
|
||||
|
||||
let div = document.createElement("div");
|
||||
div.id = "foo";
|
||||
div.className = "myClass";
|
||||
|
||||
let child = document.createElement("div");
|
||||
div.appendChild(child);
|
||||
docfrag.appendChild(div);
|
||||
|
||||
let nodelist = docfrag.querySelectorAll("#foo");
|
||||
is(nodelist.item(0), div);
|
||||
|
||||
nodelist = docfrag.querySelectorAll("#foo:nth-child(1)");
|
||||
is(nodelist.item(0), div);
|
||||
}
|
||||
|
||||
finish();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="parent">
|
||||
<div id="foo" class="test"></div>
|
||||
<div id="bar" class="test"></div>
|
||||
<div id="baz" class="test"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue