aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMs2ger <ms2ger@gmail.com>2014-06-08 16:45:06 +0200
committerMs2ger <ms2ger@gmail.com>2014-06-13 14:13:00 +0200
commit972c69883e2014a84a010790a88f234f9397583b (patch)
tree39da75e17821cc3689a6168a31a6fd6888e1dcc2
parent0803e5d0aca8f803dcd88831cb7fd0f56021ebc9 (diff)
downloadservo-972c69883e2014a84a010790a88f234f9397583b.tar.gz
servo-972c69883e2014a84a010790a88f234f9397583b.zip
Implement Element.classList (partially fixes #1717).
-rw-r--r--src/components/script/dom/bindings/codegen/Bindings.conf1
-rw-r--r--src/components/script/dom/domtokenlist.rs103
-rw-r--r--src/components/script/dom/element.rs18
-rw-r--r--src/components/script/dom/webidls/DOMTokenList.webidl15
-rw-r--r--src/components/script/dom/webidls/Element.webidl4
-rw-r--r--src/components/script/script.rs1
6 files changed, 139 insertions, 3 deletions
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf
index d6202de9956..eba419c0a4f 100644
--- a/src/components/script/dom/bindings/codegen/Bindings.conf
+++ b/src/components/script/dom/bindings/codegen/Bindings.conf
@@ -32,6 +32,7 @@ DOMInterfaces = {
'DOMException': {},
'DOMImplementation': {},
'DOMParser': {},
+'DOMTokenList': {},
'Element': {},
'Event': {},
'EventHandler': {},
diff --git a/src/components/script/dom/domtokenlist.rs b/src/components/script/dom/domtokenlist.rs
new file mode 100644
index 00000000000..b0a6f2c73c2
--- /dev/null
+++ b/src/components/script/dom/domtokenlist.rs
@@ -0,0 +1,103 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use dom::attr::{Attr, TokenListAttrValue};
+use dom::bindings::codegen::Bindings::DOMTokenListBinding;
+use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable};
+use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object};
+use dom::element::{Element, AttributeHandlers};
+use dom::node::window_from_node;
+
+use servo_util::namespace::Null;
+use servo_util::str::DOMString;
+
+#[deriving(Encodable)]
+pub struct DOMTokenList {
+ reflector_: Reflector,
+ element: JS<Element>,
+ local_name: &'static str,
+}
+
+impl DOMTokenList {
+ pub fn new_inherited(element: &JSRef<Element>,
+ local_name: &'static str) -> DOMTokenList {
+ DOMTokenList {
+ reflector_: Reflector::new(),
+ element: JS::from_rooted(element.clone()),
+ local_name: local_name,
+ }
+ }
+
+ pub fn new(element: &JSRef<Element>,
+ local_name: &'static str) -> Temporary<DOMTokenList> {
+ let window = window_from_node(element).root();
+ reflect_dom_object(box DOMTokenList::new_inherited(element, local_name),
+ &*window, DOMTokenListBinding::Wrap)
+ }
+}
+
+impl Reflectable for DOMTokenList {
+ fn reflector<'a>(&'a self) -> &'a Reflector {
+ &self.reflector_
+ }
+
+ fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
+ &mut self.reflector_
+ }
+}
+
+trait PrivateDOMTokenListHelpers {
+ fn attribute(&self) -> Option<Temporary<Attr>>;
+}
+
+impl<'a> PrivateDOMTokenListHelpers for JSRef<'a, DOMTokenList> {
+ fn attribute(&self) -> Option<Temporary<Attr>> {
+ let element = self.element.root();
+ element.deref().get_attribute(Null, self.local_name)
+ }
+}
+
+pub trait DOMTokenListMethods {
+ fn Length(&self) -> u32;
+ fn Item(&self, index: u32) -> Option<DOMString>;
+ fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<DOMString>;
+}
+
+// http://dom.spec.whatwg.org/#domtokenlist
+impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> {
+ // http://dom.spec.whatwg.org/#dom-domtokenlist-length
+ fn Length(&self) -> u32 {
+ let attribute = self.attribute().root();
+ match attribute {
+ Some(attribute) => {
+ match *attribute.deref().value() {
+ TokenListAttrValue(_, ref indexes) => indexes.len() as u32,
+ _ => fail!("Expected a TokenListAttrValue"),
+ }
+ }
+ None => 0,
+ }
+ }
+
+ // http://dom.spec.whatwg.org/#dom-domtokenlist-item
+ fn Item(&self, index: u32) -> Option<DOMString> {
+ let attribute = self.attribute().root();
+ attribute.and_then(|attribute| {
+ match *attribute.deref().value() {
+ TokenListAttrValue(ref value, ref indexes) => {
+ indexes.as_slice().get(index as uint).map(|&(start, end)| {
+ value.as_slice().slice(start, end).to_string()
+ })
+ },
+ _ => fail!("Expected a TokenListAttrValue"),
+ }
+ })
+ }
+
+ fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<DOMString> {
+ let item = self.Item(index);
+ *found = item.is_some();
+ item
+ }
+}
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs
index c346f6f2cf9..dfc7fc13e67 100644
--- a/src/components/script/dom/element.rs
+++ b/src/components/script/dom/element.rs
@@ -18,6 +18,7 @@ use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type};
use dom::clientrect::ClientRect;
use dom::clientrectlist::ClientRectList;
use dom::document::{Document, DocumentHelpers};
+use dom::domtokenlist::DOMTokenList;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlcollection::HTMLCollection;
use dom::htmlserializer::serialize;
@@ -43,7 +44,8 @@ pub struct Element {
pub prefix: Option<DOMString>,
pub attrs: RefCell<Vec<JS<Attr>>>,
pub style_attribute: Traceable<RefCell<Option<style::PropertyDeclarationBlock>>>,
- pub attr_list: Cell<Option<JS<AttrList>>>
+ pub attr_list: Cell<Option<JS<AttrList>>>,
+ class_list: Cell<Option<JS<DOMTokenList>>>,
}
impl ElementDerived for EventTarget {
@@ -151,6 +153,7 @@ impl Element {
prefix: prefix,
attrs: RefCell::new(vec!()),
attr_list: Cell::new(None),
+ class_list: Cell::new(None),
style_attribute: Traceable::new(RefCell::new(None)),
}
}
@@ -416,6 +419,7 @@ pub trait ElementMethods {
fn SetId(&self, id: DOMString);
fn ClassName(&self) -> DOMString;
fn SetClassName(&self, class: DOMString);
+ fn ClassList(&self) -> Temporary<DOMTokenList>;
fn Attributes(&self) -> Temporary<AttrList>;
fn GetAttribute(&self, name: DOMString) -> Option<DOMString>;
fn GetAttributeNS(&self, namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString>;
@@ -485,6 +489,18 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
self.set_tokenlist_attribute("class", class);
}
+ // http://dom.spec.whatwg.org/#dom-element-classlist
+ fn ClassList(&self) -> Temporary<DOMTokenList> {
+ match self.class_list.get() {
+ Some(class_list) => Temporary::new(class_list),
+ None => {
+ let class_list = DOMTokenList::new(self, "class").root();
+ self.class_list.assign(Some(class_list.deref().clone()));
+ Temporary::from_rooted(&*class_list)
+ }
+ }
+ }
+
// http://dom.spec.whatwg.org/#dom-element-attributes
fn Attributes(&self) -> Temporary<AttrList> {
match self.attr_list.get() {
diff --git a/src/components/script/dom/webidls/DOMTokenList.webidl b/src/components/script/dom/webidls/DOMTokenList.webidl
new file mode 100644
index 00000000000..650d8abf6c6
--- /dev/null
+++ b/src/components/script/dom/webidls/DOMTokenList.webidl
@@ -0,0 +1,15 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// http://dom.spec.whatwg.org/#domtokenlist
+interface DOMTokenList {
+ readonly attribute unsigned long length;
+ getter DOMString? item(unsigned long index);
+ //boolean contains(DOMString token);
+ //void add(DOMString... tokens);
+ //void remove(DOMString... tokens);
+ //boolean toggle(DOMString token, optional boolean force);
+ //stringifier;
+};
diff --git a/src/components/script/dom/webidls/Element.webidl b/src/components/script/dom/webidls/Element.webidl
index b6f9cca2541..e088a2263dd 100644
--- a/src/components/script/dom/webidls/Element.webidl
+++ b/src/components/script/dom/webidls/Element.webidl
@@ -28,8 +28,8 @@ interface Element : Node {
attribute DOMString id;
[Pure]
attribute DOMString className;
- /*[Constant]
- readonly attribute DOMTokenList? classList;*/
+ [Constant]
+ readonly attribute DOMTokenList classList;
[Constant]
readonly attribute AttrList attributes;
diff --git a/src/components/script/script.rs b/src/components/script/script.rs
index 860187dd5d2..9a47f08f6b5 100644
--- a/src/components/script/script.rs
+++ b/src/components/script/script.rs
@@ -78,6 +78,7 @@ pub mod dom {
pub mod domexception;
pub mod domimplementation;
pub mod domparser;
+ pub mod domtokenlist;
pub mod element;
pub mod event;
pub mod eventdispatcher;