diff --git a/src/components/main/layout/wrapper.rs b/src/components/main/layout/wrapper.rs index 852696705d8..63205ed1da8 100644 --- a/src/components/main/layout/wrapper.rs +++ b/src/components/main/layout/wrapper.rs @@ -290,8 +290,8 @@ impl<'ln> TNode> for LayoutNode<'ln> { attr.name.as_slice() }; match attr.namespace { - Some(ref url) => { - match element.get_attr(&namespace::Namespace::from_str(url.as_slice()), name) { + Some(ref ns) => { + match element.get_attr(ns, name) { Some(value) => test(value), None => false, } @@ -404,8 +404,8 @@ impl<'le> TElement for LayoutElement<'le> { } #[inline] - fn get_namespace_url<'a>(&'a self) -> &'a str { - self.element.namespace.to_str().unwrap_or("") + fn get_namespace<'a>(&'a self) -> &'a Namespace { + &self.element.namespace } #[inline] diff --git a/src/components/style/namespaces.rs b/src/components/style/namespaces.rs index 77ae126fcd3..762b5f7ab0a 100644 --- a/src/components/style/namespaces.rs +++ b/src/components/style/namespaces.rs @@ -4,11 +4,12 @@ use std::hashmap::HashMap; use cssparser::ast::*; +use servo_util::namespace::Namespace; use errors::log_css_error; pub struct NamespaceMap { - default: Option<~str>, // Optional URL - prefix_map: HashMap<~str, ~str>, // prefix -> URL + default: Option, + prefix_map: HashMap<~str, Namespace>, } @@ -29,7 +30,7 @@ pub fn parse_namespace_rule(rule: AtRule, namespaces: &mut NamespaceMap) { ); if rule.block.is_some() { syntax_error!() } let mut prefix: Option<~str> = None; - let mut url: Option<~str> = None; + let mut ns: Option = None; let mut iter = rule.prelude.move_skip_whitespace(); for component_value in iter { match component_value { @@ -38,25 +39,25 @@ pub fn parse_namespace_rule(rule: AtRule, namespaces: &mut NamespaceMap) { prefix = Some(value); }, URL(value) | String(value) => { - if url.is_some() { syntax_error!() } - url = Some(value); + if ns.is_some() { syntax_error!() } + ns = Some(Namespace::from_str(value.as_slice())); break }, _ => syntax_error!(), } } if iter.next().is_some() { syntax_error!() } - match (prefix, url) { - (Some(prefix), Some(url)) => { - if namespaces.prefix_map.swap(prefix, url).is_some() { + match (prefix, ns) { + (Some(prefix), Some(ns)) => { + if namespaces.prefix_map.swap(prefix, ns).is_some() { log_css_error(location, "Duplicate @namespace rule"); } }, - (None, Some(url)) => { + (None, Some(ns)) => { if namespaces.default.is_some() { log_css_error(location, "Duplicate @namespace rule"); } - namespaces.default = Some(url); + namespaces.default = Some(ns); }, _ => syntax_error!() } diff --git a/src/components/style/node.rs b/src/components/style/node.rs index 1d5b8355ed8..2e22ac0cb89 100644 --- a/src/components/style/node.rs +++ b/src/components/style/node.rs @@ -27,6 +27,6 @@ pub trait TElement { fn get_attr(&self, namespace: &Namespace, attr: &str) -> Option<&'static str>; fn get_link(&self) -> Option<~str>; fn get_local_name<'a>(&'a self) -> &'a str; - fn get_namespace_url<'a>(&'a self) -> &'a str; + fn get_namespace<'a>(&'a self) -> &'a Namespace; } diff --git a/src/components/style/selector_matching.rs b/src/components/style/selector_matching.rs index 57de671e761..a5f6b9cd3f9 100644 --- a/src/components/style/selector_matching.rs +++ b/src/components/style/selector_matching.rs @@ -488,9 +488,9 @@ fn matches_simple_selector>(selector: &SimpleSelector, ele element.get_local_name().eq_ignore_ascii_case(name.as_slice()) }) } - NamespaceSelector(ref url) => { + NamespaceSelector(ref namespace) => { element.with_element(|element: &E| { - element.get_namespace_url() == url.as_slice() + element.get_namespace() == namespace }) } // TODO: case-sensitivity depends on the document type and quirks mode @@ -626,7 +626,7 @@ fn matches_generic_nth_child<'a, element.with_element(|element: &E| { node.with_element(|node: &E| { if element.get_local_name() == node.get_local_name() && - element.get_namespace_url() == node.get_namespace_url() { + element.get_namespace() == node.get_namespace() { index += 1; } }) diff --git a/src/components/style/selectors.rs b/src/components/style/selectors.rs index 24b2d0e4b20..c15259917a4 100644 --- a/src/components/style/selectors.rs +++ b/src/components/style/selectors.rs @@ -9,6 +9,9 @@ use extra::arc::Arc; use cssparser::ast::*; use cssparser::parse_nth; +use servo_util::namespace::Namespace; +use servo_util::namespace; + use namespaces::NamespaceMap; @@ -55,7 +58,7 @@ pub enum SimpleSelector { IDSelector(~str), ClassSelector(~str), LocalNameSelector(~str), - NamespaceSelector(~str), + NamespaceSelector(Namespace), // Attribute selectors AttrExists(AttrSelector), // [foo] @@ -89,7 +92,8 @@ pub enum SimpleSelector { pub struct AttrSelector { name: ~str, lower_name: ~str, - namespace: Option<~str>, + /// None means "any namespace", `*|attr` + namespace: Option, } @@ -270,7 +274,7 @@ fn parse_type_selector(iter: &mut Iter, namespaces: &NamespaceMap) QualifiedName(namespace, local_name) => { let mut simple_selectors = ~[]; match namespace { - Some(url) => simple_selectors.push(NamespaceSelector(url)), + Some(ns) => simple_selectors.push(NamespaceSelector(ns)), None => (), } match local_name { @@ -357,7 +361,8 @@ fn parse_one_simple_selector(iter: &mut Iter, namespaces: &NamespaceMap, inside_ enum QualifiedNameParseResult { InvalidQualifiedName, NotAQualifiedName, - QualifiedName(Option<~str>, Option<~str>) // Namespace URL, local name. None means '*' + // Namespace URL, local name. None means '*' + QualifiedName(Option, Option<~str>) } fn parse_qualified_name(iter: &mut Iter, allow_universal: bool, namespaces: &NamespaceMap) @@ -365,22 +370,22 @@ fn parse_qualified_name(iter: &mut Iter, allow_universal: bool, namespaces: &Nam #[inline] fn default_namespace(namespaces: &NamespaceMap, local_name: Option<~str>) -> QualifiedNameParseResult { - QualifiedName(namespaces.default.as_ref().map(|url| url.to_owned()), local_name) + QualifiedName(namespaces.default.as_ref().map(|ns| ns.clone()), local_name) } #[inline] - fn explicit_namespace(iter: &mut Iter, allow_universal: bool, namespace_url: Option<~str>) + fn explicit_namespace(iter: &mut Iter, allow_universal: bool, namespace: Option) -> QualifiedNameParseResult { assert!(iter.next() == Some(Delim('|')), "Implementation error, this should not happen."); match iter.peek() { Some(&Delim('*')) if allow_universal => { iter.next(); - QualifiedName(namespace_url, None) + QualifiedName(namespace, None) }, Some(&Ident(_)) => { let local_name = get_next_ident(iter); - QualifiedName(namespace_url, Some(local_name)) + QualifiedName(namespace, Some(local_name)) }, _ => InvalidQualifiedName, } @@ -391,11 +396,11 @@ fn parse_qualified_name(iter: &mut Iter, allow_universal: bool, namespaces: &Nam let value = get_next_ident(iter); match iter.peek() { Some(&Delim('|')) => { - let namespace_url = match namespaces.prefix_map.find(&value) { + let namespace = match namespaces.prefix_map.find(&value) { None => return InvalidQualifiedName, // Undeclared namespace prefix - Some(ref url) => url.to_owned(), + Some(ref ns) => (*ns).clone(), }; - explicit_namespace(iter, allow_universal, Some(namespace_url)) + explicit_namespace(iter, allow_universal, Some(namespace)) }, _ => default_namespace(namespaces, Some(value)), } @@ -410,7 +415,7 @@ fn parse_qualified_name(iter: &mut Iter, allow_universal: bool, namespaces: &Nam }, } }, - Some(&Delim('|')) => explicit_namespace(iter, allow_universal, Some(~"")), + Some(&Delim('|')) => explicit_namespace(iter, allow_universal, Some(namespace::Null)), _ => NotAQualifiedName, } }