From e0580bf2f525d2503aae67facc28cf6ca234d508 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 10 Feb 2014 22:15:28 +0000 Subject: [PATCH] Use custom enum for the namespace of attribute selectors. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … instead of None meaning "any namespace" (where it could be the null namespace.) --- src/components/main/layout/wrapper.rs | 9 ++++--- src/components/style/selectors.rs | 36 +++++++++++++++++---------- src/components/style/style.rs | 2 +- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/components/main/layout/wrapper.rs b/src/components/main/layout/wrapper.rs index 2e33daa9093..cee7a5095a5 100644 --- a/src/components/main/layout/wrapper.rs +++ b/src/components/main/layout/wrapper.rs @@ -27,7 +27,8 @@ use servo_util::namespace; use servo_util::namespace::Namespace; use std::cast; use std::cell::{Ref, RefMut}; -use style::{PropertyDeclarationBlock, TElement, TNode, AttrSelector}; +use style::{PropertyDeclarationBlock, TElement, TNode, + AttrSelector, SpecificNamespace, AnyNamespace}; use layout::util::LayoutDataWrapper; @@ -239,14 +240,14 @@ impl<'ln> TNode> for LayoutNode<'ln> { attr.name.as_slice() }; match attr.namespace { - Some(ref ns) => { + SpecificNamespace(ref ns) => { match element.get_attr(ns, name) { Some(value) => test(value), None => false, } }, - // FIXME: support `*|attr`, attribute selectors in any namespace - None => return false, + // FIXME: https://github.com/mozilla/servo/issues/1558 + AnyNamespace => return false, } }) } diff --git a/src/components/style/selectors.rs b/src/components/style/selectors.rs index c9eec7d7415..144ebe593ef 100644 --- a/src/components/style/selectors.rs +++ b/src/components/style/selectors.rs @@ -93,8 +93,13 @@ pub enum SimpleSelector { pub struct AttrSelector { name: ~str, lower_name: ~str, - /// None means "any namespace", `*|attr` - namespace: Option, + namespace: NamespaceConstraint, +} + +#[deriving(Eq, Clone)] +pub enum NamespaceConstraint { + AnyNamespace, + SpecificNamespace(Namespace), } @@ -275,8 +280,8 @@ fn parse_type_selector(iter: &mut Iter, namespaces: &NamespaceMap) QualifiedName(namespace, local_name) => { let mut simple_selectors = ~[]; match namespace { - Some(ns) => simple_selectors.push(NamespaceSelector(ns)), - None => (), + SpecificNamespace(ns) => simple_selectors.push(NamespaceSelector(ns)), + AnyNamespace => (), } match local_name { Some(name) => simple_selectors.push(LocalNameSelector(name)), @@ -363,7 +368,7 @@ enum QualifiedNameParseResult { InvalidQualifiedName, NotAQualifiedName, // Namespace URL, local name. None means '*' - QualifiedName(Option, Option<~str>) + QualifiedName(NamespaceConstraint, Option<~str>) } fn parse_qualified_name(iter: &mut Iter, in_attr_selector: bool, namespaces: &NamespaceMap) @@ -371,11 +376,14 @@ fn parse_qualified_name(iter: &mut Iter, in_attr_selector: bool, namespaces: &Na #[inline] fn default_namespace(namespaces: &NamespaceMap, local_name: Option<~str>) -> QualifiedNameParseResult { - QualifiedName(namespaces.default.as_ref().map(|ns| ns.clone()), local_name) + QualifiedName(match namespaces.default { + Some(ref ns) => SpecificNamespace(ns.clone()), + None => AnyNamespace, + }, local_name) } #[inline] - fn explicit_namespace(iter: &mut Iter, in_attr_selector: bool, namespace: Option) + fn explicit_namespace(iter: &mut Iter, in_attr_selector: bool, namespace: NamespaceConstraint) -> QualifiedNameParseResult { assert!(iter.next() == Some(Delim('|')), "Implementation error, this should not happen."); @@ -401,23 +409,25 @@ fn parse_qualified_name(iter: &mut Iter, in_attr_selector: bool, namespaces: &Na None => return InvalidQualifiedName, // Undeclared namespace prefix Some(ref ns) => (*ns).clone(), }; - explicit_namespace(iter, in_attr_selector, Some(namespace)) + explicit_namespace(iter, in_attr_selector, SpecificNamespace(namespace)) }, - _ if in_attr_selector => QualifiedName(Some(namespace::Null), Some(value)), + _ if in_attr_selector => QualifiedName( + SpecificNamespace(namespace::Null), Some(value)), _ => default_namespace(namespaces, Some(value)), } }, Some(&Delim('*')) => { iter.next(); // Consume '*' match iter.peek() { - Some(&Delim('|')) => explicit_namespace(iter, in_attr_selector, None), + Some(&Delim('|')) => explicit_namespace(iter, in_attr_selector, AnyNamespace), _ => { if !in_attr_selector { default_namespace(namespaces, None) } else { InvalidQualifiedName } }, } }, - Some(&Delim('|')) => explicit_namespace(iter, in_attr_selector, Some(namespace::Null)), + Some(&Delim('|')) => explicit_namespace( + iter, in_attr_selector, SpecificNamespace(namespace::Null)), _ => NotAQualifiedName, } } @@ -643,7 +653,7 @@ mod tests { simple_selectors: ~[AttrExists(AttrSelector { name: ~"Foo", lower_name: ~"foo", - namespace: Some(namespace::Null), + namespace: SpecificNamespace(namespace::Null), })], next: None, }), @@ -657,7 +667,7 @@ mod tests { simple_selectors: ~[AttrExists(AttrSelector { name: ~"Foo", lower_name: ~"foo", - namespace: Some(namespace::Null), + namespace: SpecificNamespace(namespace::Null), })], next: None, }), diff --git a/src/components/style/style.rs b/src/components/style/style.rs index c5ae2428064..afd3787436d 100644 --- a/src/components/style/style.rs +++ b/src/components/style/style.rs @@ -23,7 +23,7 @@ pub use properties::{cascade, PropertyDeclaration, ComputedValues, computed_valu pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes pub use errors::with_errors_silenced; pub use node::{TElement, TNode}; -pub use selectors::{PseudoElement, Before, After, AttrSelector}; +pub use selectors::{PseudoElement, Before, After, AttrSelector, SpecificNamespace, AnyNamespace}; mod stylesheets; mod errors;