mirror of
https://github.com/servo/servo.git
synced 2025-06-24 17:14:33 +01:00
auto merge of #1952 : brunoabinader/servo/htmlcollection-live, r=Ms2ger
Closes #1662. PS: Cached collections will be next step.
This commit is contained in:
commit
0204745595
8 changed files with 197 additions and 81 deletions
|
@ -20,7 +20,7 @@ use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElemen
|
||||||
use dom::element::{HTMLBodyElementTypeId, HTMLFrameSetElementTypeId};
|
use dom::element::{HTMLBodyElementTypeId, HTMLFrameSetElementTypeId};
|
||||||
use dom::event::Event;
|
use dom::event::Event;
|
||||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::htmlcollection::HTMLCollection;
|
use dom::htmlcollection::{HTMLCollection, CollectionFilter};
|
||||||
use dom::nodelist::NodeList;
|
use dom::nodelist::NodeList;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmlheadelement::HTMLHeadElement;
|
use dom::htmlheadelement::HTMLHeadElement;
|
||||||
|
@ -475,12 +475,26 @@ impl Document {
|
||||||
|
|
||||||
pub fn Images(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
pub fn Images(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1847
|
// FIXME: https://github.com/mozilla/servo/issues/1847
|
||||||
HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), ~"img")
|
struct ImagesFilter;
|
||||||
|
impl CollectionFilter for ImagesFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
elem.get().tag_name == ~"img"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let filter = ~ImagesFilter;
|
||||||
|
HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Embeds(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
pub fn Embeds(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1847
|
// FIXME: https://github.com/mozilla/servo/issues/1847
|
||||||
HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), ~"embed")
|
struct EmbedsFilter;
|
||||||
|
impl CollectionFilter for EmbedsFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
elem.get().tag_name == ~"embed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let filter = ~EmbedsFilter;
|
||||||
|
HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Plugins(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
pub fn Plugins(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
||||||
|
@ -490,32 +504,63 @@ impl Document {
|
||||||
|
|
||||||
pub fn Links(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
pub fn Links(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1847
|
// FIXME: https://github.com/mozilla/servo/issues/1847
|
||||||
HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), |elem| {
|
struct LinksFilter;
|
||||||
("a" == elem.get().tag_name || "area" == elem.get().tag_name) &&
|
impl CollectionFilter for LinksFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
(elem.get().tag_name == ~"a" || elem.get().tag_name == ~"area") &&
|
||||||
elem.get_attribute(Null, "href").is_some()
|
elem.get_attribute(Null, "href").is_some()
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
let filter = ~LinksFilter;
|
||||||
|
HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Forms(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
pub fn Forms(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1847
|
// FIXME: https://github.com/mozilla/servo/issues/1847
|
||||||
HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), ~"form")
|
struct FormsFilter;
|
||||||
|
impl CollectionFilter for FormsFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
elem.get().tag_name == ~"form"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let filter = ~FormsFilter;
|
||||||
|
HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Scripts(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
pub fn Scripts(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1847
|
// FIXME: https://github.com/mozilla/servo/issues/1847
|
||||||
HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), ~"script")
|
struct ScriptsFilter;
|
||||||
|
impl CollectionFilter for ScriptsFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
elem.get().tag_name == ~"script"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let filter = ~ScriptsFilter;
|
||||||
|
HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Anchors(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
pub fn Anchors(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1847
|
// FIXME: https://github.com/mozilla/servo/issues/1847
|
||||||
HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), |elem| {
|
struct AnchorsFilter;
|
||||||
"a" == elem.get().tag_name && elem.get_attribute(Null, "name").is_some()
|
impl CollectionFilter for AnchorsFilter {
|
||||||
})
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
elem.get().tag_name == ~"a" && elem.get_attribute(Null, "name").is_some()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let filter = ~AnchorsFilter;
|
||||||
|
HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Applets(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
pub fn Applets(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> {
|
||||||
// FIXME: This should be return OBJECT elements containing applets.
|
// FIXME: This should be return OBJECT elements containing applets.
|
||||||
HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), ~"applet")
|
struct AppletsFilter;
|
||||||
|
impl CollectionFilter for AppletsFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
elem.get().tag_name == ~"applet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let filter = ~AppletsFilter;
|
||||||
|
HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_collection<T>(&self, callback: |elem: &JS<Node>| -> Option<JS<T>>) -> ~[JS<T>] {
|
pub fn create_collection<T>(&self, callback: |elem: &JS<Node>| -> Option<JS<T>>) -> ~[JS<T>] {
|
||||||
|
|
|
@ -12,69 +12,123 @@ use dom::window::Window;
|
||||||
use servo_util::namespace::Namespace;
|
use servo_util::namespace::Namespace;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
|
||||||
|
use serialize::{Encoder, Encodable};
|
||||||
|
|
||||||
|
pub trait CollectionFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: Encoder> Encodable<S> for ~CollectionFilter {
|
||||||
|
fn encode(&self, _s: &mut S) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deriving(Encodable)]
|
||||||
|
pub enum CollectionTypeId {
|
||||||
|
Static(~[JS<Element>]),
|
||||||
|
Live(JS<Node>, ~CollectionFilter)
|
||||||
|
}
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
pub struct HTMLCollection {
|
pub struct HTMLCollection {
|
||||||
elements: ~[JS<Element>],
|
collection: CollectionTypeId,
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
window: JS<Window>,
|
window: JS<Window>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLCollection {
|
impl HTMLCollection {
|
||||||
pub fn new_inherited(window: JS<Window>, elements: ~[JS<Element>]) -> HTMLCollection {
|
pub fn new_inherited(window: JS<Window>, collection: CollectionTypeId) -> HTMLCollection {
|
||||||
HTMLCollection {
|
HTMLCollection {
|
||||||
elements: elements,
|
collection: collection,
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
window: window,
|
window: window,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(window: &JS<Window>, elements: ~[JS<Element>]) -> JS<HTMLCollection> {
|
pub fn new(window: &JS<Window>, collection: CollectionTypeId) -> JS<HTMLCollection> {
|
||||||
reflect_dom_object(~HTMLCollection::new_inherited(window.clone(), elements),
|
reflect_dom_object(~HTMLCollection::new_inherited(window.clone(), collection),
|
||||||
window, HTMLCollectionBinding::Wrap)
|
window, HTMLCollectionBinding::Wrap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLCollection {
|
impl HTMLCollection {
|
||||||
pub fn create(window: &JS<Window>, root: &JS<Node>, predicate: |elem: &JS<Element>| -> bool) -> JS<HTMLCollection> {
|
pub fn create(window: &JS<Window>, root: &JS<Node>, filter: ~CollectionFilter) -> JS<HTMLCollection> {
|
||||||
let mut elements = ~[];
|
HTMLCollection::new(window, Live(root.clone(), filter))
|
||||||
for child in root.traverse_preorder() {
|
|
||||||
if child.is_element() {
|
|
||||||
let elem: JS<Element> = ElementCast::to(&child).unwrap();
|
|
||||||
if predicate(&elem) {
|
|
||||||
elements.push(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HTMLCollection::new(window, elements)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn by_tag_name(window: &JS<Window>, root: &JS<Node>, tag_name: DOMString) -> JS<HTMLCollection> {
|
pub fn by_tag_name(window: &JS<Window>, root: &JS<Node>, tag: DOMString)
|
||||||
HTMLCollection::create(window, root, |elem| elem.get().tag_name == tag_name)
|
-> JS<HTMLCollection> {
|
||||||
|
struct TagNameFilter {
|
||||||
|
tag: DOMString
|
||||||
|
}
|
||||||
|
impl CollectionFilter for TagNameFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
elem.get().tag_name == self.tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let filter = TagNameFilter {
|
||||||
|
tag: tag
|
||||||
|
};
|
||||||
|
HTMLCollection::create(window, root, ~filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn by_tag_name_ns(window: &JS<Window>, root: &JS<Node>, tag_name: DOMString, namespace: Namespace) -> JS<HTMLCollection> {
|
pub fn by_tag_name_ns(window: &JS<Window>, root: &JS<Node>, tag: DOMString,
|
||||||
HTMLCollection::create(window, root, |elem| elem.get().namespace == namespace && elem.get().tag_name == tag_name)
|
namespace: Namespace) -> JS<HTMLCollection> {
|
||||||
|
struct TagNameNSFilter {
|
||||||
|
tag: DOMString,
|
||||||
|
namespace: Namespace
|
||||||
|
}
|
||||||
|
impl CollectionFilter for TagNameNSFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
elem.get().namespace == self.namespace && elem.get().tag_name == self.tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let filter = TagNameNSFilter {
|
||||||
|
tag: tag,
|
||||||
|
namespace: namespace
|
||||||
|
};
|
||||||
|
HTMLCollection::create(window, root, ~filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn by_class_name(window: &JS<Window>, root: &JS<Node>, classes: DOMString) -> JS<HTMLCollection> {
|
pub fn by_class_name(window: &JS<Window>, root: &JS<Node>, classes: DOMString)
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1840
|
-> JS<HTMLCollection> {
|
||||||
let classes: ~[&str] = classes.split(' ').collect();
|
struct ClassNameFilter {
|
||||||
HTMLCollection::create(window, root, |elem| classes.iter().all(|class| elem.has_class(*class)))
|
classes: ~[DOMString]
|
||||||
|
}
|
||||||
|
impl CollectionFilter for ClassNameFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
self.classes.iter().all(|class| elem.has_class(*class))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let filter = ClassNameFilter {
|
||||||
|
classes: classes.split(' ').map(|class| class.into_owned()).to_owned_vec()
|
||||||
|
};
|
||||||
|
HTMLCollection::create(window, root, ~filter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLCollection {
|
impl HTMLCollection {
|
||||||
// http://dom.spec.whatwg.org/#dom-htmlcollection-length
|
// http://dom.spec.whatwg.org/#dom-htmlcollection-length
|
||||||
pub fn Length(&self) -> u32 {
|
pub fn Length(&self) -> u32 {
|
||||||
self.elements.len() as u32
|
match self.collection {
|
||||||
|
Static(ref elems) => elems.len() as u32,
|
||||||
|
Live(ref root, ref filter) => root.traverse_preorder()
|
||||||
|
.count(|child| {
|
||||||
|
let elem: Option<JS<Element>> = ElementCast::to(&child);
|
||||||
|
elem.map_or(false, |elem| filter.filter(&elem, root))
|
||||||
|
}) as u32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://dom.spec.whatwg.org/#dom-htmlcollection-item
|
// http://dom.spec.whatwg.org/#dom-htmlcollection-item
|
||||||
pub fn Item(&self, index: u32) -> Option<JS<Element>> {
|
pub fn Item(&self, index: u32) -> Option<JS<Element>> {
|
||||||
if index < self.Length() {
|
match self.collection {
|
||||||
Some(self.elements[index].clone())
|
Static(ref elems) => elems
|
||||||
} else {
|
.get(index as uint)
|
||||||
None
|
.map(|elem| elem.clone()),
|
||||||
|
Live(ref root, ref filter) => root.traverse_preorder()
|
||||||
|
.filter_map(|node| ElementCast::to(&node))
|
||||||
|
.filter(|elem| filter.filter(elem, root))
|
||||||
|
.nth(index as uint).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,9 +140,20 @@ impl HTMLCollection {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2.
|
// Step 2.
|
||||||
self.elements.iter().find(|elem| {
|
match self.collection {
|
||||||
elem.get_string_attribute("name") == key || elem.get_string_attribute("id") == key
|
Static(ref elems) => elems.iter()
|
||||||
}).map(|maybe_elem| maybe_elem.clone())
|
.find(|elem| {
|
||||||
|
elem.get_string_attribute("name") == key ||
|
||||||
|
elem.get_string_attribute("id") == key })
|
||||||
|
.map(|maybe_elem| maybe_elem.clone()),
|
||||||
|
Live(ref root, ref filter) => root.traverse_preorder()
|
||||||
|
.filter_map(|node| ElementCast::to(&node))
|
||||||
|
.filter(|elem| filter.filter(elem, root))
|
||||||
|
.find(|elem| {
|
||||||
|
elem.get_string_attribute("name") == key ||
|
||||||
|
elem.get_string_attribute("id") == key })
|
||||||
|
.map(|maybe_elem| maybe_elem.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@ use dom::bindings::codegen::HTMLDataListElementBinding;
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLDataListElementDerived, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{HTMLDataListElementDerived, NodeCast};
|
||||||
use dom::bindings::js::JS;
|
use dom::bindings::js::JS;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::HTMLDataListElementTypeId;
|
use dom::element::{Element, HTMLDataListElementTypeId};
|
||||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::htmlcollection::HTMLCollection;
|
use dom::htmlcollection::{HTMLCollection, CollectionFilter};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{Node, ElementNodeTypeId};
|
use dom::node::{Node, ElementNodeTypeId, window_from_node};
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
|
@ -42,9 +42,14 @@ impl HTMLDataListElement {
|
||||||
|
|
||||||
impl HTMLDataListElement {
|
impl HTMLDataListElement {
|
||||||
pub fn Options(&self, abstract_self: &JS<HTMLDataListElement>) -> JS<HTMLCollection> {
|
pub fn Options(&self, abstract_self: &JS<HTMLDataListElement>) -> JS<HTMLCollection> {
|
||||||
|
struct HTMLDataListOptionsFilter;
|
||||||
|
impl CollectionFilter for HTMLDataListOptionsFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
|
||||||
|
elem.get().tag_name == ~"option"
|
||||||
|
}
|
||||||
|
}
|
||||||
let node: JS<Node> = NodeCast::from(abstract_self);
|
let node: JS<Node> = NodeCast::from(abstract_self);
|
||||||
let doc = &self.htmlelement.element.node.owner_doc();
|
let filter = ~HTMLDataListOptionsFilter;
|
||||||
let window = &doc.get().window;
|
HTMLCollection::create(&window_from_node(&node), &node, filter)
|
||||||
HTMLCollection::by_tag_name(window, &node, ~"option")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,11 @@ use dom::document::Document;
|
||||||
use dom::element::{Element, HTMLFieldSetElementTypeId};
|
use dom::element::{Element, HTMLFieldSetElementTypeId};
|
||||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::htmlformelement::HTMLFormElement;
|
use dom::htmlformelement::HTMLFormElement;
|
||||||
use dom::htmlcollection::HTMLCollection;
|
use dom::htmlcollection::{HTMLCollection, CollectionFilter};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{Node, ElementNodeTypeId, window_from_node};
|
use dom::node::{Node, ElementNodeTypeId, window_from_node};
|
||||||
use dom::validitystate::ValidityState;
|
use dom::validitystate::ValidityState;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::{DOMString, StaticStringVec};
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
pub struct HTMLFieldSetElement {
|
pub struct HTMLFieldSetElement {
|
||||||
|
@ -68,12 +68,20 @@ impl HTMLFieldSetElement {
|
||||||
~""
|
~""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://www.whatwg.org/html/#dom-fieldset-elements
|
||||||
pub fn Elements(&self, abstract_self: &JS<HTMLFieldSetElement>) -> JS<HTMLCollection> {
|
pub fn Elements(&self, abstract_self: &JS<HTMLFieldSetElement>) -> JS<HTMLCollection> {
|
||||||
|
struct ElementsFilter;
|
||||||
|
impl CollectionFilter for ElementsFilter {
|
||||||
|
fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool {
|
||||||
|
static tag_names: StaticStringVec = &["button", "fieldset", "input",
|
||||||
|
"keygen", "object", "output", "select", "textarea"];
|
||||||
|
let root: &JS<Element> = &ElementCast::to(root).unwrap();
|
||||||
|
elem != root && tag_names.iter().any(|&tag_name| tag_name == elem.get().tag_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
let node: JS<Node> = NodeCast::from(abstract_self);
|
let node: JS<Node> = NodeCast::from(abstract_self);
|
||||||
let element: JS<Element> = ElementCast::from(abstract_self);
|
let filter = ~ElementsFilter;
|
||||||
let window = &window_from_node(&node);
|
HTMLCollection::create(&window_from_node(&node), &node, filter)
|
||||||
let listed_elements = ["button", "fieldset", "input", "keygen", "object", "output", "select", "textarea"];
|
|
||||||
HTMLCollection::create(window, &node, |elem| *elem != element && listed_elements.iter().any(|&tag_name| tag_name == elem.get().tag_name))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn WillValidate(&self) -> bool {
|
pub fn WillValidate(&self) -> bool {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::error::ErrorResult;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{Element, HTMLFormElementTypeId};
|
use dom::element::{Element, HTMLFormElementTypeId};
|
||||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::htmlcollection::HTMLCollection;
|
use dom::htmlcollection::{HTMLCollection, Static};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{Node, ElementNodeTypeId};
|
use dom::node::{Node, ElementNodeTypeId};
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
@ -118,7 +118,7 @@ impl HTMLFormElement {
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1844
|
// FIXME: https://github.com/mozilla/servo/issues/1844
|
||||||
let doc = self.htmlelement.element.node.owner_doc();
|
let doc = self.htmlelement.element.node.owner_doc();
|
||||||
let doc = doc.get();
|
let doc = doc.get();
|
||||||
HTMLCollection::new(&doc.window, ~[])
|
HTMLCollection::new(&doc.window, Static(~[]))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Length(&self) -> i32 {
|
pub fn Length(&self) -> i32 {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::error::ErrorResult;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::HTMLMapElementTypeId;
|
use dom::element::HTMLMapElementTypeId;
|
||||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::htmlcollection::HTMLCollection;
|
use dom::htmlcollection::{HTMLCollection, Static};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{Node, ElementNodeTypeId};
|
use dom::node::{Node, ElementNodeTypeId};
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
@ -54,6 +54,6 @@ impl HTMLMapElement {
|
||||||
// FIXME: https://github.com/mozilla/servo/issues/1845
|
// FIXME: https://github.com/mozilla/servo/issues/1845
|
||||||
let doc = self.htmlelement.element.node.owner_doc();
|
let doc = self.htmlelement.element.node.owner_doc();
|
||||||
let doc = doc.get();
|
let doc = doc.get();
|
||||||
HTMLCollection::new(&doc.window, ~[])
|
HTMLCollection::new(&doc.window, Static(~[]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
pub type DOMString = ~str;
|
pub type DOMString = ~str;
|
||||||
|
pub type StaticStringVec = &'static [&'static str];
|
||||||
|
|
||||||
pub fn null_str_as_empty(s: &Option<DOMString>) -> DOMString {
|
pub fn null_str_as_empty(s: &Option<DOMString>) -> DOMString {
|
||||||
// We don't use map_default because it would allocate ~"" even for Some.
|
// We don't use map_default because it would allocate ~"" even for Some.
|
||||||
|
|
|
@ -40,33 +40,25 @@
|
||||||
is(htmlcollection.length, 1);
|
is(htmlcollection.length, 1);
|
||||||
is(htmlcollection.item(0), live);
|
is(htmlcollection.item(0), live);
|
||||||
|
|
||||||
is(live.childNodes.length, 0)
|
let new_live = document.createElement("div");
|
||||||
is(htmlcollection.item(0).childNodes.length, 0);
|
new_live.className = "live";
|
||||||
is(document.getElementById("live").childNodes.length, 0);
|
document.body.appendChild(new_live);
|
||||||
|
is(htmlcollection.length, 2);
|
||||||
|
is(htmlcollection.item(1), new_live);
|
||||||
|
|
||||||
live.appendChild(child);
|
document.body.removeChild(new_live);
|
||||||
|
is(htmlcollection.length, 1);
|
||||||
is(live.childNodes.length, 1);
|
|
||||||
is(htmlcollection.item(0).childNodes.length, 1);
|
|
||||||
is(document.getElementById("live").childNodes.length, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test3: getElementsByTagName
|
// test3: getElementsByTagName
|
||||||
{
|
{
|
||||||
htmlcollection = document.getElementsByTagName("div");
|
is(document.getElementsByTagName("DIV").length, 0);
|
||||||
is(htmlcollection.length, 5);
|
|
||||||
|
|
||||||
let from_element = document.documentElement.getElementsByTagName("div");
|
is(document.getElementsByTagName("div").length,
|
||||||
is(htmlcollection.length, from_element.length);
|
document.documentElement.getElementsByTagName("div").length);
|
||||||
|
|
||||||
htmlcollection = document.getElementsByTagName("DIV");
|
is(document.getElementsByTagName("p").length,
|
||||||
is(htmlcollection.length, 0);
|
document.getElementById("class-example").getElementsByTagName("p").length);
|
||||||
|
|
||||||
htmlcollection = document.getElementsByTagName("p");
|
|
||||||
is(htmlcollection.length, 4);
|
|
||||||
|
|
||||||
from_element = document.getElementById("class-example").getElementsByTagName("p");
|
|
||||||
is(from_element.length, 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test4: getElementsByTagNameNS
|
// test4: getElementsByTagNameNS
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue