Make Attr::local_name an Atom.

This commit is contained in:
Ms2ger 2014-08-15 15:15:03 +02:00
parent ba592364b7
commit 9501d2e451
5 changed files with 68 additions and 53 deletions

View file

@ -69,7 +69,7 @@ impl AttrValue {
#[deriving(Encodable)] #[deriving(Encodable)]
pub struct Attr { pub struct Attr {
reflector_: Reflector, reflector_: Reflector,
pub local_name: DOMString, local_name: Atom,
value: Traceable<RefCell<AttrValue>>, value: Traceable<RefCell<AttrValue>>,
pub name: Atom, pub name: Atom,
pub namespace: Namespace, pub namespace: Namespace,
@ -86,7 +86,7 @@ impl Reflectable for Attr {
} }
impl Attr { impl Attr {
fn new_inherited(local_name: DOMString, value: AttrValue, fn new_inherited(local_name: Atom, value: AttrValue,
name: Atom, namespace: Namespace, name: Atom, namespace: Namespace,
prefix: Option<DOMString>, owner: &JSRef<Element>) -> Attr { prefix: Option<DOMString>, owner: &JSRef<Element>) -> Attr {
Attr { Attr {
@ -100,7 +100,7 @@ impl Attr {
} }
} }
pub fn new(window: &JSRef<Window>, local_name: DOMString, value: AttrValue, pub fn new(window: &JSRef<Window>, local_name: Atom, value: AttrValue,
name: Atom, namespace: Namespace, name: Atom, namespace: Namespace,
prefix: Option<DOMString>, owner: &JSRef<Element>) -> Temporary<Attr> { prefix: Option<DOMString>, owner: &JSRef<Element>) -> Temporary<Attr> {
let attr = Attr::new_inherited(local_name, value, name, namespace, prefix, owner); let attr = Attr::new_inherited(local_name, value, name, namespace, prefix, owner);
@ -115,7 +115,9 @@ impl Attr {
match set_type { match set_type {
ReplacedAttr => { ReplacedAttr => {
if namespace_is_null { if namespace_is_null {
vtable_for(node).before_remove_attr(self.local_name.clone(), self.value.deref().borrow().as_slice().to_string()); vtable_for(node).before_remove_attr(
self.local_name().as_slice().to_string(),
self.value.deref().borrow().as_slice().to_string());
} }
} }
FirstSetAttr => {} FirstSetAttr => {}
@ -124,18 +126,24 @@ impl Attr {
*self.value.deref().borrow_mut() = value; *self.value.deref().borrow_mut() = value;
if namespace_is_null { if namespace_is_null {
vtable_for(node).after_set_attr(self.local_name.clone(), self.value.deref().borrow().as_slice().to_string()); vtable_for(node).after_set_attr(
self.local_name().as_slice().to_string(),
self.value.deref().borrow().as_slice().to_string());
} }
} }
pub fn value<'a>(&'a self) -> Ref<'a, AttrValue> { pub fn value<'a>(&'a self) -> Ref<'a, AttrValue> {
self.value.deref().borrow() self.value.deref().borrow()
} }
pub fn local_name<'a>(&'a self) -> &'a Atom {
&self.local_name
}
} }
impl<'a> AttrMethods for JSRef<'a, Attr> { impl<'a> AttrMethods for JSRef<'a, Attr> {
fn LocalName(&self) -> DOMString { fn LocalName(&self) -> DOMString {
self.local_name.clone() self.local_name().as_slice().to_string()
} }
fn Value(&self) -> DOMString { fn Value(&self) -> DOMString {
@ -145,7 +153,7 @@ impl<'a> AttrMethods for JSRef<'a, Attr> {
fn SetValue(&self, value: DOMString) { fn SetValue(&self, value: DOMString) {
let owner = self.owner.root(); let owner = self.owner.root();
let value = owner.deref().parse_attribute( let value = owner.deref().parse_attribute(
&self.namespace, self.deref().local_name.as_slice(), value); &self.namespace, self.local_name(), value);
self.set_value(ReplacedAttr, value); self.set_value(ReplacedAttr, value);
} }

View file

@ -179,7 +179,8 @@ impl RawLayoutElementHelpers for Element {
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs); let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
(*attrs).iter().find(|attr: & &JS<Attr>| { (*attrs).iter().find(|attr: & &JS<Attr>| {
let attr = attr.unsafe_get(); let attr = attr.unsafe_get();
name == (*attr).local_name.as_slice() && (*attr).namespace == *namespace name == (*attr).local_name().as_slice() &&
(*attr).namespace == *namespace
}).map(|attr| { }).map(|attr| {
let attr = attr.unsafe_get(); let attr = attr.unsafe_get();
(*attr).value_ref_forever() (*attr).value_ref_forever()
@ -193,7 +194,8 @@ impl RawLayoutElementHelpers for Element {
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs); let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
(*attrs).iter().find(|attr: & &JS<Attr>| { (*attrs).iter().find(|attr: & &JS<Attr>| {
let attr = attr.unsafe_get(); let attr = attr.unsafe_get();
name == (*attr).local_name.as_slice() && (*attr).namespace == *namespace name == (*attr).local_name().as_slice() &&
(*attr).namespace == *namespace
}).and_then(|attr| { }).and_then(|attr| {
let attr = attr.unsafe_get(); let attr = attr.unsafe_get();
(*attr).value_atom_forever() (*attr).value_atom_forever()
@ -239,14 +241,14 @@ impl<'a> ElementHelpers for JSRef<'a, Element> {
pub trait AttributeHandlers { pub trait AttributeHandlers {
fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<Temporary<Attr>>; fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<Temporary<Attr>>;
fn set_attribute_from_parser(&self, local_name: DOMString, fn set_attribute_from_parser(&self, local_name: Atom,
value: DOMString, namespace: Namespace, value: DOMString, namespace: Namespace,
prefix: Option<DOMString>); prefix: Option<DOMString>);
fn set_attribute(&self, name: &str, value: AttrValue); fn set_attribute(&self, name: &str, value: AttrValue);
fn do_set_attribute(&self, local_name: DOMString, value: AttrValue, fn do_set_attribute(&self, local_name: Atom, value: AttrValue,
name: Atom, namespace: Namespace, name: Atom, namespace: Namespace,
prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool); prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool);
fn parse_attribute(&self, namespace: &Namespace, local_name: &str, fn parse_attribute(&self, namespace: &Namespace, local_name: &Atom,
value: DOMString) -> AttrValue; value: DOMString) -> AttrValue;
fn remove_attribute(&self, namespace: Namespace, name: &str); fn remove_attribute(&self, namespace: Namespace, name: &str);
@ -270,27 +272,26 @@ pub trait AttributeHandlers {
impl<'a> AttributeHandlers for JSRef<'a, Element> { impl<'a> AttributeHandlers for JSRef<'a, Element> {
fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<Temporary<Attr>> { fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<Temporary<Attr>> {
let element: &Element = self.deref(); let element: &Element = self.deref();
let is_html_element = self.html_element_in_html_document(); let local_name = match self.html_element_in_html_document() {
true => Atom::from_slice(name.to_ascii_lower().as_slice()),
false => Atom::from_slice(name)
};
element.attrs.borrow().iter().map(|attr| attr.root()).find(|attr| { element.attrs.borrow().iter().map(|attr| attr.root()).find(|attr| {
let same_name = if is_html_element { *attr.local_name() == local_name && attr.namespace == namespace
name.to_ascii_lower() == attr.local_name
} else {
name == attr.local_name.as_slice()
};
same_name && attr.namespace == namespace
}).map(|x| Temporary::from_rooted(&*x)) }).map(|x| Temporary::from_rooted(&*x))
} }
fn set_attribute_from_parser(&self, local_name: DOMString, fn set_attribute_from_parser(&self, local_name: Atom,
value: DOMString, namespace: Namespace, value: DOMString, namespace: Namespace,
prefix: Option<DOMString>) { prefix: Option<DOMString>) {
let name = match prefix { let name = match prefix {
None => Atom::from_slice(local_name.as_slice()), None => local_name.clone(),
Some(ref prefix) => Atom::from_slice(format!("{:s}:{:s}", *prefix, local_name).as_slice()), Some(ref prefix) => {
let name = format!("{:s}:{:s}", *prefix, local_name.as_slice());
Atom::from_slice(name.as_slice())
},
}; };
let value = self.parse_attribute(&namespace, local_name.as_slice(), value); let value = self.parse_attribute(&namespace, &local_name, value);
self.do_set_attribute(local_name, value, name, namespace, prefix, |_| false) self.do_set_attribute(local_name, value, name, namespace, prefix, |_| false)
} }
@ -301,12 +302,12 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
let node: &JSRef<Node> = NodeCast::from_ref(self); let node: &JSRef<Node> = NodeCast::from_ref(self);
node.wait_until_safe_to_modify_dom(); node.wait_until_safe_to_modify_dom();
self.do_set_attribute(name.to_string(), value, Atom::from_slice(name), let name = Atom::from_slice(name);
namespace::Null, None, self.do_set_attribute(name.clone(), value, name.clone(),
|attr| attr.deref().local_name.as_slice() == name); namespace::Null, None, |attr| *attr.local_name() == name);
} }
fn do_set_attribute(&self, local_name: DOMString, value: AttrValue, fn do_set_attribute(&self, local_name: Atom, value: AttrValue,
name: Atom, namespace: Namespace, name: Atom, namespace: Namespace,
prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool) { prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool) {
let idx = self.deref().attrs.borrow().iter() let idx = self.deref().attrs.borrow().iter()
@ -316,7 +317,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
Some(idx) => (idx, ReplacedAttr), Some(idx) => (idx, ReplacedAttr),
None => { None => {
let window = window_from_node(self).root(); let window = window_from_node(self).root();
let attr = Attr::new(&*window, local_name.clone(), value.clone(), let attr = Attr::new(&*window, local_name, value.clone(),
name, namespace.clone(), prefix, self); name, namespace.clone(), prefix, self);
self.deref().attrs.borrow_mut().push_unrooted(&attr); self.deref().attrs.borrow_mut().push_unrooted(&attr);
(self.deref().attrs.borrow().len() - 1, FirstSetAttr) (self.deref().attrs.borrow().len() - 1, FirstSetAttr)
@ -326,11 +327,11 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
(*self.deref().attrs.borrow())[idx].root().set_value(set_type, value); (*self.deref().attrs.borrow())[idx].root().set_value(set_type, value);
} }
fn parse_attribute(&self, namespace: &Namespace, local_name: &str, fn parse_attribute(&self, namespace: &Namespace, local_name: &Atom,
value: DOMString) -> AttrValue { value: DOMString) -> AttrValue {
if *namespace == namespace::Null { if *namespace == namespace::Null {
vtable_for(NodeCast::from_ref(self)) vtable_for(NodeCast::from_ref(self))
.parse_plain_attribute(local_name, value) .parse_plain_attribute(local_name.as_slice(), value)
} else { } else {
StringAttrValue(value) StringAttrValue(value)
} }
@ -338,9 +339,10 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
fn remove_attribute(&self, namespace: Namespace, name: &str) { fn remove_attribute(&self, namespace: Namespace, name: &str) {
let (_, local_name) = get_attribute_parts(name); let (_, local_name) = get_attribute_parts(name);
let local_name = Atom::from_slice(local_name);
let idx = self.deref().attrs.borrow().iter().map(|attr| attr.root()).position(|attr| { let idx = self.deref().attrs.borrow().iter().map(|attr| attr.root()).position(|attr| {
attr.local_name.as_slice() == local_name *attr.local_name() == local_name
}); });
match idx { match idx {
@ -354,7 +356,8 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
if namespace == namespace::Null { if namespace == namespace::Null {
let removed_raw_value = (*self.deref().attrs.borrow())[idx].root().Value(); let removed_raw_value = (*self.deref().attrs.borrow())[idx].root().Value();
vtable_for(NodeCast::from_ref(self)) vtable_for(NodeCast::from_ref(self))
.before_remove_attr(local_name.to_string(), removed_raw_value); .before_remove_attr(local_name.as_slice().to_string(),
removed_raw_value);
} }
self.deref().attrs.borrow_mut().remove(idx); self.deref().attrs.borrow_mut().remove(idx);
@ -388,11 +391,11 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
fn has_attribute(&self, name: &str) -> bool { fn has_attribute(&self, name: &str) -> bool {
let name = match self.html_element_in_html_document() { let name = match self.html_element_in_html_document() {
true => name.to_ascii_lower(), true => Atom::from_slice(name.to_ascii_lower().as_slice()),
false => name.to_string() false => Atom::from_slice(name)
}; };
self.deref().attrs.borrow().iter().map(|attr| attr.root()).any(|attr| { self.deref().attrs.borrow().iter().map(|attr| attr.root()).any(|attr| {
name == attr.local_name && attr.namespace == Null *attr.local_name() == name && attr.namespace == Null
}) })
} }
@ -587,10 +590,10 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
}; };
// Step 3-5. // Step 3-5.
let value = self.parse_attribute(&namespace::Null, name.as_slice(), value); let name = Atom::from_slice(name.as_slice());
let name_atom = Atom::from_slice(name.as_slice()); let value = self.parse_attribute(&namespace::Null, &name, value);
self.do_set_attribute(name.clone(), value, name_atom.clone(), namespace::Null, None, |attr| { self.do_set_attribute(name.clone(), value, name.clone(), namespace::Null, None, |attr| {
attr.deref().name == name_atom attr.deref().name.as_slice() == name.as_slice()
}); });
Ok(()) Ok(())
} }
@ -640,6 +643,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
} }
let name = Atom::from_slice(name.as_slice()); let name = Atom::from_slice(name.as_slice());
let local_name = Atom::from_slice(local_name);
let xmlns = Atom::from_slice("xmlns"); // TODO: Make this a static atom type let xmlns = Atom::from_slice("xmlns"); // TODO: Make this a static atom type
// Step 7a. // Step 7a.
@ -653,12 +657,12 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
} }
// Step 9. // Step 9.
let value = self.parse_attribute(&namespace, local_name.as_slice(), value); let value = self.parse_attribute(&namespace, &local_name, value);
self.do_set_attribute(local_name.to_string(), value, name, self.do_set_attribute(local_name.clone(), value, name,
namespace.clone(), prefix.map(|s| s.to_string()), namespace.clone(), prefix.map(|s| s.to_string()),
|attr| { |attr| {
attr.deref().local_name.as_slice() == local_name && *attr.local_name() == local_name &&
attr.deref().namespace == namespace attr.namespace == namespace
}); });
Ok(()) Ok(())
} }

View file

@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use servo_util::namespace;
use dom::attr::Attr; use dom::attr::Attr;
use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, CommentCast, NodeCast}; use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, CommentCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, CharacterDataCast}; use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, CharacterDataCast};
@ -19,6 +18,9 @@ use dom::node::{TextNodeTypeId, NodeHelpers};
use dom::processinginstruction::ProcessingInstruction; use dom::processinginstruction::ProcessingInstruction;
use dom::text::Text; use dom::text::Text;
use servo_util::atom::Atom;
use servo_util::namespace;
pub fn serialize(iterator: &mut NodeIterator) -> String { pub fn serialize(iterator: &mut NodeIterator) -> String {
let mut html = String::new(); let mut html = String::new();
let mut open_elements: Vec<String> = vec!(); let mut open_elements: Vec<String> = vec!();
@ -137,16 +139,16 @@ fn serialize_attr(attr: &JSRef<Attr>, html: &mut String) {
html.push_char(' '); html.push_char(' ');
if attr.deref().namespace == namespace::XML { if attr.deref().namespace == namespace::XML {
html.push_str("xml:"); html.push_str("xml:");
html.push_str(attr.deref().local_name.as_slice()); html.push_str(attr.local_name().as_slice());
} else if attr.deref().namespace == namespace::XMLNS && } else if attr.deref().namespace == namespace::XMLNS &&
attr.deref().local_name.as_slice() == "xmlns" { *attr.local_name() == Atom::from_slice("xmlns") {
html.push_str("xmlns"); html.push_str("xmlns");
} else if attr.deref().namespace == namespace::XMLNS { } else if attr.deref().namespace == namespace::XMLNS {
html.push_str("xmlns:"); html.push_str("xmlns:");
html.push_str(attr.deref().local_name.as_slice()); html.push_str(attr.local_name().as_slice());
} else if attr.deref().namespace == namespace::XLink { } else if attr.deref().namespace == namespace::XLink {
html.push_str("xlink:"); html.push_str("xlink:");
html.push_str(attr.deref().local_name.as_slice()); html.push_str(attr.local_name().as_slice());
} else { } else {
html.push_str(attr.deref().name.as_slice()); html.push_str(attr.deref().name.as_slice());
}; };

View file

@ -1388,7 +1388,7 @@ impl Node {
for attr in node_elem.deref().attrs.borrow().iter().map(|attr| attr.root()) { for attr in node_elem.deref().attrs.borrow().iter().map(|attr| attr.root()) {
copy_elem.deref().attrs.borrow_mut().push_unrooted( copy_elem.deref().attrs.borrow_mut().push_unrooted(
&Attr::new(&*window, &Attr::new(&*window,
attr.deref().local_name.clone(), attr.deref().value().clone(), attr.local_name().clone(), attr.deref().value().clone(),
attr.deref().name.clone(), attr.deref().namespace.clone(), attr.deref().name.clone(), attr.deref().namespace.clone(),
attr.deref().prefix.clone(), copy_elem)); attr.deref().prefix.clone(), copy_elem));
} }
@ -1847,7 +1847,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
element.attrs.borrow().iter().map(|attr| attr.root()).all(|attr| { element.attrs.borrow().iter().map(|attr| attr.root()).all(|attr| {
other_element.attrs.borrow().iter().map(|attr| attr.root()).any(|other_attr| { other_element.attrs.borrow().iter().map(|attr| attr.root()).any(|other_attr| {
(attr.namespace == other_attr.namespace) && (attr.namespace == other_attr.namespace) &&
(attr.local_name == other_attr.local_name) && (attr.local_name() == other_attr.local_name()) &&
(attr.deref().value().as_slice() == other_attr.deref().value().as_slice()) (attr.deref().value().as_slice() == other_attr.deref().value().as_slice())
}) })
}) })

View file

@ -20,6 +20,7 @@ use page::Page;
use hubbub::hubbub; use hubbub::hubbub;
use hubbub::hubbub::{NullNs, HtmlNs, MathMlNs, SvgNs, XLinkNs, XmlNs, XmlNsNs}; use hubbub::hubbub::{NullNs, HtmlNs, MathMlNs, SvgNs, XLinkNs, XmlNs, XmlNsNs};
use servo_net::resource_task::{Load, LoadData, Payload, Done, ResourceTask, load_whole_resource}; use servo_net::resource_task::{Load, LoadData, Payload, Done, ResourceTask, load_whole_resource};
use servo_util::atom::Atom;
use servo_util::namespace; use servo_util::namespace;
use servo_util::namespace::{Namespace, Null}; use servo_util::namespace::{Namespace, Null};
use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS}; use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS};
@ -378,7 +379,7 @@ pub fn parse_html(page: &Page,
XmlNsNs => (namespace::XMLNS, Some("xmlns")), XmlNsNs => (namespace::XMLNS, Some("xmlns")),
ns => fail!("Not expecting namespace {:?}", ns), ns => fail!("Not expecting namespace {:?}", ns),
}; };
element.set_attribute_from_parser(attr.name.clone(), element.set_attribute_from_parser(Atom::from_slice(attr.name.as_slice()),
attr.value.clone(), attr.value.clone(),
namespace, namespace,
prefix.map(|p| p.to_string())); prefix.map(|p| p.to_string()));