diff options
-rw-r--r-- | src/components/script/dom/attr.rs | 59 | ||||
-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 | 105 | ||||
-rw-r--r-- | src/components/script/dom/htmlimageelement.rs | 12 | ||||
-rw-r--r-- | src/components/script/dom/htmlserializer.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/node.rs | 4 | ||||
-rw-r--r-- | src/components/script/dom/virtualmethods.rs | 10 | ||||
-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 |
11 files changed, 269 insertions, 47 deletions
diff --git a/src/components/script/dom/attr.rs b/src/components/script/dom/attr.rs index 741c5592732..c8e5ad88527 100644 --- a/src/components/script/dom/attr.rs +++ b/src/components/script/dom/attr.rs @@ -6,13 +6,13 @@ use dom::bindings::codegen::Bindings::AttrBinding; use dom::bindings::codegen::InheritTypes::NodeCast; use dom::bindings::js::{JS, JSRef, Temporary}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; -use dom::element::Element; +use dom::element::{Element, AttributeHandlers}; use dom::node::Node; use dom::window::Window; use dom::virtualmethods::vtable_for; use servo_util::namespace; use servo_util::namespace::Namespace; -use servo_util::str::DOMString; +use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS}; use std::cell::Cell; pub enum AttrSettingType { @@ -20,11 +20,45 @@ pub enum AttrSettingType { ReplacedAttr, } +#[deriving(Eq, Clone, Encodable)] +pub enum AttrValue { + StringAttrValue(DOMString), + TokenListAttrValue(DOMString, Vec<(uint, uint)>), + UIntAttrValue(DOMString, u32), +} + +impl AttrValue { + pub fn from_tokenlist(list: DOMString) -> AttrValue { + let mut indexes = vec![]; + let mut last_index: uint = 0; + for (index, ch) in list.as_slice().char_indices() { + if HTML_SPACE_CHARACTERS.iter().any(|&space| space == ch) { + indexes.push((last_index, index)); + last_index = index + 1; + } + } + return TokenListAttrValue(list, indexes); + } + + pub fn from_u32(string: DOMString, default: u32) -> AttrValue { + let result: u32 = from_str(string.as_slice()).unwrap_or(default); + UIntAttrValue(string, result) + } + + pub fn as_slice<'a>(&'a self) -> &'a str { + match *self { + StringAttrValue(ref value) | + TokenListAttrValue(ref value, _) | + UIntAttrValue(ref value, _) => value.as_slice(), + } + } +} + #[deriving(Encodable)] pub struct Attr { pub reflector_: Reflector, pub local_name: DOMString, - pub value: DOMString, + value: AttrValue, pub name: DOMString, pub namespace: Namespace, pub prefix: Option<DOMString>, @@ -44,7 +78,7 @@ impl Reflectable for Attr { } impl Attr { - fn new_inherited(local_name: DOMString, value: DOMString, + fn new_inherited(local_name: DOMString, value: AttrValue, name: DOMString, namespace: Namespace, prefix: Option<DOMString>, owner: &JSRef<Element>) -> Attr { Attr { @@ -58,14 +92,14 @@ impl Attr { } } - pub fn new(window: &JSRef<Window>, local_name: DOMString, value: DOMString, + pub fn new(window: &JSRef<Window>, local_name: DOMString, value: AttrValue, name: DOMString, namespace: Namespace, prefix: Option<DOMString>, owner: &JSRef<Element>) -> Temporary<Attr> { let attr = Attr::new_inherited(local_name, value, name, namespace, prefix, owner); reflect_dom_object(box attr, window, AttrBinding::Wrap) } - pub fn set_value(&mut self, set_type: AttrSettingType, value: DOMString) { + pub fn set_value(&mut self, set_type: AttrSettingType, value: AttrValue) { let owner = self.owner.get().root(); let node: &JSRef<Node> = NodeCast::from_ref(&*owner); let namespace_is_null = self.namespace == namespace::Null; @@ -73,7 +107,7 @@ impl Attr { match set_type { ReplacedAttr => { if namespace_is_null { - vtable_for(node).before_remove_attr(self.local_name.clone(), self.value.clone()); + vtable_for(node).before_remove_attr(self.local_name.clone(), self.value.as_slice().to_string()); } } FirstSetAttr => {} @@ -82,10 +116,14 @@ impl Attr { self.value = value; if namespace_is_null { - vtable_for(node).after_set_attr(self.local_name.clone(), self.value.clone()); + vtable_for(node).after_set_attr(self.local_name.clone(), self.value.as_slice().to_string()); } } + pub fn value<'a>(&'a self) -> &'a AttrValue { + &self.value + } + pub fn value_ref<'a>(&'a self) -> &'a str { self.value.as_slice() } @@ -106,10 +144,13 @@ impl<'a> AttrMethods for JSRef<'a, Attr> { } fn Value(&self) -> DOMString { - self.value.clone() + self.value.as_slice().to_string() } fn SetValue(&mut self, value: DOMString) { + let owner = self.owner.get().root(); + let value = owner.deref().parse_attribute( + &self.namespace, self.deref().local_name.as_slice(), value); self.set_value(ReplacedAttr, value); } 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 9e85eef9908..d9d498d72eb 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -5,6 +5,7 @@ //! Element nodes. use dom::attr::{Attr, ReplacedAttr, FirstSetAttr, AttrMethods}; +use dom::attr::{AttrValue, StringAttrValue, UIntAttrValue}; use dom::attrlist::AttrList; use dom::bindings::codegen::Bindings::ElementBinding; use dom::bindings::codegen::InheritTypes::{ElementDerived, NodeCast}; @@ -17,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 +45,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 +154,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)), } } @@ -174,9 +178,9 @@ impl RawLayoutElementHelpers for Element { (*attrs).iter().find(|attr: & &JS<Attr>| { let attr = attr.unsafe_get(); name == (*attr).local_name.as_slice() && (*attr).namespace == *namespace - }).map(|attr| { + }).map(|attr| { let attr = attr.unsafe_get(); - mem::transmute((*attr).value.as_slice()) + mem::transmute((*attr).value_ref()) }) } } @@ -223,11 +227,12 @@ pub trait AttributeHandlers { fn set_attribute_from_parser(&self, local_name: DOMString, value: DOMString, namespace: Namespace, prefix: Option<DOMString>); - fn set_attribute(&self, namespace: Namespace, name: DOMString, - value: DOMString) -> ErrorResult; - fn do_set_attribute(&self, local_name: DOMString, value: DOMString, + fn set_attribute(&self, name: &str, value: AttrValue); + fn do_set_attribute(&self, local_name: DOMString, value: AttrValue, name: DOMString, namespace: Namespace, prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool); + fn parse_attribute(&self, namespace: &Namespace, local_name: &str, + value: DOMString) -> AttrValue; fn remove_attribute(&self, namespace: Namespace, name: DOMString) -> ErrorResult; fn notify_attribute_changed(&self, local_name: DOMString); @@ -238,6 +243,8 @@ pub trait AttributeHandlers { fn set_url_attribute(&self, name: &str, value: DOMString); fn get_string_attribute(&self, name: &str) -> DOMString; fn set_string_attribute(&self, name: &str, value: DOMString); + fn set_tokenlist_attribute(&self, name: &str, value: DOMString); + fn get_uint_attribute(&self, name: &str) -> u32; fn set_uint_attribute(&self, name: &str, value: u32); } @@ -264,37 +271,23 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { None => local_name.clone(), Some(ref prefix) => format!("{:s}:{:s}", *prefix, local_name), }; + let value = self.parse_attribute(&namespace, local_name.as_slice(), value); self.do_set_attribute(local_name, value, name, namespace, prefix, |_| false) } - fn set_attribute(&self, namespace: Namespace, name: DOMString, - value: DOMString) -> ErrorResult { - let (prefix, local_name) = get_attribute_parts(name.clone()); - match prefix { - Some(ref prefix_str) => { - if namespace == namespace::Null || - ("xml" == prefix_str.as_slice() && namespace != namespace::XML) || - ("xmlns" == prefix_str.as_slice() && namespace != namespace::XMLNS) { - return Err(NamespaceError); - } - }, - None => {} - } + fn set_attribute(&self, name: &str, value: AttrValue) { + assert!(name == name.to_ascii_lower().as_slice()); + assert!(!name.contains(":")); let node: &JSRef<Node> = NodeCast::from_ref(self); node.wait_until_safe_to_modify_dom(); - let position: |&JSRef<Attr>| -> bool = - if self.html_element_in_html_document() { - |attr| attr.deref().local_name.as_slice().eq_ignore_ascii_case(local_name.as_slice()) - } else { - |attr| attr.deref().local_name == local_name - }; - self.do_set_attribute(name.clone(), value, name.clone(), namespace::Null, None, position); - Ok(()) + self.do_set_attribute(name.to_string(), value, name.to_string(), + namespace::Null, None, + |attr| attr.deref().local_name.as_slice() == name); } - fn do_set_attribute(&self, local_name: DOMString, value: DOMString, + fn do_set_attribute(&self, local_name: DOMString, value: AttrValue, name: DOMString, namespace: Namespace, prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool) { let idx = self.deref().attrs.borrow().iter() @@ -314,6 +307,16 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { self.deref().attrs.borrow().get(idx).root().set_value(set_type, value); } + fn parse_attribute(&self, namespace: &Namespace, local_name: &str, + value: DOMString) -> AttrValue { + if *namespace == namespace::Null { + vtable_for(NodeCast::from_ref(self)) + .parse_plain_attribute(local_name, value) + } else { + StringAttrValue(value) + } + } + fn remove_attribute(&self, namespace: Namespace, name: DOMString) -> ErrorResult { let (_, local_name) = get_attribute_parts(name.clone()); @@ -379,12 +382,30 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } fn set_string_attribute(&self, name: &str, value: DOMString) { assert!(name == name.to_ascii_lower().as_slice()); - assert!(self.set_attribute(Null, name.to_string(), value).is_ok()); + self.set_attribute(name, StringAttrValue(value)); } + fn set_tokenlist_attribute(&self, name: &str, value: DOMString) { + assert!(name == name.to_ascii_lower().as_slice()); + self.set_attribute(name, AttrValue::from_tokenlist(value)); + } + + fn get_uint_attribute(&self, name: &str) -> u32 { + assert!(name == name.to_ascii_lower().as_slice()); + let attribute = self.get_attribute(Null, name).root(); + match attribute { + Some(attribute) => { + match *attribute.deref().value() { + UIntAttrValue(_, value) => value, + _ => fail!("Expected a UIntAttrValue"), + } + } + None => 0, + } + } fn set_uint_attribute(&self, name: &str, value: u32) { assert!(name == name.to_ascii_lower().as_slice()); - assert!(self.set_attribute(Null, name.to_string(), value.to_str()).is_ok()); + self.set_attribute(name, UIntAttrValue(value.to_str(), value)); } } @@ -413,6 +434,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>; @@ -480,7 +502,19 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // http://dom.spec.whatwg.org/#dom-element-classname fn SetClassName(&self, class: DOMString) { - self.set_string_attribute("class", class); + 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 @@ -543,6 +577,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { }; // Step 3-5. + let value = self.parse_attribute(&namespace::Null, name.as_slice(), value); self.do_set_attribute(name.clone(), value, name.clone(), namespace::Null, None, |attr| { attr.deref().name == name }); @@ -604,6 +639,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { } // Step 9. + let value = self.parse_attribute(&namespace, local_name.as_slice(), value); self.do_set_attribute(local_name.clone(), value, name, namespace.clone(), prefix, |attr| { attr.deref().local_name == local_name && attr.deref().namespace == namespace @@ -795,6 +831,13 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { self.notify_attribute_changed(name); } + fn parse_plain_attribute(&self, name: &str, value: DOMString) -> AttrValue { + match name { + "class" => AttrValue::from_tokenlist(value), + _ => self.super_type().unwrap().parse_plain_attribute(name, value), + } + } + fn bind_to_tree(&self) { match self.super_type() { Some(ref s) => s.bind_to_tree(), diff --git a/src/components/script/dom/htmlimageelement.rs b/src/components/script/dom/htmlimageelement.rs index 35d85441e64..6bc113b5891 100644 --- a/src/components/script/dom/htmlimageelement.rs +++ b/src/components/script/dom/htmlimageelement.rs @@ -2,6 +2,7 @@ * 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::AttrValue; use dom::bindings::codegen::Bindings::HTMLImageElementBinding; use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLElementCast, HTMLImageElementDerived}; use dom::bindings::js::{JS, JSRef, Temporary}; @@ -199,7 +200,7 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { fn Hspace(&self) -> u32 { let element: &JSRef<Element> = ElementCast::from_ref(self); - from_str::<u32>(element.get_string_attribute("hspace").as_slice()).unwrap() + element.get_uint_attribute("hspace") } fn SetHspace(&self, hspace: u32) { @@ -209,7 +210,7 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { fn Vspace(&self) -> u32 { let element: &JSRef<Element> = ElementCast::from_ref(self); - from_str::<u32>(element.get_string_attribute("vspace").as_slice()).unwrap() + element.get_uint_attribute("vspace") } fn SetVspace(&self, vspace: u32) { @@ -267,4 +268,11 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> { self.update_image(None, None); } } + + fn parse_plain_attribute(&self, name: &str, value: DOMString) -> AttrValue { + match name { + "width" | "height" | "hspace" | "vspace" => AttrValue::from_u32(value, 0), + _ => self.super_type().unwrap().parse_plain_attribute(name, value), + } + } } diff --git a/src/components/script/dom/htmlserializer.rs b/src/components/script/dom/htmlserializer.rs index bb0364672d0..e5cb06cb15f 100644 --- a/src/components/script/dom/htmlserializer.rs +++ b/src/components/script/dom/htmlserializer.rs @@ -151,7 +151,7 @@ fn serialize_attr(attr: &JSRef<Attr>, html: &mut String) { html.push_str(attr.deref().name.as_slice()); }; html.push_str("=\""); - escape(attr.deref().value.as_slice(), true, html); + escape(attr.deref().value_ref(), true, html); html.push_char('"'); } diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 2e3e02d381b..5be262a9003 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -1327,7 +1327,7 @@ impl Node { for attr in node_elem.deref().attrs.borrow().iter().map(|attr| attr.root()) { copy_elem.deref().attrs.borrow_mut().push_unrooted( &Attr::new(&*window, - attr.deref().local_name.clone(), attr.deref().value.clone(), + attr.deref().local_name.clone(), attr.deref().value().clone(), attr.deref().name.clone(), attr.deref().namespace.clone(), attr.deref().prefix.clone(), copy_elem)); } @@ -1815,7 +1815,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> { other_element.attrs.borrow().iter().map(|attr| attr.root()).any(|other_attr| { (attr.namespace == other_attr.namespace) && (attr.local_name == other_attr.local_name) && - (attr.value == other_attr.value) + (attr.deref().value_ref() == other_attr.deref().value_ref()) }) }) } diff --git a/src/components/script/dom/virtualmethods.rs b/src/components/script/dom/virtualmethods.rs index aafe3efe4f4..b32af5139da 100644 --- a/src/components/script/dom/virtualmethods.rs +++ b/src/components/script/dom/virtualmethods.rs @@ -2,6 +2,7 @@ * 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::{AttrValue, StringAttrValue}; use dom::bindings::codegen::InheritTypes::ElementCast; use dom::bindings::codegen::InheritTypes::HTMLAnchorElementCast; use dom::bindings::codegen::InheritTypes::HTMLBodyElementCast; @@ -50,6 +51,15 @@ pub trait VirtualMethods { } } + /// Returns the right AttrValue variant for the attribute with name `name` + /// on this element. + fn parse_plain_attribute(&self, name: &str, value: DOMString) -> AttrValue { + match self.super_type() { + Some(ref s) => s.parse_plain_attribute(name, value), + _ => StringAttrValue(value), + } + } + /// Called when a Node is appended to a tree that is part of a Document. fn bind_to_tree(&self) { match self.super_type() { 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; |