diff options
author | Ms2ger <ms2ger@gmail.com> | 2014-06-08 16:45:06 +0200 |
---|---|---|
committer | Ms2ger <ms2ger@gmail.com> | 2014-06-13 14:13:00 +0200 |
commit | 972c69883e2014a84a010790a88f234f9397583b (patch) | |
tree | 39da75e17821cc3689a6168a31a6fd6888e1dcc2 | |
parent | 0803e5d0aca8f803dcd88831cb7fd0f56021ebc9 (diff) | |
download | servo-972c69883e2014a84a010790a88f234f9397583b.tar.gz servo-972c69883e2014a84a010790a88f234f9397583b.zip |
Implement Element.classList (partially fixes #1717).
-rw-r--r-- | src/components/script/dom/bindings/codegen/Bindings.conf | 1 | ||||
-rw-r--r-- | src/components/script/dom/domtokenlist.rs | 103 | ||||
-rw-r--r-- | src/components/script/dom/element.rs | 18 | ||||
-rw-r--r-- | src/components/script/dom/webidls/DOMTokenList.webidl | 15 | ||||
-rw-r--r-- | src/components/script/dom/webidls/Element.webidl | 4 | ||||
-rw-r--r-- | src/components/script/script.rs | 1 |
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; |