diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2014-09-12 13:28:37 -0700 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2014-10-14 10:32:40 -0700 |
commit | ee2ccc4f872ba33a86057d87a99d1015b3c41cf1 (patch) | |
tree | 3a7ef263aa401fb3a36e9d48ff5bc8a384ab1f65 /components/script | |
parent | d1685015559562a42cc440f4e3b7a97d38cc642c (diff) | |
download | servo-ee2ccc4f872ba33a86057d87a99d1015b3c41cf1.tar.gz servo-ee2ccc4f872ba33a86057d87a99d1015b3c41cf1.zip |
script: Use atom comparison in more places, especially for attributes.
75% improvement in style recalc for Guardians of the Galaxy.
Diffstat (limited to 'components/script')
21 files changed, 226 insertions, 170 deletions
diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index d54be57b8e0..3e81bb31943 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -17,7 +17,6 @@ use devtools_traits::AttrInfo; use servo_util::str::{DOMString, split_html_space_chars}; use std::cell::{Ref, RefCell}; use std::mem; -use std::slice::Items; use string_cache::{Atom, Namespace}; pub enum AttrSettingType { @@ -51,9 +50,9 @@ impl AttrValue { AtomAttrValue(value) } - pub fn tokens<'a>(&'a self) -> Option<Items<'a, Atom>> { + pub fn tokens<'a>(&'a self) -> Option<&'a [Atom]> { match *self { - TokenListAttrValue(_, ref tokens) => Some(tokens.iter()), + TokenListAttrValue(_, ref tokens) => Some(tokens.as_slice()), _ => None } } @@ -215,17 +214,19 @@ impl<'a> AttrHelpers<'a> for JSRef<'a, Attr> { pub trait AttrHelpersForLayout { unsafe fn value_ref_forever(&self) -> &'static str; unsafe fn value_atom_forever(&self) -> Option<Atom>; - unsafe fn value_tokens_forever(&self) -> Option<Items<Atom>>; + unsafe fn value_tokens_forever(&self) -> Option<&'static [Atom]>; unsafe fn local_name_atom_forever(&self) -> Atom; } impl AttrHelpersForLayout for Attr { + #[inline] unsafe fn value_ref_forever(&self) -> &'static str { // cast to point to T in RefCell<T> directly let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value); value.as_slice() } + #[inline] unsafe fn value_atom_forever(&self) -> Option<Atom> { // cast to point to T in RefCell<T> directly let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value); @@ -235,15 +236,17 @@ impl AttrHelpersForLayout for Attr { } } - unsafe fn value_tokens_forever(&self) -> Option<Items<Atom>> { + #[inline] + unsafe fn value_tokens_forever(&self) -> Option<&'static [Atom]> { // cast to point to T in RefCell<T> directly let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value); match *value { - TokenListAttrValue(_, ref tokens) => Some(tokens.iter()), + TokenListAttrValue(_, ref tokens) => Some(tokens.as_slice()), _ => None, } } + #[inline] unsafe fn local_name_atom_forever(&self) -> Atom { self.local_name.clone() } diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 7cf193baf0c..2981cbf341a 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -5451,6 +5451,7 @@ class GlobalGenRoots(): for protoName in descriptor.prototypeChain[1:-1]: protoDescriptor = config.getDescriptor(protoName) delegate = string.Template('''impl ${selfName} for ${baseName} { + #[inline] fn ${fname}(&self) -> bool { self.${parentName}().${fname}() } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index f37a8feb2f6..bbcf3514734 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -123,7 +123,8 @@ impl CollectionFilter for EmbedsFilter { struct LinksFilter; impl CollectionFilter for LinksFilter { fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { - (elem.is_htmlanchorelement() || elem.is_htmlareaelement()) && elem.has_attribute("href") + (elem.is_htmlanchorelement() || elem.is_htmlareaelement()) && + elem.has_attribute(&atom!("href")) } } @@ -147,7 +148,7 @@ impl CollectionFilter for ScriptsFilter { struct AnchorsFilter; impl CollectionFilter for AnchorsFilter { fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { - elem.is_htmlanchorelement() && elem.has_attribute("href") + elem.is_htmlanchorelement() && elem.has_attribute(&atom!("href")) } } @@ -278,7 +279,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { self.GetElementById(fragid.clone()).or_else(|| { let check_anchor = |&node: &JSRef<HTMLAnchorElement>| { let elem: JSRef<Element> = ElementCast::from_ref(node); - elem.get_attribute(ns!(""), "name").root().map_or(false, |attr| { + elem.get_attribute(ns!(""), &atom!("name")).root().map_or(false, |attr| { attr.value().as_slice() == fragid.as_slice() }) }; @@ -785,7 +786,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } let element: JSRef<Element> = ElementCast::to_ref(node).unwrap(); - element.get_attribute(ns!(""), "name").root().map_or(false, |attr| { + element.get_attribute(ns!(""), &atom!("name")).root().map_or(false, |attr| { attr.value().as_slice() == name.as_slice() }) }) diff --git a/components/script/dom/domtokenlist.rs b/components/script/dom/domtokenlist.rs index 59d931dea31..a23e5e49bac 100644 --- a/components/script/dom/domtokenlist.rs +++ b/components/script/dom/domtokenlist.rs @@ -21,12 +21,11 @@ use string_cache::Atom; pub struct DOMTokenList { reflector_: Reflector, element: JS<Element>, - local_name: &'static str, + local_name: Atom, } impl DOMTokenList { - fn new_inherited(element: JSRef<Element>, - local_name: &'static str) -> DOMTokenList { + pub fn new_inherited(element: JSRef<Element>, local_name: Atom) -> DOMTokenList { DOMTokenList { reflector_: Reflector::new(), element: JS::from_rooted(element), @@ -34,11 +33,11 @@ impl DOMTokenList { } } - pub fn new(element: JSRef<Element>, - local_name: &'static str) -> Temporary<DOMTokenList> { + pub fn new(element: JSRef<Element>, local_name: &Atom) -> Temporary<DOMTokenList> { let window = window_from_node(element).root(); - reflect_dom_object(box DOMTokenList::new_inherited(element, local_name), - &Window(*window), DOMTokenListBinding::Wrap) + reflect_dom_object(box DOMTokenList::new_inherited(element, local_name.clone()), + &Window(*window), + DOMTokenListBinding::Wrap) } } @@ -56,7 +55,7 @@ trait PrivateDOMTokenListHelpers { impl<'a> PrivateDOMTokenListHelpers for JSRef<'a, DOMTokenList> { fn attribute(self) -> Option<Temporary<Attr>> { let element = self.element.root(); - element.get_attribute(ns!(""), self.local_name) + element.get_attribute(ns!(""), &self.local_name) } fn check_token_exceptions<'a>(self, token: &'a str) -> Fallible<&'a str> { @@ -79,8 +78,8 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { // http://dom.spec.whatwg.org/#dom-domtokenlist-item fn Item(self, index: u32) -> Option<DOMString> { - self.attribute().root().and_then(|attr| attr.value().tokens().and_then(|mut tokens| { - tokens.idx(index as uint).map(|token| token.as_slice().to_string()) + self.attribute().root().and_then(|attr| attr.value().tokens().and_then(|tokens| { + tokens.get(index as uint).map(|token| token.as_slice().to_string()) })) } @@ -93,9 +92,9 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { // http://dom.spec.whatwg.org/#dom-domtokenlist-contains fn Contains(self, token: DOMString) -> Fallible<bool> { self.check_token_exceptions(token.as_slice()).map(|slice| { - self.attribute().root().and_then(|attr| attr.value().tokens().map(|mut tokens| { + self.attribute().root().and_then(|attr| attr.value().tokens().map(|tokens| { let atom = Atom::from_slice(slice); - tokens.any(|token| *token == atom) + tokens.iter().any(|token| *token == atom) })).unwrap_or(false) }) } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 6ff62874731..2c1685fb407 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -38,7 +38,6 @@ use std::ascii::StrAsciiExt; use std::cell::{Ref, RefMut, RefCell}; use std::default::Default; use std::mem; -use std::slice::Items; use string_cache::{Atom, Namespace}; use url::UrlParser; @@ -57,6 +56,7 @@ pub struct Element { } impl ElementDerived for EventTarget { + #[inline] fn is_element(&self) -> bool { match *self.type_id() { NodeTargetTypeId(ElementNodeTypeId(_)) => true, @@ -205,24 +205,25 @@ impl Element { } pub trait RawLayoutElementHelpers { - unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &str) -> Option<&'a str>; - unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &str) -> Vec<&'a str>; - unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &str) -> Option<Atom>; - unsafe fn has_class_for_layout(&self, name: &str) -> bool; - unsafe fn get_classes_for_layout<'a>(&'a self) -> Option<Items<'a,Atom>>; + unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &Atom) + -> Option<&'a str>; + unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &Atom) -> Vec<&'a str>; + unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom) -> Option<Atom>; + unsafe fn has_class_for_layout(&self, name: &Atom) -> bool; + unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]>; } impl RawLayoutElementHelpers for Element { #[inline] #[allow(unrooted_must_root)] - unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &str) + unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &Atom) -> Option<&'a str> { // cast to point to T in RefCell<T> directly let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs); (*attrs).iter().find(|attr: & &JS<Attr>| { let attr = attr.unsafe_get(); - name == (*attr).local_name_atom_forever().as_slice() && - *(*attr).namespace() == *namespace + *name == (*attr).local_name_atom_forever() && + (*attr).namespace() == namespace }).map(|attr| { let attr = attr.unsafe_get(); (*attr).value_ref_forever() @@ -231,12 +232,12 @@ impl RawLayoutElementHelpers for Element { #[inline] #[allow(unrooted_must_root)] - unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &str) -> Vec<&'a str> { + unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &Atom) -> Vec<&'a str> { // cast to point to T in RefCell<T> directly let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs); (*attrs).iter().filter_map(|attr: &JS<Attr>| { let attr = attr.unsafe_get(); - if name == (*attr).local_name_atom_forever().as_slice() { + if *name == (*attr).local_name_atom_forever() { Some((*attr).value_ref_forever()) } else { None @@ -246,14 +247,14 @@ impl RawLayoutElementHelpers for Element { #[inline] #[allow(unrooted_must_root)] - unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &str) + unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom) -> Option<Atom> { // cast to point to T in RefCell<T> directly let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs); (*attrs).iter().find(|attr: & &JS<Attr>| { let attr = attr.unsafe_get(); - name == (*attr).local_name_atom_forever().as_slice() && - *(*attr).namespace() == *namespace + *name == (*attr).local_name_atom_forever() && + (*attr).namespace() == namespace }).and_then(|attr| { let attr = attr.unsafe_get(); (*attr).value_atom_forever() @@ -262,24 +263,26 @@ impl RawLayoutElementHelpers for Element { #[inline] #[allow(unrooted_must_root)] - unsafe fn has_class_for_layout(&self, name: &str) -> bool { + unsafe fn has_class_for_layout(&self, name: &Atom) -> bool { let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs); (*attrs).iter().find(|attr: & &JS<Attr>| { let attr = attr.unsafe_get(); - (*attr).local_name_atom_forever().as_slice() == "class" + (*attr).local_name_atom_forever() == atom!("class") }).map_or(false, |attr| { let attr = attr.unsafe_get(); - (*attr).value_tokens_forever().map(|mut tokens| { tokens.any(|atom| atom.as_slice() == name) }) + (*attr).value_tokens_forever().map(|tokens| { + tokens.iter().any(|atom| atom == name) + }) }.take().unwrap()) } #[inline] #[allow(unrooted_must_root)] - unsafe fn get_classes_for_layout<'a>(&'a self) -> Option<Items<'a,Atom>> { + unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]> { let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs); (*attrs).iter().find(|attr: & &JS<Attr>| { let attr = attr.unsafe_get(); - (*attr).local_name_atom_forever().as_slice() == "class" + (*attr).local_name_atom_forever() == atom!("class") }).and_then(|attr| { let attr = attr.unsafe_get(); (*attr).value_tokens_forever() @@ -293,6 +296,7 @@ pub trait LayoutElementHelpers { impl LayoutElementHelpers for JS<Element> { #[allow(unrooted_must_root)] + #[inline] unsafe fn html_element_in_html_document_for_layout(&self) -> bool { if (*self.unsafe_get()).namespace != ns!(HTML) { return false @@ -355,14 +359,16 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { pub trait AttributeHandlers { /// Returns the attribute with given namespace and case-sensitive local /// name, if any. - fn get_attribute(self, namespace: Namespace, local_name: &str) + fn get_attribute(self, namespace: Namespace, local_name: &Atom) -> Option<Temporary<Attr>>; - fn get_attributes(self, local_name: &str) + fn get_attributes(self, local_name: &Atom) -> Vec<Temporary<Attr>>; - fn set_attribute_from_parser(self, local_name: Atom, - value: DOMString, namespace: Namespace, + fn set_attribute_from_parser(self, + local_name: Atom, + value: DOMString, + namespace: Namespace, prefix: Option<DOMString>); - fn set_attribute(self, name: &str, value: AttrValue); + fn set_attribute(self, name: &Atom, value: AttrValue); fn do_set_attribute(self, local_name: Atom, value: AttrValue, name: Atom, namespace: Namespace, prefix: Option<DOMString>, cb: |JSRef<Attr>| -> bool); @@ -371,34 +377,33 @@ pub trait AttributeHandlers { fn remove_attribute(self, namespace: Namespace, name: &str); fn notify_attribute_changed(self, local_name: &Atom); - fn has_class(&self, name: &str) -> bool; + fn has_class(&self, name: &Atom) -> bool; fn notify_attribute_removed(self); - fn set_atomic_attribute(self, name: &str, value: DOMString); + fn set_atomic_attribute(self, name: &Atom, value: DOMString); // http://www.whatwg.org/html/#reflecting-content-attributes-in-idl-attributes - fn has_attribute(self, name: &str) -> bool; - fn set_bool_attribute(self, name: &str, value: bool); - fn get_url_attribute(self, name: &str) -> DOMString; - 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); + fn has_attribute(self, name: &Atom) -> bool; + fn set_bool_attribute(self, name: &Atom, value: bool); + fn get_url_attribute(self, name: &Atom) -> DOMString; + fn set_url_attribute(self, name: &Atom, value: DOMString); + fn get_string_attribute(self, name: &Atom) -> DOMString; + fn set_string_attribute(self, name: &Atom, value: DOMString); + fn set_tokenlist_attribute(self, name: &Atom, value: DOMString); + fn get_uint_attribute(self, name: &Atom) -> u32; + fn set_uint_attribute(self, name: &Atom, value: u32); } impl<'a> AttributeHandlers for JSRef<'a, Element> { - fn get_attribute(self, namespace: Namespace, local_name: &str) -> Option<Temporary<Attr>> { + fn get_attribute(self, namespace: Namespace, local_name: &Atom) -> Option<Temporary<Attr>> { self.get_attributes(local_name).iter().map(|attr| attr.root()) .find(|attr| *attr.namespace() == namespace) .map(|x| Temporary::from_rooted(*x)) } - fn get_attributes(self, local_name: &str) -> Vec<Temporary<Attr>> { - let local_name = Atom::from_slice(local_name); + fn get_attributes(self, local_name: &Atom) -> Vec<Temporary<Attr>> { self.attrs.borrow().iter().map(|attr| attr.root()).filter_map(|attr| { - if *attr.local_name() == local_name { + if *attr.local_name() == *local_name { Some(Temporary::from_rooted(*attr)) } else { None @@ -406,8 +411,10 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { }).collect() } - fn set_attribute_from_parser(self, local_name: Atom, - value: DOMString, namespace: Namespace, + fn set_attribute_from_parser(self, + local_name: Atom, + value: DOMString, + namespace: Namespace, prefix: Option<DOMString>) { let name = match prefix { None => local_name.clone(), @@ -420,16 +427,15 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { self.do_set_attribute(local_name, value, name, namespace, prefix, |_| false) } - fn set_attribute(self, name: &str, value: AttrValue) { - assert!(name == name.to_ascii_lower().as_slice()); - assert!(!name.contains(":")); + fn set_attribute(self, name: &Atom, value: AttrValue) { + assert!(name.as_slice() == name.as_slice().to_ascii_lower().as_slice()); + assert!(!name.as_slice().contains(":")); let node: JSRef<Node> = NodeCast::from_ref(self); node.wait_until_safe_to_modify_dom(); - let name = Atom::from_slice(name); self.do_set_attribute(name.clone(), value, name.clone(), - ns!(""), None, |attr| *attr.local_name() == name); + ns!(""), None, |attr| *attr.local_name() == *name); } fn do_set_attribute(self, local_name: Atom, value: AttrValue, @@ -507,41 +513,40 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } } - fn has_class(&self, name: &str) -> bool { - self.get_attribute(ns!(""), "class").root().map(|attr| { - attr.value().tokens().map(|mut tokens| { - tokens.any(|atom| atom.as_slice() == name) + fn has_class(&self, name: &Atom) -> bool { + self.get_attribute(ns!(""), &atom!("class")).root().map(|attr| { + attr.value().tokens().map(|tokens| { + tokens.iter().any(|atom| atom == name) }).unwrap_or(false) }).unwrap_or(false) } - fn set_atomic_attribute(self, name: &str, value: DOMString) { - assert!(name == name.to_ascii_lower().as_slice()); + fn set_atomic_attribute(self, name: &Atom, value: DOMString) { + assert!(name.as_slice().eq_ignore_ascii_case(name.as_slice())); let value = AttrValue::from_atomic(value); self.set_attribute(name, value); } - fn has_attribute(self, name: &str) -> bool { - let name = match self.html_element_in_html_document() { - true => Atom::from_slice(name.to_ascii_lower().as_slice()), - false => Atom::from_slice(name) - }; + fn has_attribute(self, name: &Atom) -> bool { + assert!(name.as_slice().chars().all(|ch| { + !ch.is_ascii() || ch.to_ascii().to_lowercase() == ch.to_ascii() + })); self.attrs.borrow().iter().map(|attr| attr.root()).any(|attr| { - *attr.local_name() == name && *attr.namespace() == ns!("") + *attr.local_name() == *name && *attr.namespace() == ns!("") }) } - fn set_bool_attribute(self, name: &str, value: bool) { + fn set_bool_attribute(self, name: &Atom, value: bool) { if self.has_attribute(name) == value { return; } if value { self.set_string_attribute(name, String::new()); } else { - self.remove_attribute(ns!(""), name); + self.remove_attribute(ns!(""), name.as_slice()); } } - fn get_url_attribute(self, name: &str) -> DOMString { - assert!(name == name.to_ascii_lower().as_slice()); + fn get_url_attribute(self, name: &Atom) -> DOMString { + assert!(name.as_slice() == name.as_slice().to_ascii_lower().as_slice()); if !self.has_attribute(name) { return "".to_string(); } @@ -555,29 +560,30 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { Err(_) => "".to_string() } } - fn set_url_attribute(self, name: &str, value: DOMString) { + fn set_url_attribute(self, name: &Atom, value: DOMString) { self.set_string_attribute(name, value); } - fn get_string_attribute(self, name: &str) -> DOMString { - assert!(name == name.to_ascii_lower().as_slice()); + fn get_string_attribute(self, name: &Atom) -> DOMString { match self.get_attribute(ns!(""), name) { Some(x) => x.root().Value(), None => "".to_string() } } - fn set_string_attribute(self, name: &str, value: DOMString) { - assert!(name == name.to_ascii_lower().as_slice()); + fn set_string_attribute(self, name: &Atom, value: DOMString) { + assert!(name.as_slice() == name.as_slice().to_ascii_lower().as_slice()); self.set_attribute(name, StringAttrValue(value)); } - fn set_tokenlist_attribute(self, name: &str, value: DOMString) { - assert!(name == name.to_ascii_lower().as_slice()); + fn set_tokenlist_attribute(self, name: &Atom, value: DOMString) { + assert!(name.as_slice() == name.as_slice().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()); + fn get_uint_attribute(self, name: &Atom) -> u32 { + assert!(name.as_slice().chars().all(|ch| { + !ch.is_ascii() || ch.to_ascii().to_lowercase() == ch.to_ascii() + })); let attribute = self.get_attribute(ns!(""), name).root(); match attribute { Some(attribute) => { @@ -589,8 +595,8 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { None => 0, } } - fn set_uint_attribute(self, name: &str, value: u32) { - assert!(name == name.to_ascii_lower().as_slice()); + fn set_uint_attribute(self, name: &Atom, value: u32) { + assert!(name.as_slice() == name.as_slice().to_ascii_lower().as_slice()); self.set_attribute(name, UIntAttrValue(value.to_string(), value)); } } @@ -628,28 +634,28 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // http://dom.spec.whatwg.org/#dom-element-id fn Id(self) -> DOMString { - self.get_string_attribute("id") + self.get_string_attribute(&atom!("id")) } // http://dom.spec.whatwg.org/#dom-element-id fn SetId(self, id: DOMString) { - self.set_atomic_attribute("id", id); + self.set_atomic_attribute(&atom!("id"), id); } // http://dom.spec.whatwg.org/#dom-element-classname fn ClassName(self) -> DOMString { - self.get_string_attribute("class") + self.get_string_attribute(&atom!("class")) } // http://dom.spec.whatwg.org/#dom-element-classname fn SetClassName(self, class: DOMString) { - self.set_tokenlist_attribute("class", class); + self.set_tokenlist_attribute(&atom!("class"), class); } // http://dom.spec.whatwg.org/#dom-element-classlist fn ClassList(self) -> Temporary<DOMTokenList> { if self.class_list.get().is_none() { - let class_list = DOMTokenList::new(self, "class"); + let class_list = DOMTokenList::new(self, &atom!("class")); self.class_list.assign(Some(class_list)); } self.class_list.get().unwrap() @@ -676,7 +682,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { } else { name }; - self.get_attribute(ns!(""), name.as_slice()).root() + self.get_attribute(ns!(""), &Atom::from_slice(name.as_slice())).root() .map(|s| s.Value()) } @@ -685,7 +691,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString> { let namespace = namespace::from_domstring(namespace); - self.get_attribute(namespace, local_name.as_slice()).root() + self.get_attribute(namespace, &Atom::from_slice(local_name.as_slice())).root() .map(|attr| attr.Value()) } @@ -808,9 +814,17 @@ impl<'a> ElementMethods for JSRef<'a, Element> { } // http://dom.spec.whatwg.org/#dom-element-hasattribute - fn HasAttribute(self, - name: DOMString) -> bool { - self.has_attribute(name.as_slice()) + fn HasAttribute(self, name: DOMString) -> bool { + // Step 1. + if self.html_element_in_html_document() { + // TODO(pcwalton): Small string optimization here. + return self.has_attribute(&Atom::from_slice(name.as_slice() + .to_ascii_lower() + .as_slice())) + } + + // Step 2. + self.has_attribute(&Atom::from_slice(name.as_slice())) } // http://dom.spec.whatwg.org/#dom-element-hasattributens @@ -997,7 +1011,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { if !tree_in_doc { return; } - match self.get_attribute(ns!(""), "id").root() { + match self.get_attribute(ns!(""), &atom!("id")).root() { Some(attr) => { let doc = document_from_node(*self).root(); let value = attr.Value(); @@ -1018,7 +1032,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { if !tree_in_doc { return; } - match self.get_attribute(ns!(""), "id").root() { + match self.get_attribute(ns!(""), &atom!("id")).root() { Some(attr) => { let doc = document_from_node(*self).root(); let value = attr.Value(); @@ -1033,12 +1047,12 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { } impl<'a> style::TElement<'a> for JSRef<'a, Element> { - fn get_attr(self, namespace: &Namespace, attr: &str) -> Option<&'a str> { + fn get_attr(self, namespace: &Namespace, attr: &Atom) -> Option<&'a str> { self.get_attribute(namespace.clone(), attr).root().map(|attr| { unsafe { mem::transmute(attr.value().as_slice()) } }) } - fn get_attrs(self, attr: &str) -> Vec<&'a str> { + fn get_attrs(self, attr: &Atom) -> Vec<&'a str> { self.get_attributes(attr).iter().map(|attr| attr.root()).map(|attr| { unsafe { mem::transmute(attr.value().as_slice()) } }).collect() @@ -1051,7 +1065,7 @@ impl<'a> style::TElement<'a> for JSRef<'a, Element> { // selector-link ElementNodeTypeId(HTMLAnchorElementTypeId) | ElementNodeTypeId(HTMLAreaElementTypeId) | - ElementNodeTypeId(HTMLLinkElementTypeId) => self.get_attr(&ns!(""), "href"), + ElementNodeTypeId(HTMLLinkElementTypeId) => self.get_attr(&ns!(""), &atom!("href")), _ => None, } } @@ -1078,7 +1092,7 @@ impl<'a> style::TElement<'a> for JSRef<'a, Element> { node.get_hover_state() } fn get_id(self) -> Option<Atom> { - self.get_attribute(ns!(""), "id").map(|attr| { + self.get_attribute(ns!(""), &atom!("id")).map(|attr| { let attr = attr.root(); match *attr.value() { AtomAttrValue(ref val) => val.clone(), @@ -1094,23 +1108,23 @@ impl<'a> style::TElement<'a> for JSRef<'a, Element> { let node: JSRef<Node> = NodeCast::from_ref(self); node.get_enabled_state() } - fn has_class(self, name: &str) -> bool { + fn has_class(self, name: &Atom) -> bool { // FIXME(zwarich): Remove this when UFCS lands and there is a better way // of disambiguating methods. - fn has_class<T: AttributeHandlers>(this: T, name: &str) -> bool { + fn has_class<T: AttributeHandlers>(this: T, name: &Atom) -> bool { this.has_class(name) } has_class(self, name) } fn each_class(self, callback: |&Atom|) { - match self.get_attribute(ns!(""), "class").root() { + match self.get_attribute(ns!(""), &atom!("class")).root() { None => {} - Some(attr) => { - match attr.deref().value().tokens() { + Some(ref attr) => { + match attr.value().tokens() { None => {} - Some(mut tokens) => { - for token in tokens { + Some(tokens) => { + for token in tokens.iter() { callback(token) } } diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index 19492ef6264..aad63f98ba8 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -56,7 +56,7 @@ impl<'a> PrivateHTMLAnchorElementHelpers for JSRef<'a, HTMLAnchorElement> { fn handle_event_impl(self, event: JSRef<Event>) { if "click" == event.Type().as_slice() && !event.DefaultPrevented() { let element: JSRef<Element> = ElementCast::from_ref(self); - let attr = element.get_attribute(ns!(""), "href").root(); + let attr = element.get_attribute(ns!(""), &atom!("href")).root(); match attr { Some(ref href) => { let value = href.Value(); diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs index af4dec6dcb3..ec2377297f3 100644 --- a/components/script/dom/htmlbuttonelement.rs +++ b/components/script/dom/htmlbuttonelement.rs @@ -62,7 +62,7 @@ impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> { // https://html.spec.whatwg.org/multipage/forms.html#dom-button-type fn Type(self) -> DOMString { let elem: JSRef<Element> = ElementCast::from_ref(self); - let ty = elem.get_string_attribute("type").into_ascii_lower(); + let ty = elem.get_string_attribute(&atom!("type")).into_ascii_lower(); // https://html.spec.whatwg.org/multipage/forms.html#attr-button-type match ty.as_slice() { "reset" | "button" | "menu" => ty, diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index ac5a5d7ded5..69a96a086fc 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -68,7 +68,7 @@ impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> { fn SetWidth(self, width: u32) { let elem: JSRef<Element> = ElementCast::from_ref(self); - elem.set_uint_attribute("width", width) + elem.set_uint_attribute(&atom!("width"), width) } fn Height(self) -> u32 { @@ -77,7 +77,7 @@ impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> { fn SetHeight(self, height: u32) { let elem: JSRef<Element> = ElementCast::from_ref(self); - elem.set_uint_attribute("height", height) + elem.set_uint_attribute(&atom!("height"), height) } fn GetContext(self, id: DOMString) -> Option<Temporary<CanvasRenderingContext2D>> { diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs index 035ee8287a4..abd8b6857aa 100644 --- a/components/script/dom/htmlcollection.rs +++ b/components/script/dom/htmlcollection.rs @@ -139,15 +139,17 @@ impl HTMLCollection { -> Temporary<HTMLCollection> { #[jstraceable] struct ClassNameFilter { - classes: Vec<DOMString> + classes: Vec<Atom> } impl CollectionFilter for ClassNameFilter { fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { - self.classes.iter().all(|class| elem.has_class(class.as_slice())) + self.classes.iter().all(|class| elem.has_class(class)) } } let filter = ClassNameFilter { - classes: split_html_space_chars(classes.as_slice()).map(|class| class.to_string()).collect() + classes: split_html_space_chars(classes.as_slice()).map(|class| { + Atom::from_slice(class) + }).collect() }; HTMLCollection::create(window, root, box filter) } @@ -216,8 +218,8 @@ impl<'a> HTMLCollectionMethods for JSRef<'a, HTMLCollection> { Static(ref elems) => elems.iter() .map(|elem| elem.root()) .find(|elem| { - elem.get_string_attribute("name") == key || - elem.get_string_attribute("id") == key }) + elem.get_string_attribute(&atom!("name")) == key || + elem.get_string_attribute(&atom!("id")) == key }) .map(|maybe_elem| Temporary::from_rooted(*maybe_elem)), Live(ref root, ref filter) => { let root = root.root(); @@ -230,8 +232,8 @@ impl<'a> HTMLCollectionMethods for JSRef<'a, HTMLCollection> { } }) .find(|elem| { - elem.get_string_attribute("name") == key || - elem.get_string_attribute("id") == key }) + elem.get_string_attribute(&atom!("name")) == key || + elem.get_string_attribute(&atom!("id")) == key }) .map(|maybe_elem| Temporary::from_rooted(maybe_elem)) } } diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 363e90fa596..ed18eb109f2 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -28,6 +28,7 @@ use std::ascii::OwnedStrAsciiExt; use std::str::StrSlice; use url::UrlParser; use url::form_urlencoded::serialize; +use string_cache::Atom; #[jstraceable] #[must_root] @@ -349,14 +350,24 @@ impl<'a> FormSubmitter<'a> { fn action(&self) -> DOMString { match *self { FormElement(form) => form.Action(), - InputElement(input_element) => input_element.get_form_attribute("formaction", |i| i.FormAction(), |f| f.Action()) + InputElement(input_element) => { + // FIXME(pcwalton): Make this a static atom. + input_element.get_form_attribute(&Atom::from_slice("formaction"), + |i| i.FormAction(), + |f| f.Action()) + } } } fn enctype(&self) -> FormEncType { let attr = match *self { FormElement(form) => form.Enctype(), - InputElement(input_element) => input_element.get_form_attribute("formenctype", |i| i.FormEnctype(), |f| f.Enctype()) + InputElement(input_element) => { + // FIXME(pcwalton): Make this a static atom. + input_element.get_form_attribute(&Atom::from_slice("formenctype"), + |i| i.FormEnctype(), + |f| f.Enctype()) + } }; match attr.as_slice() { "multipart/form-data" => FormDataEncoded, @@ -370,7 +381,12 @@ impl<'a> FormSubmitter<'a> { fn method(&self) -> FormMethod { let attr = match *self { FormElement(form) => form.Method(), - InputElement(input_element) => input_element.get_form_attribute("formmethod", |i| i.FormMethod(), |f| f.Method()) + InputElement(input_element) => { + // FIXME(pcwalton): Make this a static atom. + input_element.get_form_attribute(&Atom::from_slice("formmethod"), + |i| i.FormMethod(), + |f| f.Method()) + } }; match attr.as_slice() { "dialog" => FormDialog, @@ -382,14 +398,20 @@ impl<'a> FormSubmitter<'a> { fn target(&self) -> DOMString { match *self { FormElement(form) => form.Target(), - InputElement(input_element) => input_element.get_form_attribute("formtarget", |i| i.FormTarget(), |f| f.Target()) + InputElement(input_element) => { + // FIXME(pcwalton): Make this a static atom. + input_element.get_form_attribute(&Atom::from_slice("formtarget"), + |i| i.FormTarget(), + |f| f.Target()) + } } } } pub trait FormOwner<'a> : Copy { fn form_owner(self) -> Option<Temporary<HTMLFormElement>>; - fn get_form_attribute(self, attr: &str, + fn get_form_attribute(self, + attr: &Atom, input: |Self| -> DOMString, owner: |JSRef<HTMLFormElement>| -> DOMString) -> DOMString { if self.to_element().has_attribute(attr) { diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 77bbfcf9013..108fbbe4dc2 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -87,7 +87,7 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { fn get_url(self) -> Option<Url> { let element: JSRef<Element> = ElementCast::from_ref(self); - element.get_attribute(ns!(""), "src").root().and_then(|src| { + element.get_attribute(ns!(""), &atom!("src")).root().and_then(|src| { let url = src.value(); if url.as_slice().is_empty() { None @@ -150,22 +150,22 @@ impl HTMLIFrameElement { impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { fn Src(self) -> DOMString { let element: JSRef<Element> = ElementCast::from_ref(self); - element.get_string_attribute("src") + element.get_string_attribute(&atom!("src")) } fn SetSrc(self, src: DOMString) { let element: JSRef<Element> = ElementCast::from_ref(self); - element.set_url_attribute("src", src) + element.set_url_attribute(&atom!("src"), src) } fn Sandbox(self) -> DOMString { let element: JSRef<Element> = ElementCast::from_ref(self); - element.get_string_attribute("sandbox") + element.get_string_attribute(&atom!("sandbox")) } fn SetSandbox(self, sandbox: DOMString) { let element: JSRef<Element> = ElementCast::from_ref(self); - element.set_string_attribute("sandbox", sandbox); + element.set_string_attribute(&atom!("sandbox"), sandbox); } fn GetContentWindow(self) -> Option<Temporary<Window>> { diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index d8a4f9d67f6..c706fcfcd7e 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -113,7 +113,7 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { fn SetIsMap(self, is_map: bool) { let element: JSRef<Element> = ElementCast::from_ref(self); - element.set_string_attribute("ismap", is_map.to_string()) + element.set_string_attribute(&atom!("ismap"), is_map.to_string()) } fn Width(self) -> u32 { @@ -124,7 +124,7 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { fn SetWidth(self, width: u32) { let elem: JSRef<Element> = ElementCast::from_ref(self); - elem.set_uint_attribute("width", width) + elem.set_uint_attribute(&atom!("width"), width) } fn Height(self) -> u32 { @@ -135,7 +135,7 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { fn SetHeight(self, height: u32) { let elem: JSRef<Element> = ElementCast::from_ref(self); - elem.set_uint_attribute("height", height) + elem.set_uint_attribute(&atom!("height"), height) } make_getter!(Name) @@ -188,7 +188,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> { _ => (), } - if "src" == name.as_slice() { + if atom!("src") == *name { self.update_image(None); } } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 52cb51eeaff..b256dab7f3d 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -232,7 +232,7 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> { fn get_radio_group(self) -> Option<String> { //TODO: determine form owner let elem: JSRef<Element> = ElementCast::from_ref(self); - elem.get_attribute(ns!(""), "name") + elem.get_attribute(ns!(""), &atom!("name")) .root() .map(|name| name.Value()) } @@ -409,7 +409,7 @@ impl<'a> FormOwner<'a> for JSRef<'a, HTMLInputElement> { fn form_owner(self) -> Option<Temporary<HTMLFormElement>> { // https://html.spec.whatwg.org/multipage/forms.html#reset-the-form-owner let elem: JSRef<Element> = ElementCast::from_ref(self); - let owner = elem.get_string_attribute("form"); + let owner = elem.get_string_attribute(&atom!("form")); if !owner.is_empty() { let doc = document_from_node(self).root(); let owner = doc.GetElementById(owner).root(); diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 1c641562d81..13c4bf3b513 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -48,7 +48,7 @@ impl HTMLLinkElement { } } -fn get_attr(element: JSRef<Element>, name: &str) -> Option<String> { +fn get_attr(element: JSRef<Element>, name: &Atom) -> Option<String> { let elem = element.get_attribute(ns!(""), name).root(); elem.map(|e| e.value().as_slice().to_string()) } @@ -76,7 +76,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> { } let element: JSRef<Element> = ElementCast::from_ref(*self); - let rel = get_attr(element, "rel"); + let rel = get_attr(element, &atom!("rel")); match (rel, name.as_slice()) { (ref rel, "href") => { @@ -97,8 +97,8 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> { if tree_in_doc { let element: JSRef<Element> = ElementCast::from_ref(*self); - let rel = get_attr(element, "rel"); - let href = get_attr(element, "href"); + let rel = get_attr(element, &atom!("rel")); + let href = get_attr(element, &atom!("href")); match (rel, href) { (ref rel, Some(ref href)) if is_stylesheet(rel) => { diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs index d7a073150ef..a7de41d3599 100644 --- a/components/script/dom/htmlobjectelement.rs +++ b/components/script/dom/htmlobjectelement.rs @@ -63,8 +63,8 @@ impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> { let elem: JSRef<Element> = ElementCast::from_ref(*self); // TODO: support other values - match (elem.get_attribute(ns!(""), "type").map(|x| x.root().Value()), - elem.get_attribute(ns!(""), "data").map(|x| x.root().Value())) { + match (elem.get_attribute(ns!(""), &atom!("type")).map(|x| x.root().Value()), + elem.get_attribute(ns!(""), &atom!("data")).map(|x| x.root().Value())) { (None, Some(uri)) => { if is_image_data(uri.as_slice()) { let data_url = Url::parse(uri.as_slice()).unwrap(); diff --git a/components/script/dom/htmloptionelement.rs b/components/script/dom/htmloptionelement.rs index e44011bc2ce..1493e5cecef 100644 --- a/components/script/dom/htmloptionelement.rs +++ b/components/script/dom/htmloptionelement.rs @@ -74,7 +74,7 @@ impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> { // http://www.whatwg.org/html/#dom-option-disabled fn SetDisabled(self, disabled: bool) { let elem: JSRef<Element> = ElementCast::from_ref(self); - elem.set_bool_attribute("disabled", disabled) + elem.set_bool_attribute(&atom!("disabled"), disabled) } // http://www.whatwg.org/html/#dom-option-text diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 138c7ea8679..e4c268d5713 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -75,7 +75,7 @@ static SCRIPT_JS_MIMES: StaticStringVec = &[ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { fn is_javascript(self) -> bool { let element: JSRef<Element> = ElementCast::from_ref(self); - match element.get_attribute(ns!(""), "type").root().map(|s| s.Value()) { + match element.get_attribute(ns!(""), &atom!("type")).root().map(|s| s.Value()) { Some(ref s) if s.is_empty() => { // type attr exists, but empty means js debug!("script type empty, inferring js"); @@ -87,7 +87,9 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { }, None => { debug!("no script type"); - match element.get_attribute(ns!(""), "language").root().map(|s| s.Value()) { + match element.get_attribute(ns!(""), &atom!("language")) + .root() + .map(|s| s.Value()) { Some(ref s) if s.is_empty() => { debug!("script language empty, inferring js"); true @@ -109,7 +111,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { impl<'a> HTMLScriptElementMethods for JSRef<'a, HTMLScriptElement> { fn Src(self) -> DOMString { let element: JSRef<Element> = ElementCast::from_ref(self); - element.get_url_attribute("src") + element.get_url_attribute(&atom!("src")) } // http://www.whatwg.org/html/#dom-script-text diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index d825bf1f3a1..011254600d3 100644 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -67,7 +67,7 @@ impl<'a> HTMLSelectElementMethods for JSRef<'a, HTMLSelectElement> { // https://html.spec.whatwg.org/multipage/forms.html#dom-select-type fn Type(self) -> DOMString { let elem: JSRef<Element> = ElementCast::from_ref(self); - if elem.has_attribute("multiple") { + if elem.has_attribute(&atom!("multiple")) { "select-multiple".to_string() } else { "select-one".to_string() diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index b4b0d4d2ef7..b0aba98c7d6 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -11,7 +11,7 @@ macro_rules! make_getter( #[allow(unused_imports)] use std::ascii::StrAsciiExt; let element: JSRef<Element> = ElementCast::from_ref(self); - element.get_string_attribute($htmlname) + element.get_string_attribute(&Atom::from_slice($htmlname.to_ascii_lower().as_slice())) } ); ($attr:ident) => { @@ -28,7 +28,8 @@ macro_rules! make_bool_getter( #[allow(unused_imports)] use std::ascii::StrAsciiExt; let element: JSRef<Element> = ElementCast::from_ref(self); - element.has_attribute($htmlname) + // FIXME(pcwalton): Do this at compile time, not runtime. + element.has_attribute(&Atom::from_slice($htmlname)) } ); ($attr:ident) => { @@ -45,7 +46,8 @@ macro_rules! make_uint_getter( #[allow(unused_imports)] use std::ascii::StrAsciiExt; let element: JSRef<Element> = ElementCast::from_ref(self); - element.get_uint_attribute($htmlname) + // FIXME(pcwalton): Do this at compile time, not runtime. + element.get_uint_attribute(&Atom::from_slice($htmlname)) } ); ($attr:ident) => { @@ -62,10 +64,12 @@ macro_rules! make_url_getter( #[allow(unused_imports)] use std::ascii::StrAsciiExt; let element: JSRef<Element> = ElementCast::from_ref(self); - element.get_url_attribute($htmlname) + // FIXME(pcwalton): Do this at compile time, not runtime. + element.get_url_attribute(&Atom::from_slice($htmlname)) } ); ($attr:ident) => { + // FIXME(pcwalton): Do this at compile time, not runtime. make_url_getter!($attr, stringify!($attr).to_ascii_lower().as_slice()) } ) @@ -79,7 +83,7 @@ macro_rules! make_url_or_base_getter( #[allow(unused_imports)] use std::ascii::StrAsciiExt; let element: JSRef<Element> = ElementCast::from_ref(self); - let url = element.get_url_attribute($htmlname); + let url = element.get_url_attribute(&Atom::from_slice($htmlname)); match url.as_slice() { "" => { let window = window_from_node(self).root(); @@ -103,7 +107,8 @@ macro_rules! make_enumerated_getter( #[allow(unused_imports)] use std::ascii::StrAsciiExt; let element: JSRef<Element> = ElementCast::from_ref(self); - let val = element.get_string_attribute($htmlname).into_ascii_lower(); + let val = element.get_string_attribute(&Atom::from_slice($htmlname)) + .into_ascii_lower(); // https://html.spec.whatwg.org/multipage/forms.html#attr-fs-method match val.as_slice() { $($choices)|+ => val, @@ -125,7 +130,8 @@ macro_rules! make_setter( use dom::element::{Element, AttributeHandlers}; use dom::bindings::codegen::InheritTypes::ElementCast; let element: JSRef<Element> = ElementCast::from_ref(self); - element.set_string_attribute($htmlname, value) + // FIXME(pcwalton): Do this at compile time, not at runtime. + element.set_string_attribute(&Atom::from_slice($htmlname), value) } ); ) @@ -137,7 +143,8 @@ macro_rules! make_bool_setter( use dom::element::{Element, AttributeHandlers}; use dom::bindings::codegen::InheritTypes::ElementCast; let element: JSRef<Element> = ElementCast::from_ref(self); - element.set_bool_attribute($htmlname, value) + // FIXME(pcwalton): Do this at compile time, not at runtime. + element.set_bool_attribute(&Atom::from_slice($htmlname), value) } ); ) @@ -149,7 +156,8 @@ macro_rules! make_uint_setter( use dom::element::{Element, AttributeHandlers}; use dom::bindings::codegen::InheritTypes::ElementCast; let element: JSRef<Element> = ElementCast::from_ref(self); - element.set_uint_attribute($htmlname, value) + // FIXME(pcwalton): Do this at compile time, not at runtime. + element.set_uint_attribute(&Atom::from_slice($htmlname), value) } ); ) diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 2716c56dc5c..dc6351c9954 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -919,16 +919,19 @@ pub trait RawLayoutNodeHelpers { } impl RawLayoutNodeHelpers for Node { + #[inline] unsafe fn get_hover_state_for_layout(&self) -> bool { (*self.unsafe_get_flags()).contains(InHoverState) } + #[inline] unsafe fn get_disabled_state_for_layout(&self) -> bool { (*self.unsafe_get_flags()).contains(InDisabledState) } + #[inline] unsafe fn get_enabled_state_for_layout(&self) -> bool { (*self.unsafe_get_flags()).contains(InEnabledState) } - + #[inline] fn type_id_for_layout(&self) -> NodeTypeId { self.type_id } @@ -1581,6 +1584,7 @@ impl Node { } } + #[inline] pub unsafe fn unsafe_get_flags(&self) -> *const NodeFlags { mem::transmute(&self.flags) } @@ -2221,9 +2225,9 @@ impl<'a> style::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> { fn match_attr(self, attr: &style::AttrSelector, test: |&str| -> bool) -> bool { let name = { if self.is_html_element_in_html_document() { - attr.lower_name.as_slice() + &attr.lower_name } else { - attr.name.as_slice() + &attr.name } }; match attr.namespace { @@ -2294,7 +2298,7 @@ impl<'a> DisabledStateHelpers for JSRef<'a, Node> { fn check_disabled_attribute(self) { let elem: JSRef<'a, Element> = ElementCast::to_ref(self).unwrap(); - let has_disabled_attrib = elem.has_attribute("disabled"); + let has_disabled_attrib = elem.has_attribute(&atom!("disabled")); self.set_disabled_state(has_disabled_attrib); self.set_enabled_state(!has_disabled_attrib); } diff --git a/components/script/html/hubbub_html_parser.rs b/components/script/html/hubbub_html_parser.rs index 27f37984517..490e35ff655 100644 --- a/components/script/html/hubbub_html_parser.rs +++ b/components/script/html/hubbub_html_parser.rs @@ -481,7 +481,7 @@ pub fn parse_html(page: &Page, }; let script_element: JSRef<Element> = ElementCast::from_ref(script); - match script_element.get_attribute(ns!(""), "src").root() { + match script_element.get_attribute(ns!(""), &atom!("src")).root() { Some(src) => { debug!("found script: {:s}", src.Value()); let mut url_parser = UrlParser::new(); |